java随机时间早上8点到晚上10点,Java 8日期时间:从ZonedDateTime获取一天的开始

Is there any difference between these:

zonedDateTime.truncatedTo(ChronoUnit.DAYS);

zonedDateTime.toLocalDate().atStartOfDay(zonedDateTime.getZone());

Any reason to prefer one against the other?

Thanks

解决方案

Updated for sake of correction:

In most cases yes the same, see following example for Brazil when switching from winter to summer time:

ZonedDateTime zdt =

ZonedDateTime.of(2015, 10, 18, 0, 30, 0, 0,

ZoneId.of("America/Sao_Paulo")); // switch to summer time

ZonedDateTime zdt1 = zdt.truncatedTo(ChronoUnit.DAYS);

ZonedDateTime zdt2 = zdt.toLocalDate().atStartOfDay(zdt.getZone());

System.out.println(zdt); // 2015-10-18T01:30-02:00[America/Sao_Paulo]

System.out.println(zdt1); // 2015-10-18T01:00-02:00[America/Sao_Paulo]

System.out.println(zdt2); // 2015-10-18T01:00-02:00[America/Sao_Paulo]

Truncating happens on the local timeline. If you choose DAYS then you opt for midnight. According to javadoc the truncate()-method finally converts back to the new ZonedDateTime and shifts the time forward by the size of the gap (1 hour).

Converting the zdt first to LocalDate (cutting off the time part) and then looking for its ZonedDateTime-part in given timezone is effectively the same for this situation.

However, for the reverse case of switching back from summer time to winter time there is one exception (thanks very much to @Austin who gave a counter example). The problem is during overlap when to decide which offset to be used. Usually the class ZonedDateTime is designed/specified to use the previous offset, see also this excerpt from Javadoc:

For Overlaps, the general strategy is that if the local date-time

falls in the middle of an Overlap, then the previous offset will be

retained. If there is no previous offset, or the previous offset is

invalid, then the earlier offset is used, typically "summer" time.

If the class ZonedDateTime would consequently follow its own specification then both procedures would still be equivalent meaning:

zdt.truncatedTo(ChronoUnit.DAYS);

should be equivalent to

zdt.toLocalDate().atStartOfDay().atZone(zdt.getZone()).withEarlierOffsetAtOverlap();

But the real behaviour according to the example of @Austin and confirmed by me in own testing is:

zdt.toLocalDate().atStartOfDay().atZone(zdt.getZone()).withLaterOffsetAtOverlap();

Looks like a hidden inconsistency in the class ZonedDateTime, mildly spoken. If you ask me which method to be preferred then I would rather advocate the second method although it is much longer and requires more keystrokes. But it has the big advantage to be more transparent about what it does. Another reason to prefer the second approach is:

It really obtains the FIRST instant at which the local time is equal to the start of day. Otherwise, when using first method, you have to write:

zdt.truncatedTo(ChronoUnit.DAYS).withEarlierOffsetAtOverlap();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值