Java 是否有办法获得(仅)带有国家代码(有效ISO-3166代码)的时区?

Java 是否有办法获得(仅)带有国家代码(有效ISO-3166代码)的时区?,java,timezone,locale,country,Java,Timezone,Locale,Country,我正在尝试为用户获取时区 为此,我有一个国家代码,这是一个有效的ISO国家代码。这些代码是ISO-3166定义的大写双字母代码。您可以在多个网站上找到这些代码的完整列表,例如: 我认为答案是“不,因为这是一种多人关系……像美国这样的国家可能有很多时区……”。这就是问题所在 我试过这样的方法: //CountryEnum contains ISO_3166 values (http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html) /

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

为此,我有一个国家代码,这是一个有效的ISO国家代码。这些代码是ISO-3166定义的大写双字母代码。您可以在多个网站上找到这些代码的完整列表,例如:

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

我试过这样的方法:

//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);
  }
//CountryEnum包含ISO3166值(http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html) 
//列出要测试时区的所有国家/地区:
对于(int i=0;i
但它总是返回服务器时区


有什么想法吗?

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


美国当然是一个简单的例子——你想使用哪个时区<代码>美国/洛杉矶
<代码>美国/纽约?还有什么吗?

我不知道有什么东西可以提供这个功能(正如Jon指出的,这个用例相当有限),但是你可以使用它来构建一个地图。列表将是一个多地图,因此您可能会使用Google Collections中的多地图,或者使用您自己的ISO代码->列表
地图


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

A
Locale
不是
时区,反之亦然。检查您正在使用的方法-第一行显示

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

这就是为什么您会获得默认时区-因为您在获取日历时没有指定一个时区

想想Jon说的话——如果你知道在你计算出一个用户来自美国的情况下你想使用哪个时区,那么你可以调用
Calendar.getInstance
方法,该方法采用时区和语言环境。另一方面,如果您不能确定在这里要做什么,那么请回到绘图板,再多考虑一下您的需求,而不是查看您的实现


如果你不能回答上一个问题,我认为大多数网站的标准方法是允许用户指定他们喜欢的时区(如果他们在服务器上有一个持久帐户),如果他们没有这样说,则默认为服务器的时区。如果他们没有永久帐户,并且他们向您提供时间信息(例如XML上载),那么他们必须指定他们在请求中使用的时区,或者(可能更好)您要求您在任何时候都使用UTC。

奥尔森数据库包含所有映射


搜索zone.tab文件

您可以使用ICU4J进行此操作。。。看

你试过宝石吗

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

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

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

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();
}

languageTag的代码类似于en_-US或ru_-ru

有趣的是,在一个时区上还有其他大国;印度和中国都属于这一类。印度通常会覆盖两个时区;中国将覆盖4个时区。是的——一些国家在时区问题上选择了理智:)理智——是的;有一种。但在中国,如果太阳在东海岸早上5点升起,那么在戈壁沙漠的西部边缘,太阳要到早上8点才会升起。如果在东海岸是晚上7点,在西海岸是晚上10点。@Jonathan:我觉得这很合理。。。组织会议(etc)时不必考虑时区的好处是巨大的。我不喜欢时区:)没错,这是我最好的解决办法。我想我可能会将时区映射到一个国家,以便在每个国家都有一个唯一的时区。不仅如此,而且单个arg
Locale
构造函数指定了语言,而不是国家。这很方便,但返回的列表似乎是按名称的字母顺序排列的;遗憾的是,ICU4J没有提供一种方法来获取“国家代码最不令人惊讶的时区”用于显示目的;这是一个Java问号,它将返回
TimeZone.getDefault()