Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
256 views
in Technique[技术] by (71.8m points)

ios - Understanding UILocalNotification timeZone

From the docs:

The date specified in fireDate is interpreted according to the value of this property. If you specify nil (the default), the fire date is interpreted as an absolute GMT time, which is suitable for cases such as countdown timers. If you assign a valid NSTimeZone object to this property, the fire date is interpreted as a wall-clock time that is automatically adjusted when there are changes in time zones; an example suitable for this case is an an alarm clock.

Suppose I schedule an local notification for (in absolute time) noon tomorrow GMT. I schedule this in Seattle at 1PM (Pacific Time, GMT-8), then immediately travel to Chicago arriving 11PM (Central Time, GMT-6). My device adjust from Pacific Time to Central Time. Please help me understand when my notification will occur in the following three cases:

  1. UILocalNotification timeZone was set to nil.
  2. UILocalNotification timeZone was set to GMT.
  3. UILocalNotification timeZone was set to Pacific Time.
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I just ran some tests on iOS 6.1.3. Here's what I got:

I'm in Seattle, at 1:00PM (Pacific Daylight Time, GMT-7). I created a 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];

now I have

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

Then I created and scheduled the notifications:

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);

Logs of the notifications just created, in Seattle (Pacific Daylight Time, GMT-7):

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

I changed the phone's timezone to Chicago, where now it is 3:00PM (Central Daylight Time, GMT-5).

Logs of the notifications, in Chicago (Central Daylight Time, GMT-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

Conclusions:

  1. When UILocalNotification timeZone is nil, the fire date is fixed in time. That means the notification will be fired at 12:00PM GMT-7, 2:00PM GMT-5, or 7:00 GMT.
  2. When UILocalNotification timeZone is set to GMT, the fire date is calculated for GMT time and will auto-update if the user goes to another time zone. In this example, the time 12:00 GMT-7 was converted to 19:00 GMT, and the notification was set to 19:00 local time, whatever time zone we are (19:00 GMT, 19:00 GMT-5 or 19:00 GMT-7).
  3. When UILocalNotification timeZone is set to the local time zone (Pacific Daylight Time, GMT-7), the fire date is calculated for the local time and will auto-update if the user goes to another time zone. In this example, the time was 12:00 GMT-7, so the notification will be fired at 12:00 local time, whatever time zone we are (12:00 GMT, 12:00 GMT-5 or 12:00 GMT-7).

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...