确定夏令时的时间

Ad *_*tum 1 java date

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

时间更改为 30.10。03:00 将时间调回 2 点(欧洲/柏林)。也就是说,当天有两个02:00点(时间变更前后)

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

有没有办法根据这些对象是在第一个还是第二个 02:00 创建的来区分这些对象?

Bas*_*que 5

从纪元开始计数

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

您可以通过询问epochDate的计数来区分两个对象。在内部,日期时间以自 UTC 1970 年第一时刻以来的毫秒数进行跟踪。调用名称错误的方法 来获取.java.util.Date::getTimelong

世界标准时间

以UTC时间记录时刻。每个程序员都应该学会用 UTC 思考、用 UTC 工作、用 UTC 登录,并在办公桌上放置第二个时钟并将屏幕设置为 UTC。

UTC 是唯一真实时间。所有其他时间都只是变化,每个时区都与 UTC 存在偏差。

为了清楚起见,让我再重复一次缩写词:UTC

Instant

Instant班级是您在这个舞台上最好的新朋友,是您约会时的首选班级。它代表 UTC 时间线上的一个时刻,分辨率为纳秒。

Instant instant = Instant.now() ;
Run Code Online (Sandbox Code Playgroud)

您无需担心夏令时 (DST) 的切换、政治家重新定义 DST(通常不会引起注意),也不必担心任何一个时区特有的其他异常情况。只需使用 UTC。

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

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

转换Date

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

Instant instant = myUtilDate.toInstant();
Run Code Online (Sandbox Code Playgroud)

分区

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

唯一关心柏林时间的人是最终用户。对于他们,您可以指定一个时区来呈现数据。

ZoneId z = ZoneId.of( "Europe/Berlin" );
ZonedDateTime zdt = instant.atZone( z );
Run Code Online (Sandbox Code Playgroud)

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

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

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

夏令时生效了吗?

您可以询问以确定夏令时 (DST) 是否对任何特定的有效ZonedDateTime。看到这个问题

ZoneRules rules = zdt.getZone().getRules();
Boolean dstInEffect = rules.isDaylightSavings( zdt.toInstant() );
Run Code Online (Sandbox Code Playgroud)