java.time
你正在使用已被证明设计不佳、令人困惑和麻烦的旧日期时间类。它们已被 Java 8 及更高版本内置的
java.time 类所取代。由 JSR 310 定义。许多功能已在
ThreeTen-Backport 项目中向 Java 6 和 7 回溯移植,并在
ThreeTenABP 项目 中进一步适配 Android。
如果你有一个 java.util.Date 对象,请将其转换为一个
Instant
对象,即 UTC 时间轴上的一个瞬间,分辨率为纳秒。新方法已添加到旧类中以方便转换。
Instant instant = myJavaUtilDate.toInstant();
或者获取当前时刻。在Java 8中,尽管Instant
类具有纳秒的容量,但当前时刻仅以毫秒分辨率捕获。在Java 9中,取决于计算机硬件时钟能力,当前时刻可以以纳秒分辨率捕获。
Instant instant = Instant.now();
为想要查看挂钟时间的地区应用时区。即使是仅包含日期的值,由于日期在任何给定时刻在世界各地变化,这一点非常重要。新的一天在东方早些时候开始。
我随意选择了新西兰时区进行演示。应用ZoneId
以获取ZonedDateTime
对象。
使用适当的时区名称,而不是媒体中看到的3-4个字母的代码,如IST
或EST
。这些代码没有标准化,甚至不是唯一的。
ZoneId zoneId = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
时区与将文本本地化为人类语言(如马来语)无关。
Locale
处理这个问题,同时定义了用于排序元素或使用句点和逗号等问题的文化规范。
我的示例假设您在指定语言和国家/文化代码方面是正确的。
Locale locale = new Locale( "ms" , "MY" );
java.time.format 包含的类可以在生成代表 java.time 值的字符串时自动进行本地化。
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM );
在定义格式化程序时,请记得指定
Locale
。如果省略,则将隐式应用您JVM的当前默认区域设置。该默认值可以在任何时刻甚至在运行时更改!因此最好始终明确表达。
formatter = formatter.withLocale( locale );
String output = zdt.format( formatter );
2016年5月23日
相比之下,使用Locale.US
时:
2016年5月23日
而使用Locale.CANADA_FRENCH
时:
2016-05-23