两个月前,我在应用商店发布了我的第一个应用程序,到目前为止,它的成功非常好。然而,我最近发现了一个问题。
该应用程序的前提是能够跟踪收发的信封。这是一个简单的应用程序,允许您添加条目,然后在选项卡栏中显示按时间顺序排列的时间线,然后在其他选项卡中仅按名称、事件和年份进行筛选。它在世界各地都能很好地工作,除非你更改时区。
该应用程序在后台使用核心数据,包括一些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点。
我希望这是合理的,但任何帮助都将不胜感激。
谢谢,
时区处理起来相当棘手。。您必须始终考虑日期属性的语义(例如,如果2014年在澳大利亚输入的值显示为"2014年"或"2013年",因为"主时区"在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
自己的时区属性(该属性应与UIDatePicker的属性相同)。