我一直在努力寻找一种在iPhone上使用Core Data存储日常数据的明智方法。
我的应用程序以csv格式接收数据,但日期却没有时间:
date, cycles
2009-08-01, 123
2009-08-02, 234
2009-08-03, 345
2009-08-04, 456
存储此数据时,每天只应有一条记录。我认为最好的办法是创建一个要存储的NSDate,但要删除时间&时区数据。
我可以使用NSDateComponents或NSDateFormatter轻松创建没有小时,分钟或秒的NSDate。但是,即使我将时区显式设置为UTC或从GMT设置为零秒,使用NSLog()始终输出创建日期也具有我的本地时区,如:
2009-07-29 00:00:00 +0100
有没有人知道更好的方法来制作没有时间组件的NSDates?或者也许是存储日期的更好方法?
答案 0 :(得分:9)
一个好的编程经验法则是始终以UTC格式存储日期。无论您是否使用核心数据都无关紧要;你还需要做一些工作,因为Apple的日期课程非常糟糕。
日期在内部表示为自参考日期以来的秒数,我相信,2001年1月1日00:00:00(尽管实际参考日期不是很重要)。点是,NSDate
对象始终以UTC为单位。如果您在CSV文件中获得的日期是本地日期,则需要执行以下操作以获取UTC时间:
NSDate *UTCDate = [localDate addTimeInterval:-[[NSTimeZone localTimeZone] secondsFromGMT]];
然后,我将时间设置为00:00:00。现在,您将在午夜以UTC格式保存日期。出于演示目的,您将使用配置了您选择的时区的NSDateFormatter
(如果您未指定系统时区,则默认为系统时区)以显示这些日期。
但是,当你刚刚处理日期时,时区并不重要。只要您确保将NSDateFormatter
上的时区设置为UTC,无论用户在其设备上选择了哪个时区,您都将始终显示相同的日期。
如果您不喜欢此解决方案,则可以始终以其他格式存储日期。您可以使用double
或int
以某种自定义格式存储日期(例如,自某个参考日期以来的天数),或者您甚至可以使用自己的类来完全按照方式对日期进行建模您想要并将其存储为NSData
对象。只要该类实现NSCoding
,您就可以将其序列化为Core Data中的NSData
对象。您只需将Core Data中的属性类型设置为“Transformable”。
这里有很多选项,其中没有一个涉及编写自己的SQLite查询和数据库的工作。
答案 1 :(得分:3)
NSDate没有时区。 NSLog使用您当地的时区;它说+0100因为那就是你所在的地方。
答案 2 :(得分:2)
NSDate对象将始终包含时间日期 - 引用它“代表[s]单个时间点”的文档,并通过存储自其参考日期(2001年1月1日格林尼治标准时间开始时间的时间值)来实现此目的。再根据文件)。因此,您不能拥有不知道时间的NSDate。
我不会尝试以自己的方式存储日期,而是在模型中使用NSDate并考虑在实体类中添加一对方法,其中一种方法可以执行上述操作,将NSDate设置为00:00 :某一天的00。另一个可以以您首选的格式从NSDate返回日期。然后,这些将使用Core Data生成的getter和setter来访问NSDate属性。
通过仍然使用NSDate,您使用的是Core Data可以本机使用的类,这意味着您仍然可以轻松地使用谓词进行过滤,或者按日期对获取的结果进行排序,而不必过于考虑它。