2017-09-08 25 views
0

假设我在区域UTC +0200,我想用date保存记录:2017-10-04。我不喜欢这样写道:如何按日期属性考虑时区的记录?

service!.date = Calendar.current.date(from: DateComponents(year: date.year, month: date.month, day: date.day))! 

日期保存这样的:

2017-10-04 22:00:00 +0000 

现在我需要每天显示的服务。代表问我要服务的date,例如:

2017-10-04 22:00:00 +0000 

一切都很好,记录被取出并处于正常状态。

但是假设我将前往另一个国家(UTC +0100),其中的代表问我同样的date但是这一次它看起来像这样:

2017-10-04 23:00:00 +0000 

和......无所不取。为什么?难道不是同一天吗?如何解决这个问题?

我如何获取记录的谓词是这样的:

NSPredicate(format: "date = %@", date as NSDate) 
+0

您需要以相同的格式保存和获取UTC我认为 –

+0

你是什么意思?该应用程序正在生产中......并且所有内容都保存到持久存储中。现在我需要修复... –

+0

总是与UTC工作必须解决您的问题,你需要转换为UTC保存并转换为UTC后取它,我不知道我是否了解我,对不起我的英语 –

回答

0

如果我理解这个权利,你只关心的日期,而不是时间,但您使用的是NSDate存放,对?问题是NSDate不知道时区。它实际上只是某个时代以来的秒数,将其转换为日期的唯一方法是知道您正在转换的时区。

这里最好的答案可能是将其存储为String,格式如2017-10-04。否则,正如您发现的那样,时区导致同一天被表示为不同的Date s。

如果您使用的是iOS 10+,则可以使用NSISO8601DateFormatter来处理此问题,否则可以使用适当的格式配置DateFormatter

或者,您可以继续将其存储为NSDate,但要特别注意,在使用Calendar转换为/从日期分量转换时,请始终指定UTC时区。


如果你需要修复的在生产应用,在这里最好的解决办法可能是采用启发式说,“轮”每个日期,在UTC解释,到最近的午夜值。这应该有效地恢复用于创建日期的时区。唯一的困难是距离UTC 12小时或更长时间的时区(实际上是UTC + 14:00时区),但我相信这些时区大多只是无人居住的岛屿,所以您可能没有任何从这些时区创建的日期。

无论如何,您需要浏览所有数据,使用UTC将其转换为日期组件,然后检查小时。弄清楚你是否需要四舍五入才能到达最近的午夜,并相应地调整实际日期。然后,您可以取出更正的日期组件并将其写回(通过将其转换回使用UTC的NSDate或将其转换为字符串,具体取决于是否修改数据格式)。

既然这是CoreData,如果你要切换到字符串,你可以实现一个自定义的迁移来处理这个。否则,您将需要一些方法来尝试检测是否有影响的数据(因为您不希望在每次启动时重写所有日期,只是在解决此问题后的首次启动时)。

+0

那么有没有办法来处理这个问题?该应用程序正在制作中...并需要解决此问题。 –

+0

不考虑字符串解决方案...因为它已经作为NSDate存在。 –

+0

@BartłomiejSemańczyk我已经更新了我的答案和建议。 –

相关问题