如何在 ICU4J 中获取“当前”IANA 时区缩写?
我目前正在尝试编写一套时区验证程序,以查看各种平台是否解释 IANA 时区数据。
我的目标输出格式包括对特定时间有效的缩写 - 例如“BST”表示“英国夏令时”,或“PST”表示“太平洋标准时间”。
在大多数平台上,这很容易 - 但奇怪的是,ICU4J似乎不起作用。根据SimpleDateFormat
文档,我应该能够使用“zzz”模式来获得我正在寻找的东西,但这似乎在很多时候都回落到GMT + X的“O”模式。对于某些时区,根本没有缩写。
使用纽约的简短示例:
import java.util.Date;
import java.util.Locale;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.text.SimpleDateFormat;
public class Test {
public static void main(String[] args) {
TimeZone zone = TimeZone.getTimeZone("America/New_York");
SimpleDateFormat format = new SimpleDateFormat("zzz", Locale.US);
format.setTimeZone(zone);
// One month before the unix epoch
System.out.println(format.format(new Date(-2678400000L))); // GMT-5
// At the unix epoch
System.out.println(format.format(new Date(0L))); // EST
}
}
(我正在使用ICU4J 55.1运行,无论是库存下载还是在2015e数据发布更新后。
我不清楚ICU4J是从tz数据还是从CLDR中获取其缩写 - 我怀疑它是后者,因为tz数据中没有任何内容表明这里的差异。
它似乎也受到区域设置的影响,我认为这是合理的 - 使用美国区域设置,我可以看到美国/New_York的EST / EDT,但欧洲/伦敦则没有;对于英国区域设置,我看到欧洲/伦敦的GMT / BST,但美国/New_York :(
有没有办法说服ICU4J回到tz缩写?在我非常具体的情况下,这就是我正在寻找的。
更新
感谢RealSkeptic的评论,它看起来是一种更干净的方式来获取这些数据而无需格式化。这一切听起来都很有希望 - 甚至还有:TimeZoneNames
TimeZoneNames.getTZDBInstance
返回一个时区名称实例,该实例仅包含与 IANA tz 数据库的区域缩写(未本地化)兼容的短特定区域名称 ( 和 )。
TimeZoneNames.NameType.SHORT_STANDARD
TimeZoneNames.NameType.SHORT_DAYLIGHT
这几乎正是我想要的 - 但在大多数情况下,这不会早于1970年,也不包括所有相关数据:
import static com.ibm.icu.text.TimeZoneNames.NameType.SHORT_STANDARD;
import com.ibm.icu.text.TimeZoneNames;
import com.ibm.icu.text.TimeZoneNames.NameType;
import com.ibm.icu.util.ULocale;
public class Test {
public static void main(String[] args) {
TimeZoneNames names = TimeZoneNames.getTZDBInstance(ULocale.ROOT);
long december1969 = -2678400000L;
// 24 hours into the Unix epoch...
long january1970 = 86400000L;
// null
System.out.println(
names.getDisplayName("America/New_York", SHORT_STANDARD, december1969));
// EST
System.out.println(
names.getDisplayName("America/New_York", SHORT_STANDARD, january1970));
// null
System.out.println(
names.getDisplayName("Europe/London", SHORT_STANDARD, december1969));
// null
System.out.println(
names.getDisplayName("Europe/London", NameType.SHORT_STANDARD, january1970));
}
}
鉴于在这一点上几乎没有间接性 - 我告诉ICU4J正是我想要的 - 我的怀疑是这些信息无法获得:(