在Java 8中设置未来日期



在Joda中,我们设置了CurrentMillisFixed方法,可用于设置未来日期在我的一个测试用例中,我将DateTime(joda(参数传递给当前系统时间:DateTime created = new DateTime() DateTimeUtils.setCurrentMillisSystem(created.toInstant().toEpochMilli()););

在Java 8中,我正在尝试:我通过ZonedDateTime而不是DateTime,

我试着将日期设置如下:

ZonedDateTime.now(Clock.fixed(Instant.now().plusMillis(created.toInstant().toEpochMilli()),ZoneId.systemDefault()));

但很多测试用例都失败了,我猜这与日期的设置有关。

有什么建议吗?找不到任何有用的代码,

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.
)
)

所以你从大约50年的纳秒开始。然后,大概再加上大约50毫秒。因此,你最终确定了一个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 );

果不其然,2066年,如果created在今年早些时候的话。

created.toString:2018-01-23T12:34:56-08:00[America/Loss_Angeles]

zdt.toString((:2066-08-09T08:51:38.488980-07:00[美国/洛杉矶]

毫米与纳米

请注意,java.time类(如InstantZonedDateTime(的分辨率为纳秒。这比旧的遗留类java.util.Date&使用毫秒的CCD_ 8。

编写简单代码

提示:不要在一行代码中写太多人类很难破译和调试/跟踪。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.

现在将名为clockClock对象传递给正在测试的代码。

…
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

从现在到字符串的五分钟((:2018-07-17T19:27:48.670320Z

zdt.toString((:2018-07-17T12:27:48.670320-77:00〔美国/洛杉矶〕

是的,它起作用了。我们将小时的分钟视为27,而不是22,即未来的五分钟。

在生产中通过Clock

要在测试工具之外的生产环境中运行相同的代码,请传递默认的Clock实现。

Clock clock =  Clock.systemDefaultZone() ;  // Default `Clock` used implicitly in Java if you do not say otherwise.

关于java.time

java.time框架构建在Java8及更高版本中。这些类取代了诸如java.util.DateCalendar、&SimpleDateFormat

现在处于维护模式的JodaTime项目建议迁移到java.Time类。

要了解更多信息,请参阅Oracle教程。并在Stack Overflow中搜索许多示例和解释。规范是JSR310。

您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,也不需要java.sql.*类。

从哪里获得java.time类?

  • Java SE 8Java SE 9和更高版本
    • 内置
    • 标准Java API的一部分,带有捆绑实现
    • Java 9添加了一些小功能和修复程序
  • Java SE 6Java SE 7
    • 大部分Java.time功能都是向后移植到Java 6&7英寸ThreeTen背包
  • Android
    • java.time类的Android捆绑包的后续版本
    • 对于早期的Android(<26(,ThreeTenABP项目适用于ThreeTen Backport(如上所述(。请参阅如何使用ThreeTenABP…

ThreeTen Extra项目通过附加类扩展java.time。这个项目是将来可能添加到java.time的试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等等。

最新更新