小编典典
tl; dr
ZonedDateTime.now( ZoneId.of( "Pacific/Auckland" )) // Current moment in a particular time zone.
.withZoneSameInstant( ZoneId.of( "Asia/Kolkata" )) // Same moment adjusted into another time zone.
细节
java.util.Date类未分配时区†,但是其toString实现令人困惑地应用了JVM的当前默认时区。
避免使用java.util.Date和.Calendar
这是避免与Java捆绑在一起的臭名昭著的java.util.Date,.Calendar和SimpleDateFormat类的众多原因之一。避免他们。而是使用以下任一方法:
Java 8中内置的java.time软件包是受Joda-Time启发的。
Joda-Time
java.time
Java 8和更高版本具有内置的java.time软件包。该软件包的灵感来自Joda-Time。尽管它们有一些相似之处和类名,但它们是不同的。每个都有其他不足的特征。一个显着的区别是java.time避免使用构造函数,而是使用静态实例化方法。这两个框架都由同一个人Stephen Colbourne领导。
在ThreeTen-Backport项目中,许多java.time功能都已反向移植到Java 6和7 。在ThreeTenABP项目中进一步适用于Android 。
就本课题而言,它们以相同的方式工作。指定一个时区,并调用一个now方法以获取当前时刻,然后基于旧的不可变实例创建一个新实例以适应时区。
请注意两个不同的时区类别。一个是命名时区,其中包括夏令时的所有规则和其他此类异常以及与UTC的偏移量,而另一个仅是偏移量。
ZoneId zoneMontréal = ZoneId.of("America/Montreal");
ZonedDateTime nowMontréal = ZonedDateTime.now ( zoneMontréal );
ZoneId zOneTokyo= ZoneId.of("Asia/Tokyo");
ZonedDateTime nowTokyo = nowMontréal.withZoneSameInstant( zoneTokyo );
ZonedDateTime nowUtc = nowMontréal.withZoneSameInstant( ZoneOffset.UTC );
Joda-Time
以下是Joda-Time 2.3中的一些示例代码。在StackOveflow中搜索更多示例和更多讨论。
DateTimeZone timeZOneLondon= DateTimeZone.forID( "Europe/London" );
DateTimeZone timeZOneKolkata= DateTimeZone.forID( "Asia/Kolkata" );
DateTimeZone timeZOneNewYork= DateTimeZone.forID( "America/New_York" );
DateTime nowLOndon= DateTime.now( timeZoneLondon ); // Assign a time zone rather than rely on implicit default time zone.
DateTime nowKolkata = nowLondon.withZone( timeZoneKolkata );
DateTime nowNewYork = nowLondon.withZone( timeZoneNewYork );
DateTime nowUtc = nowLondon.withZone( DateTimeZone.UTC ); // Built-in constant for UTC.
我们在宇宙的时间轴上有四个相同时刻的表示。
†实际上,java.util.Date该类确实在其源代码中隐藏了一个时区。但出于大多数实际目的,该班级忽略了该时区。因此,简而言之,通常说juDate没有分配时区。令人困惑?是。避免使用juDate造成混乱,并使用Joda-Time和/或java.time。
2020-03-02