可能这个问题被多次询问,但我可能找不到正确的关键字来找到它们。
时间有变化,为30.10。时间回到了凌晨3点(欧洲/柏林)的2点钟。这意味着,在那一天,有两个02:00 o(时间变化前后)
目前,我有两个日期(java.util.Date)对象。其中一个是在第一个02:00 o时钟(在时间被设置之前)创建的,第二个是在第二个02:00 o时钟创建的。
有没有办法区分这些对象是基于它是在第一个或第二个02:00开始创建的?
答案 0 :(得分:4)
您的java.util.Date
个对象实际 是UTC,但是toString
方法在生成字符串输出时会混淆地应用时区。
您可以通过查询epoch的计数来区分两个Date
个对象。在内部,日期时间跟踪自UTC 1970年第一时刻以来的毫秒数。调用名称不当的方法java.util.Date::getTime
以获得long
。
在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
应用时区的问题。标准格式末尾有Z
,Zulu
的缩写,表示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)是否对任何特定ZonedDateTime
有效。请参阅this Question。
ZoneRules rules = zdt.getZone().getRules();
Boolean dstInEffect = rules.isDaylightSavings( zdt.toInstant() );