有没有办法获取(仅)包含国家/地区代码(有效的 ISO-3166 代码)的时区?

问题描述 投票:0回答:8

我正在尝试为用户获取时区。

为此,我有一个国家/地区代码,它是有效的 ISO 国家/地区代码。这些代码是 ISO-3166 定义的大写两字母代码。您可以在许多网站上找到这些代码的完整列表,例如: http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html

我认为答案是“不,因为这是一种多对多的关系......像美国这样的国家可以有很多时区......”。这就是问题所在...

我尝试过类似的事情:

//CountryEnum contains ISO_3166 values (http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html) 
  //List all country to test timezone:
  for (int i = 0; i < CountryEnum.values().length; i++) {
   String isoCountryCode = CountryEnum.values()[i].name();// Get the iso country code
   Locale locale = new Locale(isoCountryCode);// Build a country specific locale
   Calendar calendar = Calendar.getInstance(locale);// Build a calendar with the specific locale
   String timeZone = calendar.getTimeZone().getDisplayName();// Build a timeZone with the calendar
   System.out.println("LOCALE : "+locale+" / COUNTRY: "+isoCountryCode+" / TIMEZONE: "+timeZone);
  }

但它总是返回服务器时区...

有什么想法吗?

java timezone locale country
8个回答
6
投票

A

Locale
不是
TimeZone
,反之亦然。检查 Javadoc 了解您正在使用的方法 - 第一行说

使用默认时区和指定区域设置获取日历。

这就是您获得默认时区的原因 - 因为您在获取日历时没有指定时区。

想想 Jon 所说的 - 如果您知道在确定用户来自美国的情况下要使用哪个时区,那么您可以调用

Calendar.getInstance
方法,该方法采用时区 语言环境。另一方面,如果您不能明确地说出您要在这里做什么,那么请返回到绘图板并更多地考虑您的需求,而不是查看您的实现。

如果您无法回答上一个问题,我认为大多数网站的标准资源是允许用户指定他们的首选时区(如果他们在服务器上有持久帐户),如果他们没有,则将其默认为服务器的时区不然的话。如果他们没有持久帐户,并且他们向您提供时间信息(例如 XML 上传),那么他们必须指定他们在请求中使用的时区,或者(可能更好)您强制要求所有时间都使用 UTC。



3
投票

你说得完全正确。美国、俄罗斯或其他各种“大国”(就东/西而言)没有一个时区。

美国当然是一个简单的例子 - 您想使用哪个时区?

America/Los_Angeles
America/New_York
?还有别的吗?


0
投票

我不知道有什么可以给你这个(正如乔恩指出的用例相当有限),但你可以使用这个数据构建一个地图。该列表将是一个多地图,因此您可能会使用 Google Collections 中的列表,或者使用您自己的 ISO 代码->List

<String>
地图。

给定时区字符串,您可以创建一个 TimeZone 对象并从那里开始。但是,如果该国家/地区有多个时区,您必须决定如何处理。


0
投票

ISO3 国家/地区代码和时区之间不存在 1 对 1 的映射,因为一个国家/地区可以有多个。

作为一种解决方法,您可以为您感兴趣的国家/地区使用如下所示的自定义地图。请记住,这张地图完全有问题,因为没有将时区定义为国家/地区“主要”时区的惯例我知道。

private static final Map<CountryEnum, String> mainTimeZones;
static {
    Map<CountryEnum, String> timezoneMap = new HashMap<>();
    timezoneMap.put(ARG, "America/Argentina/Buenos_Aires");
    timezoneMap.put(BGR, "Europe/Sofia");
    timezoneMap.put(BRA, "America/Sao_Paulo");
    timezoneMap.put(CHN, "Asia/Shanghai");
    timezoneMap.put(CZE, "Europe/Prague");
    timezoneMap.put(CHE, "Europe/Zurich");
    timezoneMap.put(DEU, "Europe/Berlin");
    timezoneMap.put(ESP, "Europe/Madrid");
    timezoneMap.put(FRA, "Europe/Paris");
    timezoneMap.put(GBR, "Europe/London");
    timezoneMap.put(HRV, "Europe/Zagreb");
    timezoneMap.put(IND, "Asia/Kolkata");
    timezoneMap.put(ITA, "Europe/Rome");
    timezoneMap.put(LTU, "Europe/Vilnius");
    timezoneMap.put(MNE, "Europe/Podgorica");
    timezoneMap.put(NLD, "Europe/Amsterdam");
    timezoneMap.put(POL, "Europe/Warsaw");
    timezoneMap.put(PRT, "Europe/Lisbon");
    timezoneMap.put(ROU, "Europe/Bucharest");
    timezoneMap.put(RUS, "Europe/Moscow");
    timezoneMap.put(SRB, "Europe/Belgrade");
    timezoneMap.put(SVK, "Europe/Bratislava");
    timezoneMap.put(TUR, "Europe/Istanbul");
    timezoneMap.put(USA, "America/New_York");
    timezoneMap.put(UKR, "Europe/Kiev");
    timezoneMap.put(HUN, "Europe/Budapest");
    timezoneMap.put(ALL, "Europe/Tirane");
    timezoneMap.put(CHL, "America/Santiago");
    timezoneMap.put(MEX, "America/Mexico_City");
    timezoneMap.put(EST, "Europe/Tallinn");
    timezoneMap.put(LVA, "Europe/Riga");
    timezoneMap.put(COL, "America/Bogota");
    ....
    mainTimeZones = Collections.unmodifiableMap(timezoneMap);

-1
投票

这是您正在寻找的解决方案:

public String getTimeZoneByLocale(final String languageTag){
    final Locale locale = Locale.forLanguageTag(languageTag);
    final Calendar cal = Calendar.getInstance(locale);
    final TimeZone timeZone = cal.getTimeZone();
    return timeZone.getID();
}

语言标签是类似 en_US 或 ru_RU 的代码


-2
投票

olson 数据库包含所有映射。 链接

搜索 zone.tab 文件。


-3
投票

您尝试过TZInfo gem 吗?

您可以通过以下方式获取一个国家/地区的时区:

>> TZInfo::Country.get("DE").zone_identifiers
=> ["Europe/Berlin", "Europe/Busingen"]
>> TZInfo::Country.get("CN").zone_identifiers
=> ["Asia/Shanghai", "Asia/Harbin", "Asia/Chongqing", "Asia/Urumqi", "Asia/Kashgar"]
>> TZInfo::Country.get("US").zone_identifiers
=> ["America/New_York", "America/Detroit", "America/Kentucky/Louisville",   "America/Kentucky/Monticello", "America/Indiana/Indianapolis", "America/Indiana/Vincennes", "America/Indiana/Winamac", "America/Indiana/Marengo", "America/Indiana/Petersburg", "America/Indiana/Vevay", "America/Chicago", "America/Indiana/Tell_City", "America/Indiana/Knox", "America/Menominee", "America/North_Dakota/Center", "America/North_Dakota/New_Salem", "America/North_Dakota/Beulah", "America/Denver", "America/Boise", "America/Phoenix", "America/Los_Angeles", "America/Anchorage", "America/Juneau", "America/Sitka", "America/Yakutat", "America/Nome", "America/Adak", "America/Metlakatla", "Pacific/Honolulu"]
© www.soinside.com 2019 - 2024. All rights reserved.