2017-08-24 32 views
1

不同的結果,我使用的JavaScript國際API來檢測瀏覽器的用戶的時區:JavaScript的國際API提供了在Chrome

Intl.DateTimeFormat().resolvedOptions().timeZone 

雖然這個API​​,我不知道如何處理接下來的事情。在我的Windows 10的機器,該時區設置爲US Eastern Standard Time

C:\> tzutil /g 
US Eastern Standard Time 

在Firefox與"America/Indiana/Indianapolis"封邊上面的JavaScript代碼的結果,而Chrome瀏覽器只返回"America/Indianapolis"

爲什麼這會產生不同的瀏覽器不同的結果?是Chrome bug嗎?還是應該在處理服務器之前以某種方式轉換時區?

在Ubuntu(這是我的服務器操作系統),如果我列出了可用的時區與timedatectl list-timezones,有"America/Indiana/Indianapolis",但沒有"America/Indianapolis"。由於這個問題,我無法接受來自客戶端的Chrome的"America/Indianapolis",因爲我從timedatectl list-timezones的輸出中獲取「可用時區列表」。我應該在這裏適用哪些行爲?

任何幫助表示讚賞。謝謝!

+1

實際上,兩者是相同的 - 檢查他們的名字在[本列表](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)(一個是鏈接另一個)。也請查看[這裏](https://github.com/eggert/tz/blob/master/backward) – 2017-08-24 17:40:45

+0

https://unix.stackexchange.com/questions/35781/why-is-zone-tab-missing-so - 多個時區 –

+0

@Hugo,謝謝。您鏈接的「後退」文件是否提供完整的「時區別名」列表?算法應該是什麼?看起來像是我的LINK-NAME具有確切的時區名稱,我需要在該表格中將其更改爲TARGET。它是否正確?那麼你能回答一個問題嗎? – ZitRo

回答

2

Chrome與許多其他Chrome瀏覽器一樣,通過ICU獲取其時區信息,該信息源自CLDR,部分源自IANA

IANA和CLDR之間在規範化方面存在細微差異。

  • IANA對待優選形式的時區標識符作爲典型的。如果首選表單發生更改,則會使新主表單(一個Zone條目)並將舊錶單移動到別名(Link條目)。

  • CLDR處理第一個形式的時區標識符爲規範。也就是說,它第一次出現在CLDR中,它永遠被鎖定。如果出現新表單,則會將其添加爲/common/bcp47/timezone.xml文件中的別名。

以你的印第安納波利斯的情況下:

  • IANA區入口(reference here

    Zone America/Indiana/Indianapolis ... 
    
  • IANA鏈接條目(reference here

    Link America/Indiana/Indianapolis America/Indianapolis 
    
  • 在CLDR中,主要區域首先列在「別名」屬性中,後跟別的別名。 (reference here

    <type name="usind" description="Indianapolis, United States" alias="America/Indianapolis America/Fort_Wayne America/Indiana/Indianapolis US/East-Indiana"/> 
    

同樣的事情可以用Asia/CalcuttaAsia/Kolkata和其他幾個例子可以找到。

此外,請注意,Windows時區映射也源自CLDR,文件爲/common/supplemental/windowsZones.xml。你會注意到US Eastern Standard Time映射到America/Indianapolis因此,瀏覽器之間的差異很大程度上取決於遵循哪些規範化規則。

最後,使用哪個別名並不重要。他們指向相同的數據。

另外值得指出的是,只有在您關心historical time changes in Indiana時才應選擇該特定Windows區域。如果您剛剛在美國東部時區,則應將系統設置爲"Eastern Standard Time",而不是"US Eastern Standard Time"。 (是的,這些ID是令人困惑的...)

+0

非常感謝你對這樣的擴展描述!一切都很有意義。事實上,我在我的Moment.js項目中使用moment-timezone(以及其他一些庫)來解決這個問題,因爲使用這些庫會使處理時間翻倍,這是至關重要的(我的項目構建了多時區,基於日曆數據的二維數據透視表)。因此,我決定使用集羣啓動工作人員,並將每個工作人員初始化到一個特定的時區,而不是在處理時區和替換時間區域並替換「Date」對象(NodeJS),這在NodeJS/V8中是可行的。 – ZitRo

+0

很好的回答!我一直認爲瀏覽器直接從SO讀取這些信息。我並不感到驚訝,因爲每個人都遵循不同的規則 - 我對此的瞭解越多,看起來就越困惑。 – 2017-08-24 21:11:02

+1

@Hugo - 歡迎來到我的世界。 ;) –

1

zone.tab不完整。某些時區表示爲符號鏈接:

$ find /usr/share/zoneinfo/America -name Indianapolis -exec file {} \; 
/usr/share/zoneinfo/America/Indiana/Indianapolis: symbolic link to ../Indianapolis 
/usr/share/zoneinfo/America/Indianapolis: timezone data, version 2, 7 gmt time flags, 7 std time flags, no leap seconds, 99 transition times, 7 abbreviation chars 
+0

謝謝喬希!那麼獲得所有可用時區列表的最佳方式是什麼?通過'/ usr/share/zoneinfo'來查找?擁有這個列表的目的是爲了能夠在處理任何數據之前驗證用戶請求的時區(在我的例子中,產生一個新進程,進行計算等)。 – ZitRo

1

我不知道如何/爲什麼每個瀏覽器返回不同的結果(可能是他們從不同的來源和/或它可以是由於每個如何實現讀Intl.DateTimeFormat) 。但沒關係,因爲兩者都是同一時區。

如果你檢查this list,你會看到America/Indianapolis鏈接到America/Indiana/Indianapolis。格式爲Region/City的這些名稱由IANA維護,它可能是我們有關時區信息的最佳來源之一。

IANA也保持了backward file映射的2名,與America/Indiana/Indianapolis是最近的一個。

那麼一個替代方案是讓落後的文件的副本,並用它來映射您收到相應的新名字任何名義,也驗證對您的服務器的時區列表。

+1

謝謝!看起來我最終將通過添加來自[後退文件](https:// github)的別名。com/eggert/tz/blob/master/backward)添加到'timedatectl list-timezones'的結果中,這樣可以創建一個(完整的?)可用時區列表。 – ZitRo

+1

@ZitRo不客氣!該清單將盡可能完整。時區是由政府和法律界定的,政界人士(他們喜歡改變他們)(https://www.timeanddate.com/news/time),無論出於何種原因(請參閱[git中的更改列表](https:/ /github.com/eggert/tz/commits/master)有一個想法)。當然,新的**時區比改變現有區域的規則更不常見,但是如果您想要有一個「完整」列表,則必須始終更新此文件。祝你好運! – 2017-08-24 18:33:10