了解UILocalNotification时区

从文档:

fireDate中指定的date根据此属性的值进行解释。 如果您指定nil(默认值),则启动date被解释为绝对GMT时间,适用于倒数计时器等情况。 如果将一个有效的NSTimeZone对象分配给此属性,则激活date被解释为在时区发生更改时自动调整的挂钟时间; 适合这种情况的例子是闹钟。

假设我明天格林尼治标准时间的中午(绝对时间)安排当地通知。 我安排在西雅图下午1点(太平洋时间,格林威治标准时间8),然后立即前往芝加哥下午11时(中部时间,格林威治标准时间-6)。 我的设备从太平洋时间调整到中央时间。 请帮助我了解在以下三种情况下我的通知将会发生:

  1. UILocalNotification timeZone被设置为零。
  2. UILocalNotification timeZone被设置为GMT。
  3. UILocalNotification timeZone被设置为太平洋时间。

我只是在iOS 6.1.3上运行了一些testing。 这是我得到的:

我在西雅图下午1:00(太平洋夏令时,格林威治标准时间-7)。 我创build了一个NSDate

 NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; // 2013-08-31 @ 12:00:00 (noon) dateComponents.year = 2013; dateComponents.month = 8; dateComponents.day = 31; dateComponents.hour = 12; dateComponents.minute = 0; dateComponents.second = 0; NSDate *fireDate = [gregorianCalendar dateFromComponents:dateComponents]; 

我现在有

 fireDate = 2013-08-31 19:00:00 +0000 (2013-08-31 12:00:00 -0700) 

然后我创build并安排了通知:

 notification1 = [[UILocalNotification alloc] init]; notification1.fireDate = fireDate; // notification1.timeZone is nil by default NSLog(@"%@", notification1); notification2 = [[UILocalNotification alloc] init]; notification2.fireDate = fireDate; notification2.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; NSLog(@"%@", notification2); notification3 = [[UILocalNotification alloc] init]; notification3.fireDate = fireDate; notification3.timeZone = [NSTimeZone defaultTimeZone]; NSLog(@"%@", notification3); 

在西雅图(太平洋夏令时,GMT-7)创build的通知日志:

 notification1: fire date = Saturday, August 31, 2013, 12:00:00 PM Pacific Daylight Time, time zone = (null), next fire date = Saturday, August 31, 2013, 12:00:00 PM Pacific Daylight Time notification2: fire date = Saturday, August 31, 2013, 7:00:00 PM GMT, time zone = GMT (GMT) offset 0, next fire date = Saturday, August 31, 2013, 7:00:00 PM Pacific Daylight Time notification3: fire date = Saturday, August 31, 2013, 12:00:00 PM Pacific Daylight Time, time zone = US/Pacific (PDT) offset -25200 (Daylight), next fire date = Saturday, August 31, 2013, 12:00:00 PM Pacific Daylight Time 

我把电话的时区改成芝加哥,现在是下午3点(中央夏令时间,格林威治标准时间-5)。

芝加哥(中央夏令时间,格林威治标准时间-5)

 notification1: fire date = Saturday, August 31, 2013, 2:00:00 PM Central Daylight Time, time zone = (null), next fire date = Saturday, August 31, 2013, 2:00:00 PM Central Daylight Time notification2: fire date = Saturday, August 31, 2013, 7:00:00 PM GMT, time zone = GMT (GMT) offset 0, next fire date = Saturday, August 31, 2013, 7:00:00 PM Central Daylight Time notification3: fire date = Saturday, August 31, 2013, 12:00:00 PM Pacific Daylight Time, time zone = US/Pacific (PDT) offset -25200 (Daylight), next fire date = Saturday, August 31, 2013, 12:00:00 PM Central Daylight Time 

结论:

  1. 当UILocalNotification timeZone为零时,火灾date是固定的。 这意味着通知将在GMT格林威治标准时间下午12:00,格林威治标准时间下午2点或格林威治标准时间下午7点点发射。
  2. 将UILocalNotification timeZone设置为GMT时,计算GMT时间的启动date,如果用户转到其他时区,则会自动更新。 在这个例子中,格林尼治标准时间-7点的时间被转换为格林威治标准时间19点,当地时间通知被设置为19点,无论我们在哪个时区(格林尼治标准时间19点,格林威治标准时间19点,格林威治标准时间19:00)。
  3. 将UILocalNotification timeZone设置为当地时区(太平洋夏令时,GMT-7)时,将根据当地时间计算火灾date,如果用户转到其他时区,则会自动更新。 在这个例子中,时间是格林威治标准时间12:00,所以无论我们在哪个时区(格林尼治标准时间12:00,格林尼治标准时间-5或格林尼治标准时间12:00),当地时间12:00通知通知。 7)。

在Swift 3中,使用TimeZone.autoupdatingCurrent的行为与objective-C [NSTimeZone defaultTimeZone]行为相同。