2009-11-08 32 views
24

我允许用户在我的web应用程序上根据他们选择的时区安排事件。Java中的时区

我想向最终用户展示一个很好的时区列表,然后将其轻松转换为服务器端的java.util.TimeZone对象。

String[] TimeZone.getAvailableIds()是我可以使用的,但问题是它打印了大约585个时区ID。

什么是最好的方式向用户提供时区的简短列表(如Windows时区设置的时间框),并轻松地使用它的ID在服务器端转换为TimeZone对象?

+0

作为参考,维基百科保留[时区名称列表](http://en.wikipedia.org/wiki/List_of_tz_database_time_zones)。 – 2014-05-11 06:39:47

回答

20

时区列表是非常具体的应用程序和区域设置。只有您知道哪些区域最适合您的用户。我们实际上对不同地区有不同的名单。

下面是我们为美国用户,供大家参考名单,

"Pacific/Midway", 
    "US/Hawaii", 
    "US/Alaska", 
    "US/Pacific", 
    "America/Tijuana", 
    "US/Arizona", 
    "America/Chihuahua", 
    "US/Mountain", 
    "America/Guatemala", 
    "US/Central", 
    "America/Mexico_City", 
    "Canada/Saskatchewan", 
    "America/Bogota", 
    "US/Eastern", 
    "US/East-Indiana", 
    "Canada/Eastern", 
    "America/Caracas", 
    "America/Manaus", 
    "America/Santiago", 
    "Canada/Newfoundland", 
    "Brazil/East", 
    "America/Buenos_Aires", 
    "America/Godthab", 
    "America/Montevideo", 
    "Atlantic/South_Georgia", 
    "Atlantic/Azores", 
    "Atlantic/Cape_Verde", 
    "Africa/Casablanca", 
    "Europe/London", 
    "Europe/Berlin", 
    "Europe/Belgrade", 
    "Europe/Brussels", 
    "Europe/Warsaw", 
    "Africa/Algiers", 
    "Asia/Amman", 
    "Europe/Athens", 
    "Asia/Beirut", 
    "Africa/Cairo", 
    "Africa/Harare", 
    "Europe/Helsinki", 
    "Asia/Jerusalem", 
    "Europe/Minsk", 
    "Africa/Windhoek", 
    "Asia/Baghdad", 
    "Asia/Kuwait", 
    "Europe/Moscow", 
    "Africa/Nairobi", 
    "Asia/Tbilisi", 
    "Asia/Tehran", 
    "Asia/Muscat", 
    "Asia/Baku", 
    "Asia/Yerevan", 
    "Asia/Kabul", 
    "Asia/Yekaterinburg", 
    "Asia/Karachi", 
    "Asia/Calcutta", 
    "Asia/Colombo", 
    "Asia/Katmandu", 
    "Asia/Novosibirsk", 
    "Asia/Dhaka", 
    "Asia/Rangoon", 
    "Asia/Bangkok", 
    "Asia/Krasnoyarsk", 
    "Asia/Hong_Kong", 
    "Asia/Irkutsk", 
    "Asia/Kuala_Lumpur", 
    "Australia/Perth", 
    "Asia/Taipei", 
    "Asia/Tokyo", 
    "Asia/Seoul", 
    "Asia/Yakutsk", 
    "Australia/Adelaide", 
    "Australia/Darwin", 
    "Australia/Brisbane", 
    "Australia/Sydney", 
    "Pacific/Guam", 
    "Australia/Hobart", 
    "Asia/Vladivostok", 
    "Asia/Magadan", 
    "Pacific/Auckland", 
    "Pacific/Fiji", 
    "Pacific/Tongatapu", 
0

难道你不能使用“GMT +/- Hours”符号(跳过分钟)的自定义时区ID列表吗? (编辑:我的第一个建议,夏令时转换不是自动的。要解决这个问题,你可以先要求用户选择一个GMT偏移量,然后显示一个(链接的)时区ID列表利用给定的偏移。

public static String[] getAvailableIDs(int rawOffset) 

通过这种方式,用户将能够选择自己的时区在名单,并受益于夏令行为(用户体验更好))

+1

谢谢。 是的,但是使用它创建的java.util.TimeZone不会自动考虑夏令时。 如果我使用TimeZone.getTimeZone(“America/Los_Angeles”)创建时区,那么我不需要担心DST等。 或者我错了吗? – Vish 2009-11-08 00:28:18

+0

你说得对。事实上,没有夏令时转换为自定义时区ID。我会用另一个建议更新我的答案。 – 2009-11-08 02:12:48

+0

谢谢。这也适用! – Vish 2009-11-08 21:20:46

0

如果您需要确切地选择列表的样子的粒度,我会使用最好的硬编码列表I.可以找到(this is a good example),并确保它尽可能精确地显示和转换。

请记住,这585个时区中的每一个都具有语义含义(例如DST),用户可能希望为他们选择最佳时区。虽然我确实同意,名单可以更短。

+0

我不明白如何清单可以解释夏令时,不幸的是... – 2012-07-20 04:14:21

0

我这样做是为我公司不拥有任何的了,所以不能提供的代码。 Windows上的JVM附带一个名为tzmappings的文件(请参阅C:\Program Files\Java\jre6\lib或类似文件),它将Windows时区映射到Java的基于zoneinfo的Continent/City表单。

不幸的是,tzmappings中的文本名称很糟糕,所以您需要做几分钟的制表。打开regedit并导航到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones。在这下是机器上每个时区的关键; Windows 7约有90个。每个密钥都有一个名为Display的值,它是您想要的文本名称;请在tzmappings中查找密钥本身以查找每个密钥的Java时区标识符。

0

有了这么多,我不会试图将它们塞进一个选择框列表....我会把它们放在一个单独的模式对话框中(或弹出,如果你必须的话),让用户滚动并点击他们想要的名字。他们会点击模式对话框中的链接,然后用正确的代码填充文本字段,然后将其提交到服务器。

更好的是,让他们在世界地图上点击自己的位置,然后使用图像地图将该位置转换为适当的时区。

4

可以减少与TZ的ID列表只匹配以下正则表达式

^(Africa|America|Asia|Atlantic|Australia|Europe|Indian|Pacific)/.* 
11

我刚写了一个小的Java应用程序,提供Windows时区列表(在时区选择的区域,其Windows中的对话框)及其相关的Java TimeZone对象。见https://github.com/nfergu/Java-Time-Zone-List

这是基于CLDR映射在http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml

+0

在TimeZoneList上干得好。感谢您将所有Microsoft时区映射到Java ID。 – Peter 2012-05-17 13:11:13

+0

我同意。这是我正在寻找的东西。 – JamesA 2014-07-18 05:39:22

0

只是为了通过tbruyelle补充答案,我增加了一些国家(如加拿大),去除过滤器的“/”部分,并提供了一个途径对列表进行排序。

public static void main(String[] args) 
{ 
    List<String> simplifiedTimezoneList = getTimezoneIdList(); 

    for (String tz : simplifiedTimezoneList) 
     System.out.println(tz); 
} 

public static List<String> getTimezoneIdList() 
{ 
    String[] temp = TimeZone.getAvailableIDs(); 
    List<String> timezoneList = new ArrayList<String>(); 
    List<String> simplifiedTimezoneList = new ArrayList<String>(); 
    for (String tz : temp) 
    { 
     timezoneList.add(tz); 
    } 
    Collections.sort(timezoneList); 
    String filterList = "Canada|Mexico|Chile|Cuba|Brazil|Japan|Turkey|Mideast|Africa|America|Asia|Atlantic|Australia|Europe|Indian|Pacific"; 
    Pattern p = Pattern.compile("^(" + filterList + ").*"); 
    for (String tz : timezoneList) 
    { 
     Matcher m = p.matcher(tz); 
     if (m.find()) 
     { 
      simplifiedTimezoneList.add(tz); 
     } 
    } 
    return simplifiedTimezoneList; 
}