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

48

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

defaultTimeZone  
localTimeZone  
systemTimeZone

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

    
задан Oliver 13.05.2011 в 00:58
источник

1 ответ

70

Язык в документах, конечно, немного на сухой стороне, и сходство имен потенциально сбивает с толку. Я приведу здесь 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 по-прежнему зависит от кеша уровня приложения в системном часовом поясе. Он изменяется только в соответствии с настройками часового пояса по умолчанию .

    
ответ дан Josh Caswell 13.05.2011 в 06:59
  • Я не понимаю разницы между defaultTimeZone и localTimeZone. Я понимаю, что systemTimeZone - это тот, который определен в системных привилегиях, если есть одно или местоположение устройства. defaultTimeZone - это смоделированный в приложении, или системный, если он не имитируется в приложении. Итак ... Что такое localTimeZone? То, что вы говорите для localTimeZone, похоже, не то, что вы говорите для defaultTimeZone. Не могли бы вы ответить на этот вопрос? –  Oliver 13.05.2011 в 14:01
  • @Oliver: вы правы, localTimeZone дает вам почти тот же результат, что и defaultTimeZone. Я попытался проиллюстрировать единственную разницу в конце моего ответа: конкретный объект NSTimeZone, который вы получаете из localTimeZone, всегда будет отражать настройку, которую вы внесли в часовой пояс в своем приложении. Вы можете вызвать его один раз, сохранить объект и всегда получать текущий имитируемый часовой пояс через этот объект, вне зависимости от сделанных изменений. Это похоже на то, что при использовании этого объекта структура обращается к defaultTimeZone для вас каждый раз, чтобы всегда получать текущее значение. Это помогает? –  Josh Caswell 13.05.2011 в 19:03
  • Это понятно. Я понимаю, что использование любой переменной, содержащей результат вызова localTimeZone, будет отражать изменения. Но этого не произойдет с переменной, которая содержит результат defaultTimeZone. Это правильно ? –  Oliver 14.05.2011 в 19:28
  • Если это то, что вы имели в виду, не могли бы вы извлечь комментарий и поместить его в свой ответ? –  Oliver 14.05.2011 в 19:28
  • Является ли этот ответ еще актуальным для iOS9? Я просто сделал простой тест, вызвав [NSTimeZone systemTimeZone] в своем приложении, изменив часовой пояс на своем устройстве (без перезапуска приложения) и снова вызвав его. В каждом вызове был возвращен текущий часовой пояс устройства (т. Е. Первый вызов не кэшировался и я не вызывал + resetSystemTimeZone). –  chris 24.01.2016 в 11:03