确定夏令时的小时

时间:2016-11-02 13:18:45

标签: java date

可能这个问题被多次询问,但我可能找不到正确的关键字来找到它们。

时间有变化,为30.10。时间回到了凌晨3点(欧洲/柏林)的2点钟。这意味着,在那一天,有两个02:00 o(时间变化前后)

目前,我有两个日期(java.util.Date)对象。其中一个是在第一个02:00 o时钟(在时间被设置之前)创建的,第二个是在第二个02:00 o时钟创建的。

有没有办法区分这些对象是基于它是在第一个或第二个02:00开始创建的?

1 个答案:

答案 0 :(得分:4)

从纪元算起

您的java.util.Date个对象实际 是UTC,但是toString方法在生成字符串输出时会混淆地应用时区。

您可以通过查询epoch的计数来区分两个Date个对象。在内部,日期时间跟踪自UTC 1970年第一时刻以来的毫秒数。调用名称不当的方法java.util.Date::getTime以获得long

UTC

UTC中记录时刻。每个程序员都应该学会用UTC思考,用UTC工作,用UTC登录,并在桌面和屏幕上保留第二个时钟设置为UTC。

UTC是 One True Time 。所有其他只是变化,每个时区都与UTC有所偏差。

让我再一次重复这个首字母缩略词: UTC

Instant

Instant课程是你在这个舞台上的新朋友,也是日常工作的首选课程。它代表UTC时间轴上的一个时刻,分辨率为纳秒。

Instant instant = Instant.now() ;

您不必担心夏令时(DST)切换,政客重新定义夏令时(通常很少注意),也不需要担心任何一个时区特有的其他异常情况。只需使用UTC。

要生成表示此时刻的字符串,请为标准ISO 8601格式的字符串调用toString。此字符串始终为UTC,因此您在生成字符串时不会遇到Date::toString应用时区的问题。标准格式末尾有ZZulu的缩写,表示UTC。

  

instant.toString():
2016-01-23T12:34:56.123456789Z

转换Date

java.util.Date个对象转换为Instant。新的转换方法已添加到旧类中。

Instant instant = myUtilDate.toInstant();

分区

我不关心柏林时间。作为程序员,你不关心柏林时间。您的网络和服务器管理员不关心柏林时间。我们关心UTC。

唯一关心柏林时间的人是最终用户。对于他们,您可以为数据的表示分配时区。

ZoneId z = ZoneId.of( "Europe/Berlin" );
ZonedDateTime zdt = instant.atZone( z );

调用toString生成标准ISO 8601格式的字符串,但通过在方括号中附加时区名称来明智地扩展。

  

2016-07-07T08:00:15.768 + 02:00 [欧洲/柏林]

使用DateTimeFormatter类生成表示其他格式的日期时间值的字符串。

DST有效吗?

您可以询问以确定夏令时(DST)是否对任何特定ZonedDateTime有效。请参阅this Question

ZoneRules rules = zdt.getZone().getRules();
Boolean dstInEffect = rules.isDaylightSavings( zdt.toInstant() );