在Java 8中设置未来日期 [英] Setting future date in Java 8

查看:135
本文介绍了在Java 8中设置未来日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Joda中我们有setCurrentMillisFixed方法,可用于设置未来日期
在我的测试用例中,我将DateTime(joda)参数传递给
当前系统时间:
创建的DateTime = new DateTime()

DateTimeUtils.setCurrentMillisSystem(created.toInstant()。toEpochMilli()););

In Joda we have setCurrentMillisFixed method which can be used to set future date In one my test cases , i pass a DateTime (joda) parameter to current system time: DateTime created = new DateTime() DateTimeUtils.setCurrentMillisSystem(created.toInstant().toEpochMilli()););

在Java 8中我正在尝试:
我传递ZonedDateTime而不是DateTime,

In Java 8 i am trying : I pass ZonedDateTime instead of DateTime,

我尝试将日期设置如下:

I tried setting the date as below:

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

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

But lot of test cases are failing, i am guessing this has something to do with how the date is being set.

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

Any advice ? Could not find any useful piece of code ,

推荐答案

2066年?



<我怀疑你是在设置一个意想不到的时刻,将来大约50年。

Year 2066?

I suspect you are setting an unintended moment, around 50 years in the future.

让我们解压你的代码。

Let’s unpack your code.

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年的纳秒开始。然后,据推测,你再增加大约50年的毫秒。所以你最终会在未来五十年左右,大约在2066年。这是你打算测试的价值吗?

So you start with about 5 decades of nanoseconds. Then, presumably, you add approximately another 5 decades of milliseconds. So you end up with a date fifty years in the future, around the year 2066. Is that the value you intended to test?


2066 ≈2018+(从1970年到2018年左右经过的时间)

2066 ≈ 2018 + ( time elapsed from 1970 to some moment around 2018 )

我们可以尝试该代码,所以请看结果。

We can try that code, so see the result.

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年,如果创建了今年早些时候。

Sure enough, year 2066, if created is a moment earlier this year.


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

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]

zdt.toString(): 2066-08-09T08:51:38.488980-07:00[America/Los_Angeles]



Millis vs nanos



请注意 java.time 类,例如 Instant ZonedDateTime 的分辨率为纳秒。这比旧的遗产类 java.util.Date &更加精细。 日历使用毫秒

Millis vs nanos

Be aware that the java.time classes such as Instant and ZonedDateTime have a resolution of nanoseconds. That is much finer than the old legacy classes java.util.Date & Calendar which use milliseconds.

提示:不要在一行代码中写这么多。人类难以破译和调试/追踪。并且JVM可能更难以优化。一般来说,编写简单的代码行在人类和机器上都比较容易。

Tip: Don't write so much into one line of code. Hard for humans to decipher and to debug/trace. And may be harder for the JVM to optimize. Writing dead-simple lines of code is easier on both humans and machines, generally.

所以,让我们将代码分解成简单的行。

So, let’s break up that code into simple lines.

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 到你正在测试的代码。

Now pass that Clock object named clock to your code being tested.

…
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

now.toString(): 2018-07-17T19:22:48.670320Z

fiveMinutesFromNow.toString():2018-07- 17T19:27:48.670320Z

fiveMinutesFromNow.toString(): 2018-07-17T19:27:48.670320Z

zdt.toString():2018-07-17T12:27:48.670320-07:00 [America / Los_Angeles]

zdt.toString(): 2018-07-17T12:27:48.670320-07:00[America/Los_Angeles]

是的,它有效。我们将分钟显示为 27 ,而不是 22 ,将来五分钟。

Yes, it worked. We see the minute-of-hour as 27 rather than 22, five minutes in the future.

运行相同的代码在生产中,在测试工具之外,传递默认的时钟实现。

To run that same code in production, outside your test harness, pass the default Clock implementation.

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






关于 java.time



java.time 框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如 java.util.Date 日历 ,& SimpleDateFormat


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time 项目,现已进入维护模式 ,建议迁移到 java.time classes。

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle Tutorial 。并搜索Stack Overflow以获取许多示例和解释。规范是 JSR 310

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

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

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

从哪里获取java.time班?

Where to obtain the java.time classes?


  • Java SE 8 Java SE 9 Java SE 10 ,以及之后


    • 内置。

    • 带有捆绑实现的标准Java API的一部分。

    • Java 9添加了一些小功能和修复。

    • Java SE 8, Java SE 9, Java SE 10, and later
      • Built-in.
      • Part of the standard Java API with a bundled implementation.
      • Java 9 adds some minor features and fixes.
      • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
      • Later versions of Android bundle implementations of the java.time classes.
      • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

      ThreeTen-Extra 项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在这里找到一些有用的课程,例如 Interval YearWeek YearQuarter 更多

      这篇关于在Java 8中设置未来日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆