【问题标题】:iOS App Different Timezone treating Date Entries DifferentiOS App不同的时区对待日期条目不同
【发布时间】:2014-03-15 19:38:50
【问题描述】:

2 个月前,我在 App Store 上发布了我的第一个应用程序,到目前为止,我的成功非常好。然而,我最近发现了一个问题。

该应用程序的前提是能够跟踪发送和接收的钱信封。这是一个简单的应用程序,允许您添加条目,然后在选项卡栏中,它显示按时间顺序排列的时间线,然后在其他选项卡中仅按名称、事件和年份进行过滤。它在世界各地都很好用,除非您更改时区。

应用程序在后台使用核心数据,包括一些 NSPredicate 检查以查看“如果您选择的今年已经存在,我将返回它,如果不存在,我将为该年创建一个新条目”。因此,如果您有一个 2014 年和一个 2013 年作为年份的条目,在“年份”选项卡中,您将看到一个 2014 年的条目和一个 2013 年的条目。如果您添加另一个 2014 年的条目,您将不会在“年份”选项卡中看到两个 2014 年的条目年选项卡,但仍然是一个 2014 年条目(包含以下所有交易)。

使用UIDatePicker 选择日期以获得实际日期。

更改时区时会出现问题。如果您这样做,则以 2014 年为年份的条目不再被识别为与之前的 2014 年相同的条目,因此在年份选项卡中,我最终会得到多个 2014 年条目,这当然没有意义。

我发现这与时间有关,您可以在下面看到我没有使用时区,而是使用NSGregorianCalendar 功能。

NSCalendar *yearCal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *yearComponent = [yearCal components:NSYearCalendarUnit fromDate:self.datePicker.date];
NSDate *selectedYear = [yearCal dateFromComponents:yearComponent];

如果不过多更改应用程序的功能(我希望它以相同的方式工作),我将如何指定一个时区,比如 GMT,但由于夏令时等原因,我想保留它以格林威治标准时间下午 12 点为标准,因此无论您身在何处,它都会专注于格林威治标准时间下午 12 点。

我希望这是有道理的,但我们将不胜感激。

谢谢,

【问题讨论】:

  • 通常我使用带有 GMT 时区的 dateFormatter 来解析日期字符串,并使用零时区发送/接收日期字符串(例如 @"01/01/2014 +000")。 NSDateFormatter * dateFormatter = [NSDateFormater new]; [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT: 0]]。不确定该解决方案是否正确,但可以满足我的需求
  • 亲爱的 Mykola - 非常感谢您的回复,这是有道理的 - 我使用 Martin 的回答来完成这项工作,但我也理解您的方法 - 不胜感激!

标签: ios date core-data timezone nspredicate


【解决方案1】:

时区处理起来非常棘手。您始终必须考虑日期属性的语义(例如,如果在澳大利亚输入 2014 年的值应显示为“2014 年”或“2013 年”,因为“ home timezone' 在美国是 2013 年等等)

NSCalendar 默认使用当前本地时区,UIDatePicker(和 NSTimeFormatter,当您在调试器中执行 po date 时在内部使用)也是如此。 我的第一个建议是将年份作为单独的字段存储在数据库中,如果您想基于它进行过滤..

但是,如果您想将日期值“标准化”到特定时区,您可以在 NSDateComponents 上设置 UTC 时区,以获得 UTC 中一年中的第一刻:

NSCalendar *yearCal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *yearComponent = [yearCal components:NSYearCalendarUnit fromDate:self.datePicker.date];
[yearComponent setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]
NSDate *selectedYear = [yearCal dateFromComponents:yearComponent];

这会覆盖NSCalendar 自己的 timeZone 属性(应该与 UIDatePicker 的相同)。

【讨论】:

  • 嗨 Martin - 非常感谢您的回复,并为迟到的回复表示歉意(几天有点疯狂),但您的代码确实提供了很大帮助,并确保现在已删除此错误。这真的很有帮助,而且使用 UTC 时区完全有意义。非常感谢 - 非常感谢!
猜你喜欢
  • 2015-04-20
  • 2013-10-29
  • 2017-03-03
  • 2012-05-19
  • 1970-01-01
  • 2017-06-05
  • 2015-05-16
  • 1970-01-01
  • 2023-04-07
相关资源
最近更新 更多