我遇到过两种在 NSUserDefaults 中存储 NSDate 的方法。
选项 1 - setObject:forKey:
// Set
NSDate *myDate = [NSDate date];
[[NSUserDefaults standardUserDefaults] setObject:myDate forKey:@"myDateKey"];
// Get
NSDate *myDate = (NSDate *)[[NSUserDefaults standardUserDefaults] objectForKey:@"myDateKey"];
选项 2 - timeIntervalSince1970
// Set
NSDate *myDate = [NSDate date];
NSTimeInterval myDateTimeInterval = [myDate timeIntervalSince1970];
[[NSUserDefaults standardUserDefaults] setFloat:myDateTimeInterval forKey:@"myDateKey"];
// Get
NSTimeInterval myDateTimeInterval = [[NSUserDefaults standardUserDefaults] floatForKey:@"myDateKey"];
NSDate *myDate = [NSDate dateWithTimeIntervalSince1970:myDateTimeInterval];
优点和缺点
选项 1
这似乎紧凑且符合逻辑。但是,由于日期格式化程序错误<,我担心会出现问题< /a>.
选项 2
这似乎很笨拙。我也不确定它的准确性 - 在我所做的一项测试中,当我检索日期时,它落后了 48 秒,尽管 Apple 文档说 NSTimeInterval 具有“亚秒级精度”。
要求
无论我选择什么方法,它都必须是:
-
精确到一秒内。
-
可读且可靠。
我的问题
是选项 2 不准确是因为我做错了什么吗?
您会使用这两个选项中的哪一个?
还有其他我不知道的选择吗?
谢谢!
There's two ways of storing an NSDate in NSUserDefaults that I've come across.
Option 1 - setObject:forKey:
// Set
NSDate *myDate = [NSDate date];
[[NSUserDefaults standardUserDefaults] setObject:myDate forKey:@"myDateKey"];
// Get
NSDate *myDate = (NSDate *)[[NSUserDefaults standardUserDefaults] objectForKey:@"myDateKey"];
Option 2 - timeIntervalSince1970
// Set
NSDate *myDate = [NSDate date];
NSTimeInterval myDateTimeInterval = [myDate timeIntervalSince1970];
[[NSUserDefaults standardUserDefaults] setFloat:myDateTimeInterval forKey:@"myDateKey"];
// Get
NSTimeInterval myDateTimeInterval = [[NSUserDefaults standardUserDefaults] floatForKey:@"myDateKey"];
NSDate *myDate = [NSDate dateWithTimeIntervalSince1970:myDateTimeInterval];
Pros and Cons
Option 1
This seems to be compact and logical. However, I've got worries about this going wrong because of Date Formatter bugs.
Option 2
This seems to be clumsy. I'm also unsure of the accuracy of it - in one test I did, when I retrieved the date back it was out by 48 seconds, despite the Apple Docs saying that NSTimeInterval has "subsecond accuracy".
Requirements
Whatever method I choose, it must be:
-
Precise to within a second.
-
Readable and reliable.
My Question
Is the inaccuracy with Option 2 because I'm doing something wrong?
Which out of these two options would you use?
Is there another option that I'm not aware of?
Thanks!
发布评论
评论(4)
你不必要地使事情复杂化。为什么要将日期转换为时间间隔(然后将时间间隔转换为不同的基元)?只需
[sharedDefaults setObject:theDate forKey:@"theDateKey"]
即可完成。 NSDate 是 PLIST 格式支持的“主要类型”之一(日期、数字、字符串、数据、字典和数组),因此您可以直接存储它。请参阅文档作为证明。
只需直接存储和检索日期并观看它做正确的事情(包括时区、精度等)。正如其他人所说,不涉及格式化程序。
You are needlessly complicating things. Why are you converting the date to a time interval (then the time interval to a different primitive)? Just
[sharedDefaults setObject:theDate forKey:@"theDateKey"]
and be done with it. NSDate is one of the "main types" supported by the PLIST format (dates, numbers, strings, data, dictionaries, and arrays), so you can just store it directly.See the documentation for proof.
Just store and retrieve the date directly and watch it Do The Right Thing (including time zones, precision, etc). There is no formatter involved, as others have said.
对于选项#1,我不认为涉及日期格式化程序。可能在引擎盖下,但我想它没有坏。该日期以 ISO 8601 形式存储。
对于选项 #2,请使用
-setDouble:forKey:
和-doubleForKey
而不是基于float
的版本。这可能是造成精度误差的原因。For option #1, I don't believe a date formatter is involved. Possibly under the hood, but I imagine it's not broken. The date is stored in ISO 8601 form.
For option #2, use
-setDouble:forKey:
and-doubleForKey
instead of thefloat
-based versions. That might be the cause of your precision errors.使用 NSUserDefaults;日期以祖鲁时间存储,因此无需担心时区问题。将其存储在您的时区,将其拉出到另一个时区,一切都会好起来的,系统会处理转换(无需担心日期格式化程序)。
Use NSUserDefaults; dates are stored in Zulu time, so there are no time zone issues to worry about. Store it in your time zone, pull it out in another time zone, you'll be fine, the system handles the conversion (no date formatter to worry about).
如果您要从 Facebook Graph API 保存到期日期,我会使用*选项 2*。
选项二可以轻松转换为字符串(使用 stringWithFormat)。最重要的是,它适用于 Graph API。
另外,您不必担心日期的格式。不处理 NSDateFormatter 值得冒 48 秒错误的可能性。
If you are saving the expiration date from the Facebook Graph API, I would use *Option 2*.
Option two can be easily converted to a string (using stringWithFormat). Most importantly, it works for the Graph API.
Plus, you don't have to worry about the format of your date. Not dealing with NSDateFormatter is worth the possibility of a 48 second error.