使用Java查找区域的标准时间名称



是否可以找到时区区域下的标准时间,例如

America/New_York and America/NewJersey -> EST

我正在开发一个REST服务,其中请求将以基于区域的时区(美国/新泽西州(为参数,我需要找到它所属的标准时间,并将其传递给传统的API,后者只接受3位时区(EST/MST/CST/AET(。

我使用的是Java 8,我检查了Time API,但它没有任何这样的特性/功能。作为一种变通方法,我可以在文件或数据库中进行映射,但我只想知道是否有其他人面临这种情况,以及是否有任何干净的解决方案

如果我理解正确,主要要求是有一些特定的三字母缩写,这是您控制之外的API所需要的。例如:

东部标准时间的东部标准时间(可能是北美东部标准时间?(,而不是东部时间的东部时间
  • 另一方面,澳大利亚东部时间的AET,而不是澳大利亚东部标准时间的AEST(尽管我读到EST在澳大利亚也被用作缩写,但东部标准时间也不是EST(
  • 在我看来,Java知道的时区缩写(来自CLDR或您使用的区域设置数据提供程序(与API所需的缩写之间似乎没有系统的对应关系。作为另一个问题,三个字母的时区缩写通常是模糊的,所以我怀疑有许多时区是您的传统API无法识别的(或者它需要一些模糊的土布缩写,我们几乎没有机会猜测(。

    方法有两种:

    1. Deadpool长期以来在一篇评论中建议采用一种安全但又间接且费力的方法:构建并保存所需缩写的映射
    2. 看看Java所知道的缩写能走多远。要做好准备,你不可能涵盖所有情况,偶尔可能会做出错误的猜测

    我将保留选项1。我推荐你自己。

    如果你想试试选项2的运气,我会试试。

    private static final DateTimeFormatter ZONE_FORMATTER
    = DateTimeFormatter.ofPattern("zzz", Locale.ENGLISH);
    private static String getThreeLetterAbbreviation(ZoneId zone) {
    // Try the display name first
    String displayName = zone.getDisplayName(TextStyle.SHORT_STANDALONE, Locale.ENGLISH);
    if (displayName.length() == 3) {
    return displayName;
    }
    
    // Try formatting a date in standard time; try southern hemisphere first
    ZonedDateTime timeInStandardTime = LocalDate.of(2021, Month.JULY, 1)
    .atStartOfDay(zone);
    if (zone.getRules().isDaylightSavings(timeInStandardTime.toInstant())) {
    // Then northern hemisphere
    timeInStandardTime = LocalDate.of(2021, Month.JANUARY, 1)
    .atStartOfDay(zone);
    if (zone.getRules().isDaylightSavings(timeInStandardTime.toInstant())) {
    throw new IllegalArgumentException("Unable to find a date in standard time");
    }
    }
    return timeInStandardTime.format(ZONE_FORMATTER);
    }
    

    这种辅助方法进行了尝试:

    private static void printAbbreviation(String zid) {
    System.out.format("%19s -> %s%n", zid,
    getThreeLetterAbbreviation(ZoneId.of(zid)));
    }
    

    所以我们使用它:

    printAbbreviation("America/Los_Angeles");
    printAbbreviation("America/Denver");
    printAbbreviation("America/Chicago");
    printAbbreviation("America/New_York");
    printAbbreviation("Australia/Sydney");
    

    输出:

    America/Los_Angeles -> PST
    America/Denver -> MST
    America/Chicago -> CST
    America/New_York -> EST
    Australia/Sydney -> AET
    

    我不认为它是一个干净的解决方案。我特别担心的是,该方法会产生一个错误的结果,而API的解释与预期不同,没有人会注意到它反过来会产生错误的结果。例如:

    printAbbreviation("Asia/Shanghai");
    
    Asia/Shanghai -> CST
    

    这里的CST是中国标准时间,但我猜您的API会将其理解为北美中部标准时间。我们真的应该永远不要依赖三个字母的时区缩写。它们是模棱两可的,也许更多时候是这样。正如这个问题所表明的那样,它们并不是标准化的。

    相关内容

    最新更新