Подтвердить что ты не робот

Понимание UILocalNotification timeZone

Из документов:

Дата, указанная в firedate, интерпретируется в соответствии со значением этого свойства. Если вы укажете nil (значение по умолчанию), дата огня интерпретируется как абсолютное время по Гринвичу, которое подходит для таких случаев как таймеры обратного отсчета. Если вы назначили действительный объект NSTimeZone для этого свойство, дата огня интерпретируется как время настенных часов, которое автоматически корректируется при изменении часовых поясов; примером, подходящим для этого случая, является будильник.

Предположим, что я планирую локальное уведомление (в абсолютном времени) в полдень завтра. Я планирую это в Сиэтле в 1:00 (по тихоокеанскому времени, по Гринвичу-8), а затем немедленно отправляется в Чикаго, прибывая 11 вечера (Центральное время, GMT-6). Мое устройство настраивается с тихоокеанского времени на центральное время. Пожалуйста, помогите мне понять, когда мое уведомление будет происходить в следующих трех случаях:

  • UILocalNotification timeZone был установлен на ноль.
  • UILocalNotification timeZone был установлен в GMT.
  • UILocalNotification timeZone был установлен в Pacific Time.
4b9b3361

Ответ 1

Я только что проверил некоторые тесты на iOS 6.1.3. Вот что я получил:

Я в Сиэтле, в 13:00 (Pacific Daylight Time, GMT-7). Я создал 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)

Затем я создал и запланировал уведомления:

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

Журналы только что созданных уведомлений в Сиэтле (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

Я изменил часовой пояс телефона в Чикаго, где сейчас 3:00 PM (Central Daylight Time, GMT-5).

Журналы уведомлений, в Чикаго (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

Выводы:

  • Когда значение UILocalNotification timeZone равно нулю, дата огни фиксируется во времени. Это означает, что уведомление будет выпущено в 12:00 PM GMT-7, 2:00 PM GMT-5 или 7:00 GMT.
  • Если для UILocalNotification timeZone установлено значение GMT, дата пожара рассчитывается для GMT и будет автоматически обновляться, если пользователь перейдет в другой часовой пояс. В этом примере время 12:00 GMT-7 было преобразовано в 19:00 по Гринвичу, и уведомление было установлено в 19:00 по местному времени, независимо от того, какой часовой пояс мы (19:00 GMT, 19:00 GMT-5 или 19:00 GMT-7).
  • Когда UILocalNotification timeZone установлен в локальный часовой пояс (Pacific Daylight Time, GMT-7), дата огней рассчитывается для локального времени и будет автоматически обновляться, если пользователь перейдет в другой часовой пояс. В этом примере время было 12:00 GMT-7, поэтому уведомление будет выпущено в 12:00 по местному времени, независимо от того, в какой часовой зоне мы находимся (12:00 GMT, 12:00 GMT-5 или 12:00 GMT- 7).

Ответ 2

В Swift 3 используйте TimeZone.autoupdatingCurrent, чтобы вести себя так же, как objective-C [NSTimeZone defaultTimeZone].