当我尝试将 ZonedDateTime
转换为 Timestamp
时一切正常,直到我在以下代码中调用 Timestamp.from()
:
ZonedDateTime currentTimeUTC = ZonedDateTime.now(ZoneOffset.UTC);
currentTimeUTC = currentTimeUTC.minusSeconds(currentTimeUTC.getSecond());
currentTimeUTC = currentTimeUTC.minusNanos(currentTimeUTC.getNano());
return Timestamp.from(currentTimeUTC.toInstant());
ZonedDateTime.now(ZoneOffset.UTC); -> 2018-04-26T12:31Z
currentTimeUTC.toInstant() -> 2018-04-26T12:31:00Z
Timestamp.from(currentTimeUTC.toInstant()) -> 2018-04-26 14:31:00.0
// (with Timezone of Europe/Berlin, which is currently +2)
为什么 Timestamp.from()
不注意即时设置的时区?
最佳答案
Instant
类没有时区,它只有自 unix 纪元以来的秒和纳秒值。 Timestamp
也表示(从纪元开始的计数)。
why is the debugger displaying this with a Z behind it?
问题出在 toString
方法中:
Instant.toString()
将秒和纳秒值转换为相应的 UTC 日期/时间 - 因此最后是“Z” - 我相信这样做是为了方便(使 API 更加“开发人员友好”)。
A string representation of this instant using ISO-8601 representation.
The format used is the same asDateTimeFormatter.ISO_INSTANT
.
如果我们看一下 DateTimeFormatter.ISO_INSTANT
javadoc :
The ISO instant formatter that formats or parses an instant in UTC, such as '2011-12-03T10:15:30Z'
由于调试器通常使用 toString
方法来显示变量值,这解释了为什么您看到 Instant
最后带有“Z”,而不是秒/纳秒值(value)观。
另一方面,Timestamp.toString
使用 JVM 默认时区将秒/纳秒值转换为日期/时间字符串。
但是 Instant
和 Timestamp
的值是一样的。您可以通过调用方法 Instant.toEpochMilli
和 Timestamp.getTime
来检查两者是否会返回相同的值。
注意:您可以使用 truncatedTo
方法代替调用 minusSeconds
和 minusNanos
:
ZonedDateTime currentTimeUTC = ZonedDateTime.now(ZoneOffset.UTC);
currentTimeUTC = currentTimeUTC.truncatedTo(ChronoUnit.MINUTES);
这会将所有小于 ChronoUnit.MINUTES
的字段(在本例中为秒和纳秒)设置为零。
你也可以使用 withSecond(0)
和 withNano(0)
,但在这种情况下,我认为 truncatedTo
更好,更多开门见山。
注意 2:java.time API 的创建者还为 Java 6 和 7 做了一个反向移植,在项目的 github 问题中 you can see a comment关于 Instant.toString
的行为。这个问题的相关部分:
If we were really hard line, the toString of an Instant would simply be the number of seconds from 1970-01-01Z. We chose not to do that, and output a more friendly toString to aid developers
这强化了我的观点,即 toString
方法的设计是为了方便和易于使用。
关于java - Timestamp.from 不注意 Instant 的时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50043107/