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

На устройствах с Android 11 и более ранними версиями ОС автоматическое определение часового пояса в Android Open Source Project (AOSP) основано на сигналах от подсистемы телефонии. Поскольку автоматическое определение часового пояса в Android 11 и более ранних версиях зависит от подсистемы телефонии, оно доступно только на устройствах с поддержкой телефонии.

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

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

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

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

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

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

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

В таблице ниже показано, как устройства работают в зависимости от времени года в Денвере и Финиксе.

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

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

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

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

На устройстве правильно установлено время America/Phoenix.

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

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

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

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

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

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

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

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

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

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

Чтобы проверить, получает ли устройство правильные подсказки о часовом поясе от оператора связи, используйте следующую команду:

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

Эта команда позволяет получить информацию о телефонии, которая также содержится в отчетах об ошибках Android. На устройствах с несколькими 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")]}