使用城市名称(示例。阿布扎比、悉尼、达卡、巴黎等)需要查找本地时区。可以使用 2 位国家代码
对于涵盖所有可以想象的城市名称的解决方案,这将需要一个包含城市及其相应时区的数据库。由于存在同名城市,这将变得更加复杂,因此您可能会有模棱两可的输入。例如,我猜你说的巴黎是指法国的首都和最大的城市,欧洲,但其他地方也存在叫巴黎的城镇。我不知道是否存在合适的数据库,您可以搜索。
不过,我可以让你接近Java中内置的内容。时区的 ID 格式为区域/城市,例如Australia/Sydney
和Asia/Dubai
。用于命名时区的城市是时区中人口最多的区域,因此即使一个国家或州只有一个时区,城市也不必是首都。但如果城市重合,我们可以找到该区域。
Set<String> zids = ZoneId.getAvailableZoneIds();
String[] cityNames = { "Abu Dhabi", "Dubai", "Sydney", "Dhaka", "Paris", "Indianapolis", "São Tomé" };
for (String cityName : cityNames) {
String tzCityName = Normalizer.normalize(cityName, Normalizer.Form.NFKD)
.replaceAll("[^\p{ASCII}-_ ]", "")
.replace(' ', '_');
List<String> possibleTimeZones = zids.stream()
.filter(zid -> zid.endsWith("/" + tzCityName))
.collect(Collectors.toList());
System.out.format("%-12s %s%n", cityName, possibleTimeZones);
}
此代码段的输出为:
Abu Dhabi []
Dubai [Asia/Dubai]
Sydney [Australia/Sydney]
Dhaka [Asia/Dhaka]
Paris [Europe/Paris]
Indianapolis [America/Indianapolis, America/Indiana/Indianapolis]
São Tomé [Africa/Sao_Tome]
但是,您会注意到,它没有找到阿布扎比的任何时区,因为尽管它是阿拉伯联合酋长国的首都,但它不是最大的城市;迪拜是。您还会注意到,印第安纳波利斯发现了两个时区。不过,前者只是后者的别名。
时区数据库中使用的城市名称是英文名称(如果存在),去除任何重音。当名称由两个或三个单词组成时,它们由下划线而不是空格分隔。所以圣多美变得Sao_Tome。因此,在代码中,我正在执行此转换。去除重音的方法取自另一个堆栈溢出答案,链接如下。
链接
- 维基百科上的tz数据库时区列表
- 回答 埃里克·罗伯逊 有没有办法摆脱重音并将整个字符串转换为常规字母?