Определение часового пояса телефонии

На устройствах под управлением Android 11 и ниже автоматическое определение часового пояса в AOSP основано на сигналах подсистемы телефонии. Из-за зависимости от подсистемы телефонии автоматическое определение часового пояса на Android 11 и ниже доступно только для телефонных устройств.

Если функция определения часового пояса телефонии доступна, она работает с использованием сигналов мобильного кода страны (MCC) и идентификатора сети и часового пояса (NITZ) .

Например, устройство в Бельгии может определить часовой пояс исключительно по коду MCC, передаваемому близлежащими вышками сотовой связи. Это возможно, поскольку в Бельгии используется единый часовой пояс.

Если в стране используется несколько часовых поясов, одного MCC недостаточно для определения часового пояса. В таких странах устройство также использует сигналы NITZ для определения правильного часового пояса. Это работает во многих местах по всему миру, но требует наличия и корректности сигналов NITZ, поэтому зависит от операторов связи.

Определение часового пояса в телефонии — пассивный детектор. Он работает постоянно, поэтому предложения по телефонии часто выдаются даже тогда, когда активный алгоритм time_zone_detector в данный момент не использует телефонию.

Ограничение определения часового пояса телефонии

Даже при наличии корректных сигналов NITZ определение часового пояса в телефонии не всегда корректно работает в каждой стране. Это связано с тем, что NITZ содержит только информацию о смещении часового пояса и переходе на летнее время, чего не всегда достаточно для однозначной идентификации часового пояса.

В мире существует множество мест, где может возникнуть эта проблема с часовыми поясами. Например, Денвер, штат Колорадо, и Финикс, штат Аризона, в США не различаются по сигналам NITZ зимой, но различаются в другие времена года. Подобная проблема может возникнуть в любом месте с аналогичным перекрытием часовых поясов.

В следующей таблице показано поведение устройства в зависимости от сезона на примере Денвера и Финикса:

Местоположение и сезон Информация от MCC или NITZ Обнаруженный часовой пояс и поведение
Денвер, Колорадо
Зима
Время: 1 января 2021 г., 12:00:00
Страна: США
Смещение: UTC-7, без перехода на летнее время
Совпадают два идентификатора зон:
  • Америка/Денвер
  • Америка/Феникс

Устройство правильно настроено на Америку/Денвер.
Финикс, Аризона
Зима
Время: 1 января 2021 г., 12:00:00
Страна: США
Смещение: UTC-7, без перехода на летнее время
Совпадают два идентификатора зон:
  • Америка/Денвер
  • Америка/Феникс

Устройство неправильно настроено на Америку/Денвер.
Денвер, Колорадо
Лето
Время: 1 июля 2021 г., 12:00:00
Страна: США
Смещение: UTC-6, летнее время
Один идентификатор зоны соответствует:
  • Америка/Денвер

Устройство правильно настроено на Америку/Денвер.
Финикс, Аризона
Лето
Время: 1 июля 2021 г., 12:00:00
Страна: США
Смещение: UTC-7, без перехода на летнее время
Один идентификатор зоны соответствует:
  • Америка/Феникс

Устройство правильно настроено на Америку/Феникс.

Примеры в таблице показывают, что зимой устройства Android в Денвере или Аризоне должны выбрать один из двух соответствующих идентификаторов часового пояса. Для некоторых устройств это может быть некорректно, но при этом местное время будет отображаться корректно. Часы, календари и другие приложения устройства будут отображать ожидаемое местное время, даже если идентификатор часового пояса неверен, поскольку зимой оба идентификатора часового пояса рассчитывают одинаковое местное время.

Однако весной, когда в Денвере действует летнее время, а в Финиксе — нет, некоторые устройства могут временно показывать неверное местное время, если в них установлен неверный идентификатор часового пояса, соответствующий местоположению пользователя. Это исправляется, как только устройство получает новый сигнал NITZ (в частности, сигнал, содержащий информацию о смещении «UTC-7, без перехода на летнее время»), но это может занять некоторое время и зависит от операторов связи.

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

Отладка и тестирование

В следующем разделе описываются команды оболочки для отладки и тестирования функции определения часового пояса телефонии.

Настройка тестовой среды

Тестировщики обычно используют тестовую среду с тестовой или имитируемой телефонной ячейкой для проверки поведения определения часового пояса телефонной связи. Тестовая ячейка может использоваться для моделирования сетей с различными MCC и для отправки сигналов NITZ на устройства с последующим мониторингом их влияния.

Чтобы устройство определило часовой пояс, информация о сигнале NITZ должна быть корректной, соответствовать MCC и копии базы данных IANA TZDB (правила определения часовых поясов), хранящейся на устройстве. Сигналы NITZ, не соответствующие MCC, приводят к неопределенности алгоритма телефонии.

Например, если MCC, используемый тестовой ячейкой, предназначен для США, сигнал NITZ должен содержать информацию о UTC, смещении и летнем времени, которая верна для какой-либо точки США.

Взаимодействие со службой com.android.phone

Чтобы проверить, получает ли устройство правильные предложения часового пояса телефонии, используйте:

adb shell dumpsys activity service \
    com.android.phone/com.android.phone.TelephonyDebugService

Это позволяет получить информацию о телефонии, которую также можно найти в отчётах об ошибках Android. На устройствах с несколькими SIM-картами информация доступна для каждого радиомодуля SIM-карты.

В журналах часовых поясов отображаются предложения, отправленные процессом телефонии в time_zone_detector, а также причины отправки предложений.

TimeServiceHelperImpl:
          SystemClock.elapsedRealtime()=11864061
          System.currentTimeMillis()=1620652067178
          Time Logs:
...

Time zone Logs:
    18602 / 2021-05-10T09:50:21.718Z - Suggesting time zone update:
    TelephonyTimeZoneSuggestion{mSlotIndex=0, mZoneId='null', mMatchType=0, mQuality=0,
    mDebugInfo=[getTimeZoneSuggestion: nitzSignal=TimestampedValue{mReferenceTimeMillis=14098,
    mValue=NitzData{mOriginalString=21/05/10,09:50:18+04,01, mZoneOffset=3600000,
    mDstOffset=3600000, mCurrentTimeMillis=1620640218000, mEmulatorHostTimeZone=null}},
    countryIsoCode=null, Detection
    reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=14098,
    mValue=NitzData{mOriginalString=21/05/10,09:50:18+04,01, mZoneOffset=3600000,
    mDstOffset=3600000, mCurrentTimeMillis=1620640218000, mEmulatorHostTimeZone=null}})]}
    18831 / 2021-05-10T09:50:21.948Z - Suggesting time zone update:
    TelephonyTimeZoneSuggestion{mSlotIndex=0, mZoneId='Europe/London', mMatchType=3, mQuality=1,
    mDebugInfo=[findTimeZoneFromCountryAndNitz: countryIsoCode=gb,
    nitzSignal=TimestampedValue{mReferenceTimeMillis=14098,
    mValue=NitzData{mOriginalString=21/05/10,09:50:18+04,01, mZoneOffset=3600000,
    mDstOffset=3600000, mCurrentTimeMillis=1620640218000, mEmulatorHostTimeZone=null}},
    findTimeZoneFromCountryAndNitz: lookupResult=OffsetResult{mTimeZone(ID)=Europe/London,
    mIsOnlyMatch=true}, Detection reason=handleCountryDetected("gb")]}