2066 年?
我怀疑你设定了一个意想不到的时刻,大约 50 年后。
让我们解压缩您的代码。
ZonedDateTime.now( // Represents a moment adjusted into a time zone.
Clock.fixed(
Instant.now() // Get current moment. Actually a count of nanoseconds since 1970-01-01T00:000Z. That is 48 years, about 5 decades worth of nanoseconds.
.plusMillis( // Adding some more milliseconds, for a moment in the future, later than now.
created.toInstant() // Accessing some stored moment. Presumably a contemporary date-time.
.toEpochMilli()) , // Getting the count of milliseconds since 1970-01-01T00:000Z, another 5 decades or so of time.
ZoneId.systemDefault() // Getting the JVM’s current default time zone. To be assigned to our resulting `ZonedDateTime` object.
)
)
因此,您从大约 5 个数十纳秒开始。然后,大概再增加大约 5 个数十毫秒。所以你最终得到了一个未来 50 年的日期,大约 2066 年。这是你打算测试的值吗?
2066 ≈ 2018 + (时间从 1970 年到 2018 年左右的某个时刻)
我们可以试试那个代码,看看结果。
ZonedDateTime created = ZonedDateTime.of( 2018 , 1 , 23 , 12 , 34 , 56, 0 , ZoneId.systemDefault()); // 2018-01-23T12:34:56 in America/Los_Angeles.
ZonedDateTime zdt = ZonedDateTime.now( // Represents a moment adjusted into a time zone.
Clock.fixed(
Instant.now() // Get current moment. Actually a count of nanoseconds since 1970-01-01T00:000Z. That is 48 years, about 5 decades worth of nanoseconds.
.plusMillis( // Adding some more milliseconds, for a moment in the future, later than now.
created.toInstant() // Accessing some stored moment. Presumably a contemporary date-time.
.toEpochMilli()) , // Getting the count of milliseconds since 1970-01-01T00:000Z, another 5 decades or so of time.
ZoneId.systemDefault() // Getting the JVM’s current default time zone. To be assigned to our resulting `ZonedDateTime` object.
)
);
System.out.println("created.toString: " + created );
System.out.println("zdt.toString(): " + zdt );
如果created 是今年早些时候,那果然是 2066 年。
created.toString: 2018-01-23T12:34:56-08:00[America/Los_Angeles]
zdt.toString(): 2066-08-09T08:51:38.488980-07:00[America/Los_Angeles]
Millis vs nanos
请注意,java.time 类(例如 Instant 和 ZonedDateTime)的分辨率为 nanoseconds。这比使用milliseconds 的旧遗留类java.util.Date 和Calendar 要好得多。
编写简单的代码
提示:不要在一行代码中编写太多内容。人类难以破译和调试/跟踪。并且 JVM 可能更难优化。通常,在人和机器上编写极其简单的代码行更容易。
所以,让我们把代码分解成简单的几行。
Instant now = Instant.now(); // Current moment in UTC, with a resolution of nanoseconds.
Duration fiveMinutes = Duration.ofMinutes( 5L ); // `Duration` represents a span-of-time unattached to the timeline.
Instant fiveMinutesFromNow = now.plus( fiveMinutes ); // Returns a `Instant`, using our original `Instant` object plus adding some span-of-time.
Clock clock = Clock.fixed( fiveMinutesFromNow , ZoneId.systemDefault() ); // Instantiate a clock frozen at a specific moment about five minutes in the future. This clock does not “tick”, remaining fixed at this one specified moment.
现在将名为 clock 的 Clock 对象传递给正在测试的代码。
…
ZonedDateTime zdt = ZonedDateTime.now( clock ) ; // Tells a lie. Reports a moment about five minutes in the future as “now”. Good for testing.
…
试试看。
now.toString(): 2018-07-17T19:22:48.670320Z
fiveMinutesFromNow.toString(): 2018-07-17T19:27:48.670320Z
zdt.toString(): 2018-07-17T12:27:48.670320-07:00[America/Los_Angeles]
是的,它奏效了。我们将分钟时间视为27 而不是22,即未来五分钟。
在生产环境中传递Clock。
要在测试工具之外的生产环境中运行相同的代码,请通过默认的 Clock 实现。
Clock clock = Clock.systemDefaultZone() ; // Default `Clock` used implicitly in Java if you do not say otherwise.
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。