電話時區偵測

如果裝置搭載 Android 11 以下版本,AOSP 中的自動時區偵測功能會依據電話子系統的訊號運作。由於 Android 11 以下版本會依附電話子系統,因此自動偵測時區功能僅適用於電話裝置。

如果可以使用電話時區偵測功能,系統會透過行動裝置國家/地區代碼 (MCC)網路身分與時區 (NITZ) 訊號偵測時區。

舉例來說,比利時的裝置可以只根據附近基地台回報的 MCC 判斷時區。這是因為比利時只使用單一時區。

如果國家/地區使用多個時區,光靠 MCC 無法識別時區。在這些國家/地區,裝置也會使用 NITZ 訊號來判斷正確時區。這項功能在全球許多地方都能正常運作,但必須提供正確的 NITZ 信號,因此取決於電信業者。

電話時區偵測器是被動偵測器,這項演算法會持續運作,因此即使目前的time_zone_detector演算法並非電話,系統仍經常會提供電話建議。

電話時區偵測的限制

即使有正確的 NITZ 訊號,電話時區偵測功能也不一定能在每個國家/地區正常運作。這是因為 NITZ 只包含時差和日光節約時間資訊,這些資訊不一定足以明確識別時區。

全球各地都有可能發生時區問題。舉例來說,在美國,科羅拉多州丹佛市和亞利桑那州鳳凰城在冬季無法透過 NITZ 信號區分,但在其他季節可以。凡是時區重疊的地區,都可能發生這類問題。

下表以丹佛和鳳凰城為例,說明裝置在不同季節的行為:

地點和季節 MCC 或 NITZ 提供的資訊 偵測到的時區和行為
科羅拉多州丹佛
冬季
時間:2021 年 1 月 1 日 12:00:00
國家/地區:美國
時差:UTC-7,無日光節約時間
兩個區域 ID 相符:
  • 美洲/丹佛
  • America/Phoenix

裝置正確設為 America/Denver。
亞利桑那州鳳凰城
冬季
時間:2021 年 1 月 1 日 12:00:00
國家/地區:美國
時差:UTC-7,無日光節約時間
兩個區域 ID 相符:
  • 美洲/丹佛
  • America/Phoenix

  • 裝置錯誤
設定為美洲/丹佛。
科羅拉多州丹佛
夏季
時間:2021 年 7 月 1 日 12:00:00
國家/地區:美國
時差:UTC-6,夏令時間
一個區域 ID 相符:
  • 美洲/丹佛

裝置正確設為 America/Denver。
亞利桑那州鳳凰城
夏季
時間:2021 年 7 月 1 日 12:00:00
國家/地區:美國
時差:UTC-7,無日光節約時間
一個區域 ID 相符:
  • America/Phoenix

裝置正確設為 America/Phoenix。

下表中的範例顯示,在冬季,丹佛或亞利桑那州的 Android 裝置必須選擇兩個相符時區 ID 的其中一個,這對某些裝置來說可能不正確,但仍會顯示看似正確的當地時間。即使時區 ID 不正確,裝置時鐘、日曆和其他應用程式仍會顯示預期的當地時間,因為這兩個時區 ID 在冬季計算出的當地時間相同。

不過,在春季,丹佛會實施日光節約時間,鳳凰城則不會。如果裝置設定的使用者所在位置時區 ID 有誤,可能會暫時顯示錯誤的當地時間。裝置收到新的 NITZ 信號 (特別是包含「UTC-7,無日光節約時間」時差資訊的信號) 後,就會修正時區,但這可能需要一段時間,且取決於電信業者。

因此,如果日曆或其他應用程式儲存或沿用從冬季到春季的時區 ID,相關應用程式更新時區 ID 前,可能會顯示及使用錯誤的當地時間。

偵錯和測試

以下章節說明如何使用 Shell 指令偵錯及測試電話時區偵測功能。

設定測試環境

測試人員通常會使用測試環境,並透過測試或模擬電話網路單元,檢查電話時區偵測行為。測試單元可用於模擬具有不同 MCC 的網路,並將 NITZ 信號傳送至裝置,然後監控其影響。

如要讓裝置偵測時區,NITZ 訊號資訊必須正確無誤、與 MCC 一致,且與裝置的 IANA TZDB (時區規則) 副本相符。如果 NITZ 信號與 MCC 不一致,電話演算法就會變得不確定。

舉例來說,如果測試單元使用的 MCC 是美國,則 NITZ 信號必須包含美國某地的正確世界標準時間、時差和日光節約時間資訊。

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