是否可以找到时区区域下的标准时间,例如
America/New_York and America/NewJersey -> EST
我正在开发一个REST服务,其中请求将以基于区域的时区(美国/新泽西州(为参数,我需要找到它所属的标准时间,并将其传递给传统的API,后者只接受3位时区(EST/MST/CST/AET(。
我使用的是Java 8,我检查了Time API,但它没有任何这样的特性/功能。作为一种变通方法,我可以在文件或数据库中进行映射,但我只想知道是否有其他人面临这种情况,以及是否有任何干净的解决方案
如果我理解正确,主要要求是有一些特定的三字母缩写,这是您控制之外的API所需要的。例如:
东部标准时间的东部标准时间(可能是北美东部标准时间?(,而不是东部时间的东部时间在我看来,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会将其理解为北美中部标准时间。我们真的应该永远不要依赖三个字母的时区缩写。它们是模棱两可的,也许更多时候是这样。正如这个问题所表明的那样,它们并不是标准化的。