Detecção de fuso horário de telefonia

Para dispositivos com o Android 11 ou versões anteriores, a detecção automática de fuso horário no AOSP depende de sinais do subsistema de telefonia. Devido à dependência do subsistema de telefonia, a detecção automática de fuso horário no Android 11 ou versões anteriores é limitada a dispositivos de telefonia.

Quando a detecção de fuso horário de telefonia está disponível, ela funciona usando os sinais de código de país para dispositivos móveis (MCC) e identidade de rede e fuso horário (NITZ).

Por exemplo, um dispositivo na França pode identificar o fuso horário com base apenas no MCC informado pelas torres de celular próximas. Isso é possível porque a França é conhecida por usar um único fuso horário.

Quando um país usa vários fusos horários, o MCC sozinho não é suficiente para identificar o fuso horário. Para esses países, o dispositivo também usa sinais NITZ para identificar o fuso horário correto. Isso funciona bem em muitos lugares ao redor do mundo, mas exige que os sinais NITZ estejam disponíveis e corretos e, portanto, depende das operadoras.

A detecção de fuso horário de telefonia é um detector passivo. Ele é executado o tempo todo, e as sugestões de telefonia são feitas mesmo quando o algoritmo time_zone_detector ativo não está usando a telefonia.

Limitação da detecção de fuso horário para telefonia

Mesmo com sinais NITZ corretos disponíveis, a detecção de fuso horário de telefonia nem sempre funciona bem em todos os países. Isso ocorre porque o NITZ contém apenas informações de deslocamento e horário de verão, que nem sempre são suficientes para identificar exclusivamente um fuso horário.

Há muitos lugares no mundo em que esse problema de fuso horário pode ocorrer. Por exemplo, Denver, Colorado, e Phoenix, Arizona, nos EUA, não podem ser distinguidas usando sinais NITZ durante o inverno, mas podem ser durante outras estações. Qualquer local com fusos horários sobrepostos semelhantes pode enfrentar esse tipo de problema.

A tabela a seguir detalha o comportamento do dispositivo dependendo da estação para Denver e Phoenix como exemplo:

Local e estação Informações do MCC ou NITZ Fuso horário e comportamento detectados
Denver, Colorado
Inverno
Hora: 1º de janeiro de 2021, 12h00
País: EUA
Compensação: UTC-7, sem horário de verão
Dois IDs de zona correspondem:
  • America/Denver
  • America/Phoenix

O dispositivo está corretamente definido como America/Denver.
Phoenix, Arizona
Inverno
Hora: 1º de janeiro de 2021, 12h00
País: EUA
Compensação: UTC-7, sem horário de verão
Dois IDs de zona correspondem:
  • America/Denver
  • America/Phoenix

O dispositivo está incorretamente definido como America/Denver.
Denver, Colorado
Verão
Horário: 1o de julho de 2021, 12h
País: EUA
Compensação: UTC-6, horário de verão
Um ID de zona corresponde a:
  • America/Denver

O dispositivo está definido corretamente como America/Denver.
Phoenix, Arizona
Verão
Horário: 1o de julho de 2021, 12h
País: EUA
Compensação: UTC-7, sem horário de verão
Um ID de zona corresponde a:
  • America/Phoenix

O dispositivo está definido corretamente como Estados Unidos/Phoenix.

Os exemplos acima mostram que, durante o inverno, os dispositivos Android em Denver ou no Arizona precisam escolher um dos dois IDs de fuso horário correspondentes, que podem estar incorretos para alguns dispositivos, mas ainda mostram um horário local aparentemente correto. O relógio do dispositivo, os calendários e outros apps mostram o horário local esperado, mesmo que o ID do fuso horário esteja incorreto, porque ambos calculam o mesmo horário local durante o inverno.

No entanto, na primavera, quando Denver segue o horário de verão e a Phoenix não, alguns dispositivos podem mostrar temporariamente a hora local incorreta se estiverem definidos com o ID de fuso horário errado para o local do usuário. Isso será corrigido assim que o dispositivo receber um novo sinal NITZ (especificamente, um que contenha informações de compensação "UTC-7, sem horário de verão"), mas isso pode levar algum tempo e depende das operadoras.

Como resultado, os calendários ou outros apps que armazenam ou transferem o ID do fuso horário do inverno para a primavera podem mostrar e usar a hora local errada até que os apps relevantes atualizem o ID do fuso horário.

Depuração e testes

A seção a seguir descreve os comandos do shell para depurar e testar o recurso de detecção de fuso horário de telefonia.

Configuração do ambiente de teste

Os testadores geralmente usam um ambiente de teste com uma célula de telefonia simulada ou de teste para verificar o comportamento da detecção de fuso horário de telefonia. A célula de teste pode ser usada para simular redes com diferentes MCCs e enviar sinais NITZ para dispositivos e, em seguida, monitorar os efeitos.

Para que o dispositivo detecte o fuso horário, as informações do sinal NITZ precisam estar corretas, consistentes com o MCC e corresponder à cópia do dispositivo do IANA TZDB (regras de fuso horário). Sinais NITZ inconsistentes com o MCC fazem com que o algoritmo de telefonia se torne incerto.

Por exemplo, se o MCC usado pela célula de teste for dos EUA, o sinal NITZ precisa conter informações de "hora universal", deslocamento e horário de verão que sejam corretas para algum lugar nos EUA.

Interagir com o serviço com.android.phone

Para verificar se o dispositivo está recebendo sugestões de fuso horário de telefonia corretas, use:

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

Ele descarta informações de telefonia, que também podem ser encontradas em relatórios de bugs do Android. Em dispositivos com vários chips, há informações para cada rádio chip.

Os Registros de fuso horário mostram as sugestões que o processo de telefonia enviou para o time_zone_detector e os motivos para enviar as sugestões.

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")]}