java - Timestamp.from 不注意 Instant 的时区

标签 java timestamp java-time zoneddatetime java.time.instant

当我尝试将 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 更加“开发人员友好”)。

The javadoc for toString说:

A string representation of this instant using ISO-8601 representation.
The format used is the same as DateTimeFormatter.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 默认时区将秒/纳秒值转换为日期/时间字符串。

但是 InstantTimestamp 的值是一样的。您可以通过调用方法 Instant.toEpochMilliTimestamp.getTime 来检查两者是否会返回相同的值。


注意:您可以使用 truncatedTo 方法代替调用 minusSecondsminusNanos:

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/

相关文章:

java - 设置表格宽度

java - 将从数据库检索到的数据分配给字符串变量

mysql - 一个具有多个 TIMESTAMP 列的 Mysql 表

java - 在日期/时间调用方法

Java 8 - ZonedDateTime 的 DateTimeFormatter 和 ISO_INSTANT 问题

java - parseLong 方法在 Java 中如何工作?

java - Hibernate @OneToOne 与多个对象的关系?

Mysql错误代码: 1067 two timestamp column

python - 使用Python将时间戳列从列表插入MYSQL

java - 在 JavaFX 的 DatePicker 中设置一周的第一天