TimeZones in Java
我允许我的web应用程序上的用户根据他们选择的时区来安排活动。
我想向最终用户提供一个很好的时区列表,然后在服务器端将其轻松转换为
我可以使用
向用户展示时区的简短列表(如时区设置的Windows框)并使用其ID轻松转换为服务器端的时区对象的最佳方法是什么?
时区列表非常特定于应用程序和区域设置。只有您知道哪些区域最适合您的用户。我们针对不同的地区有不同的列表。
这是我们的用户列表,供您参考。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | "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", |
我刚刚编写了一个小的Java实用工具,它提供了一个Windows时区列表(Windows中的时区选择对话框中的区域),以及它们相关的Java时区对象。请参阅https://github.com/nfergu/java-time-zone-list
这是基于位于http://unicode.org/repos/cldr/trunk/common/supplementary/windowszones.xml的cldr映射的。
您可以使用仅匹配以下regexp的TZ ID减少列表
1 | ^(Africa|America|Asia|Atlantic|Australia|Europe|Indian|Pacific)/.* |
为了补充tbruyelle的答案,我增加了一些国家(如加拿大),删除了过滤器的"/"部分,并提供了对列表进行排序的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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; } |
有了这么多,我就不想把它们塞进选择框列表了。我将它们放在一个单独的模式对话框(或者弹出窗口,如果必须的话)的列表中,让用户滚动并单击他们想要的名称。他们会点击模式对话框中的一个链接,它会用正确的代码填充一个文本字段,然后您可以将其提交给您的服务器。
更好的是,让他们在世界地图上单击他们的位置,并使用图像地图将该位置转换为适当的时区。
我是为一家我不再拥有的公司做的,所以不能提供代码。Windows上的JVM带有一个名为EDCOX1 OR 0的文件(参见EDCOX1,1或类似),它将Windows时区映射到Java的基于ZONEING的大陆/城市窗体。
不幸的是,
如果您需要精确选择列表的外观,我将使用我能找到的最佳硬编码列表(这是一个很好的示例),并确保尽可能精确地显示和转换列表。
请记住,585个时区中的每一个都具有语义含义(例如DST),用户可能希望为他们选择最佳时区。尽管我同意这个列表可以短得多。
您不能使用"gmt+/-hours"表示法(跳过分钟)的自定义时区ID列表吗?
(编辑:根据我的第一个建议,夏令时转换不是自动的。要解决此问题,您可以首先要求用户选择一个GMT偏移量,然后使用以下方法显示给定偏移量的时区ID列表(链接):
1 |
这样,用户可以在较短的列表中选择自己的时区(更好地满足用户体验),并从夏令时行为中获益。