iPhone - Различия между удобными методами часового пояса

Я вижу, что NSTimeZone имеет следующие методы:

defaultTimeZone  
localTimeZone  
systemTimeZone

Может ли кто-нибудь объяснить мне простыми словами, в чем разница между этими вызовами и когда следует использовать один вместо другого? Я ничего не понимаю в документах Apple по этому поводу.


person Oliver    schedule 12.05.2011    source источник


Ответы (1)


Конечно, язык в документах немного суховат, а сходство имен может сбить с толку. Я процитирую здесь NSTimeZone docs и попытаюсь их объяснить. :

systemTimeZone
Часовой пояс, используемый в настоящее время системой. Если текущий часовой пояс не может быть определен, возвращает часовой пояс GMT.

Это часовой пояс, в котором, по мнению устройства, он находится; он часто устанавливается автоматически и будет соответствовать физическому местоположению устройства, но если пользователь явно установил определенный часовой пояс в приложении «Настройки», это то, что вы получите.

defaultTimeZone
Часовой пояс по умолчанию для текущего приложения. Если часовой пояс по умолчанию не установлен, этот метод вызывает systemTimeZone и возвращает системный часовой пояс.

Вашему приложению разрешено устанавливать собственный часовой пояс, так что вы можете выполнять действия, как если бы устройство находилось в другом поясе, но не затрагивая системный часовой пояс (и, следовательно, другие приложения). Настройка выполняется вызовом setDefaultTimeZone:. Если вы этого не сделали, этот вызов идентичен вызову systemTimeZone.

localTimeZone
Объект, который перенаправляет все сообщения в часовой пояс по умолчанию для текущего приложения. Местный часовой пояс всегда представляет текущее состояние часового пояса по умолчанию.

Вот где это становится немного сложно. localTimeZone дает почти тот же результат, что и defaultTimeZone. Разница в том, что конкретный экземпляр NSTimeZone, который вы получаете от localTimeZone, всегда будет отражать настройку, которую вы сделали для часового пояса в своем приложении. Вы можете вызвать его один раз, сохранить результат и всегда получать текущий смоделированный часовой пояс через этот объект, независимо от внесенных изменений. Как будто, когда вы используете этот экземпляр NSTimeZone, фреймворк вызывает defaultTimeZone для вас, чтобы быть уверенным, что вы всегда получаете текущее значение.

Вот пара кратких иллюстраций к вышесказанному. Объект NSTimeZone, который вы получаете от systemTimeZone, представляет системный часовой пояс на момент совершения вызова. Если вы снова вызовете systemTimeZone, даже если пользователь с тех пор изменил часовой пояс, вы получите тот же самый. Ваше приложение кэширует это значение, и вы должны попросить систему очистить его с помощью resetSystemTimeZone, чтобы получить обновление.

// Say that device is in GMT originally
NSLog(@"%@", [NSTimeZone systemTimeZone]);    // GMT
// User flies into Rome and iPhone changes the zone automatically
NSLog(@"%@", [NSTimeZone systemTimeZone]);    // Still GMT
[NSTimeZone resetSystemTimeZone];    // Clear app's cache
NSLog(@"%@", [NSTimeZone systemTimeZone]);    // Now GMT+2

То же самое происходит и с defaultTimeZone. Когда вы вызываете этот метод, вы получаете объект, который всегда будет представлять один и тот же часовой пояс, даже если вы позже вызовете setDefaultTimeZone:. Однако, если вы используете объект, полученный от localTimeZone, он будет следовать за изменением, внесенным вами в часовой пояс по умолчанию*.

// Say that defaultTimeZone is originally GMT
NSTimeZone * myDefaultTZ = [NSTimeZone defaultTimeZone];
NSTimeZone * myLocalTZ = [NSTimeZone localTimeZone];
[NSTimeZone setDefaultTimeZone:[NSTimeZone timeZoneWithName:@"Etc/GMT-4"]];
NSLog(@"%@", myDefaultTZ);    // Still gives GMT
NSLog(@"%@", [NSTimeZone defaultTimeZone]);    // GMT-4, the new value
NSLog(@"%@", myLocalTZ);    // Also the new value!

Apple, кажется, рекомендует используя localTimeZone:

с помощью метода класса localTimeZone вы можете получить объект относительного часового пояса, который декодирует себя, чтобы стать часовым поясом по умолчанию на любом компьютере, на котором он находится.


*Обратите внимание, что localTimeZone по-прежнему зависит от кеша уровня приложения системного часового пояса. Он изменяется только в соответствии с вашими настройками часового пояса по умолчанию.

person jscs    schedule 13.05.2011
comment
Я не понимаю разницы между defaultTimeZone и localTimeZone. Я понимаю, что systemTimeZone — это тот, который определен в системных настройках, если он есть, или в местоположении устройства. defaultTimeZone — это смоделированный в приложении или системный, если он не смоделирован в приложении. Итак... Какая польза от localTimeZone? То, что вы говорите для localTimeZone, похоже, то же самое, что и для defaultTimeZone. Не могли бы вы завершить свой ответ по этому вопросу? - person Oliver; 13.05.2011
comment
@Oliver: Вы правы, localTimeZone дает почти тот же результат, что и defaultTimeZone. Я попытался проиллюстрировать единственное отличие в конце своего ответа: конкретный объект NSTimeZone, который вы получаете от localTimeZone, всегда будет отражать настройку, которую вы сделали для часового пояса в своем приложении. Вы можете вызвать его один раз, сохранить объект и всегда получать текущий смоделированный часовой пояс через этот объект, независимо от внесенных изменений. Как будто, когда вы используете этот объект, фреймворк каждый раз вызывает для вас defaultTimeZone, чтобы всегда получать текущее значение. Это помогает? - person jscs; 13.05.2011
comment
Это ясно. Я понимаю, что использование любой переменной, содержащей результат вызова localTimeZone, будет отражать изменения. Но этого не произойдет с переменной, содержащей результат defaultTimeZone. Это правильно ? - person Oliver; 14.05.2011
comment
Если это то, что вы имели в виду, не могли бы вы извлечь комментарий и поместить его в свой ответ? - person Oliver; 14.05.2011
comment
@Oliver: У тебя это есть, и ты сделаешь это! - person jscs; 14.05.2011
comment
Этот ответ все еще актуален для iOS9? Я только что провел простой тест, вызвав [NSTimeZone systemTimeZone] в своем приложении, изменив часовой пояс на своем устройстве (без перезапуска приложения) и снова вызвав его. При каждом вызове возвращался текущий часовой пояс устройства (т. е. первый вызов не кэшировался, и я не вызывал +resetSystemTimeZone). - person chris; 24.01.2016