如果我理解正确的话,主要要求是有一些特定的三字母缩写,这是您无法控制的 API 所需要的。比如:
- EST 表示东部标准时间(可能是北美东部标准时间?),而不是 ET 表示东部时间。
- 另一方面,AET 表示澳大利亚东部时间,而不是 AEST 表示澳大利亚东部标准时间(也不是 EST 表示东部标准时间,尽管我已经读过 EST 在澳大利亚也被用作缩写)。
在我看来,Java 知道的时区缩写(来自 CLDR 或您正在使用的区域设置数据提供者)与该 API 所需的缩写之间没有系统的对应关系。作为另一个问题,三个字母的时区缩写通常是模棱两可的,所以我怀疑有很多时区是您的遗留 API 根本无法识别的(或者它需要一些我们几乎没有机会猜测的晦涩的简单的缩写)。
方法有两种:
- Deadpool 长期以来在评论中建议的一种安全但又间接且费力的方法:构建并保留所需缩写的映射。
- 看看使用 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 会将它理解为北美中部标准时间。我们真的应该永远依赖三个字母的时区缩写。它们是模棱两可的,也许经常是这样。正如这个问题所示,它们不是标准化的。