我想根据当前时区获取任何国家的国家代码。
要实现此目的,我在我的react js项目中使用了Momentjs
和countries-and-timezones包。
一切正常,除了有时在(UTC +01:00) West Central Africa
时区,我得到了这些值Africa/Lagos
和Africa/Luanda
。
在我的情况下,我想要首都为罗安达的安哥拉的国家代码,但是由于我使用的是countries-and-timezones
,因此没有Africa/Luanda
作为安哥拉的时区,这会引发未定义的错误。
当我查看Momentjs打包的data.json文件时,发现:"Africa/Lagos|Africa/Luanda"
。这不是唯一要更新的时区,有很多。
所以我想知道的是:
如何从Africa/Lagos
函数中获取原始值Moment.tz.guess()
。因为我不想从countries-and-timezones
编辑我正在使用的data.json来更正错误。另外,我发现许多此类JSON文件都包含相同的旧时区。
或者有没有更好的库可以从时区获取国家/地区代码,因为我不能使用timezonedb
或ip-api
之类的任何服务从IP地址获取国家/地区代码。非常感谢您的帮助。
答案 0 :(得分:1)
...有时在
(UTC+01:00) West Central Africa
时区,我会得到这些值Africa/Lagos
和Africa/Luanda
。
是正确的。您提到的Windows时区有多个有效的IANA时区映射。 Unicode CLDR是这些映射的权限,您可以在windowsZones.xml
文件中查看,目前看起来像这样:
<!-- (UTC+01:00) West Central Africa -->
<mapZone other="W. Central Africa Standard Time" territory="001" type="Africa/Lagos"/>
<mapZone other="W. Central Africa Standard Time" territory="AO" type="Africa/Luanda"/>
<mapZone other="W. Central Africa Standard Time" territory="BJ" type="Africa/Porto-Novo"/>
<mapZone other="W. Central Africa Standard Time" territory="CD" type="Africa/Kinshasa"/>
<mapZone other="W. Central Africa Standard Time" territory="CF" type="Africa/Bangui"/>
<mapZone other="W. Central Africa Standard Time" territory="CG" type="Africa/Brazzaville"/>
<mapZone other="W. Central Africa Standard Time" territory="CM" type="Africa/Douala"/>
<mapZone other="W. Central Africa Standard Time" territory="DZ" type="Africa/Algiers"/>
<mapZone other="W. Central Africa Standard Time" territory="GA" type="Africa/Libreville"/>
<mapZone other="W. Central Africa Standard Time" territory="GQ" type="Africa/Malabo"/>
<mapZone other="W. Central Africa Standard Time" territory="NE" type="Africa/Niamey"/>
<mapZone other="W. Central Africa Standard Time" territory="NG" type="Africa/Lagos"/>
<mapZone other="W. Central Africa Standard Time" territory="TD" type="Africa/Ndjamena"/>
<mapZone other="W. Central Africa Standard Time" territory="TN" type="Africa/Tunis"/>
<mapZone other="W. Central Africa Standard Time" territory="ZZ" type="Etc/GMT-1"/>
在大多数情况下,列出的所有IANA区域都是等效的,并且都与给定的Windows区域对齐。 CLDR将Africa/Lagos
称为“黄金地带”(territory="001"
)。通常,在国家/地区代码可用时,实现应使用国家/地区代码特定的映射,否则请使用黄金区域。
...由于我使用的是
countries-and-timezones
,因此没有非洲/罗安达作为安哥拉的时区...
通过查看该特定程序包的GitHub来源,尚不清楚其数据源自何处。另外,它已经3年没有更新了。如果没有定期更新和明确的来源,此类软件包通常就不可用(IMHO)。
...当我查看Momentjs打包的data.json文件时,发现:“ Africa / Lagos | Africa / Luanda”。这不是唯一要更新的时区,有很多。
实际上,Moment-timezone将链接等效的区域。要认识到的一个实现细节是,此刻不一定会把“黄金地带”放在第一位。它只是按字母顺序排列,当看到两个具有相同数据的区域时,它将它们组合在一起。这是相对不重要的,因为时区本身确实具有相同的数据(偏移量,转换和缩写匹配)。
如何从
Moment.tz.guess()
函数获得原始值Africa / Lagos。
好吧,这里没有“原始”值,所以您不能。原始值为Windows时区(“ W.中非标准时间”)。 Moment首先尝试使用JavaScript Intl
API直接从浏览器获取IANA时区ID-因此,根据实现的不同,浏览器可能会返回 any 等效时区ID。因此,在此区域的CLDR映射中,某些实现可能会给出Africa/Lagos
,有些可能会给出Africa/Luanda
,或者其他任何实现。
对于没有使用Intl
API的实现,moment.tz.guess
会根据其拥有的数据(无论装入了什么)测试本地时区的偏移量,然后选择一个匹配的数据。如果有平局,则其中包含一些有关人口的其他数据,以选择更常见的人口。您可以在一下时区文档中以及源代码中moment.tz.guess
函数的实现中了解这些详细信息。
请记住,仅仅因为您在不同环境中从moment.tz.guess
获得了不同的结果,并不意味着这些结果是无效的。您仍然应该能够使用返回给您的任何结果。
或者有没有更好的库可以从时区获取国家/地区代码...
我不知道一个维护良好的JavaScript库可以方便地为您完成此操作。我很想创建一个(就像我对.NET所做的那样),但是与此同时,您可以阅读JSON version of the CLDR mapping file并自己解析。
...因为我无法使用timezonedb或ip-api之类的任何服务来从IP地址获取国家/地区代码...
除了IP地址,您可能还会考虑是否有一个可以提供经度/纬度的位置?如果是这样,请查看in this question中列出的方法,以了解如何使用该方法获取时区ID。