在Java 8中设置将来的日期

时间:2018-07-17 17:55:01

标签: java-8 zoneddatetime

在Joda中,我们有setCurrentMillisFixed方法,该方法可用于设置将来的日期 在我的测试用例中,我将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()));

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

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

1 个答案:

答案 0 :(得分:2)

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]

米利斯vs纳米

请注意,诸如InstantZonedDateTime之类的 java.time 类的分辨率为nanoseconds。这比使用milliseconds的旧式旧类java.util.DateCalendar更好。

编写简单代码

提示:不要在一行代码中写太多。人们很难解密和调试/跟踪。对于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的{​​{3}}对象传递给正在测试的代码。

…
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

Clock框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧java.time日期时间类,例如legacyjava.util.DateCalendar

目前位于SimpleDateFormatJoda-Time项目建议迁移到maintenance mode类。

要了解更多信息,请参见java.time。并在Stack Overflow中搜索许多示例和说明。规格为Oracle Tutorial

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

在哪里获取java.time类?

How to use ThreeTenABP…项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如ThreeTen-ExtraIntervalYearWeekYearQuarter