在Java中使用城市名称获取本地时区

时间:2019-04-18 14:14:47

标签: java timezone timezone-offset city

使用城市名称(例如阿布扎比,悉尼,达卡,巴黎等)需要查找当地时区。可以使用2位数的国家/地区代码

1 个答案:

答案 0 :(得分:0)

对于涵盖所有可想到的城市名称的解决方案,这将需要一个包含城市及其相应时区的数据库。由于存在具有相同名称的城市,这将使情况更加复杂,因此您可能输入的内容不明确。例如,在巴黎,我想您打算将法国和欧洲作为首都和最大城市,但在其他地方也存在称为巴黎的城镇。我不知道是否存在合适的数据库,您可以搜索。

不过,使用Java内置的功能,我可以使您接近。时区的ID格式为 region / city ,例如Australia/SydneyAsia/Dubai。命名时区时使用的城市是时区中人口最多的区域,因此即使在一个国家或州仅是一个时区的情况下, city 也不必是首都。但是如果城市重合,我们就可以找到区域。

    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]

不过,您会注意到,它没有为阿布扎比找到任何时区,因为尽管是阿拉伯联合酋长国的首都,但它不是最大的城市;迪拜是。您还会注意到,为印第安纳波利斯找到了两个时区。不过,前者只是后者的别名。

时区数据库中使用的城市名称是英文名称(如果存在的话),其中不包括任何重音符号。名称用两个或三个词表示时,它们之间用下划线而不是空格分隔。 SãoTomé成为Sao_Tome。因此,在代码中,我正在执行此转换。去除重音的方法来自另一个Stack Overflow答案,请点击下面的链接。

链接