Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java8日期时间:从ZoneDateTime开始一天_Java_Datetime_Java 8_Java Time - Fatal编程技术网

Java8日期时间:从ZoneDateTime开始一天

Java8日期时间:从ZoneDateTime开始一天,java,datetime,java-8,java-time,Java,Datetime,Java 8,Java Time,这两者之间有什么区别吗 zonedDateTime.truncatedTo(ChronoUnit.DAYS); zonedDateTime.toLocalDate().atStartOfDay(zonedDateTime.getZone()); 有什么理由选择一个而不是另一个 谢谢为了更正而更新: 在大多数情况下是相同的,从冬季切换到夏季时,请参见以下巴西示例: ZonedDateTime zdt = ZonedDateTime.of(2015, 10, 18, 0, 30, 0, 0

这两者之间有什么区别吗

zonedDateTime.truncatedTo(ChronoUnit.DAYS);

zonedDateTime.toLocalDate().atStartOfDay(zonedDateTime.getZone());
有什么理由选择一个而不是另一个


谢谢

为了更正而更新:

在大多数情况下是相同的,从冬季切换到夏季时,请参见以下巴西示例:

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]
截断发生在本地时间线上。如果你选择白天,那么你选择午夜。根据
truncate()
-方法最终转换回新的
ZoneDateTime
,并将时间向前移动间隙的大小(1小时)

首先将zdt转换为
LocalDate
(切断时间部分),然后在给定时区中查找其
ZonedDateTime
-部分,在这种情况下实际上是相同的

然而,对于从夏季时间切换回冬季时间的相反情况,有一个例外(非常感谢@Austin给出了一个反例)。问题是在重叠期间,何时决定使用哪个偏移。通常,类
ZoneDateTime
设计/指定为使用上一个偏移量,另请参见以下摘录:

对于重叠,一般策略是如果本地日期时间 在重叠的中间落下,那么前面的偏移将是 保留。如果没有上一个偏移,或上一个偏移为 无效,则使用较早的偏移量,通常为“夏季”时间

如果类
ZonedDateTime
因此遵循其自身的规范,则这两个过程仍然具有同等意义:

zdt.truncatedTo(ChronoUnit.DAYS);
应该相当于

zdt.toLocalDate().atStartOfDay().atZone(zdt.getZone()).withEarlierOffsetAtOverlap();
但根据@Austin的例子,我在自己的测试中确认的真实行为是:

zdt.toLocalDate().atStartOfDay().atZone(zdt.getZone()).withLaterOffsetAtOverlap();
看起来类
ZoneDateTime
中隐藏的不一致,说话温和。如果你问我更喜欢哪种方法,那么我宁愿提倡第二种方法,尽管它要长得多,需要更多的击键。但它有一个很大的优势,那就是对它所做的事情更加透明。选择第二种方法的另一个原因是:

它确实获得了第一个本地时间等于一天开始的时刻。否则,在使用第一种方法时,您必须编写:

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

它们略有不同。根据javadocs的说法,在发生重叠的情况下,将试图保留时区,但会发现第一个发生在午夜

例如,古巴在凌晨1点恢复夏令时,降回到凌晨12点。如果从该转换之后的某个时间开始,
atStartOfDay()
将返回第一次出现的12am,而
truncatedTo()
将返回第二次出现的时间

ZonedDateTime zdt = ZonedDateTime.of(2016, 11, 6, 2, 0, 0, 0, ZoneId.of("America/Havana"));
ZonedDateTime zdt1 = zdt.truncatedTo(ChronoUnit.DAYS);
ZonedDateTime zdt2 = zdt.toLocalDate().atStartOfDay(zdt.getZone());

System.out.println(zdt);  // 2016-11-06T02:00-05:00[America/Havana]
System.out.println(zdt1); // 2016-11-06T00:00-05:00[America/Havana]
System.out.println(zdt2); // 2016-11-06T00:00-04:00[America/Havana]

注意,还有另一种方法:

zonedDateTime.with(LocalTime.MIN);

这会产生与截断到

相同的结果,难道他们不能将方法
atStartOfDay()
放在
ZonedDataTime
类中吗?这并不总是正确的!“为什么不看我的答案呢?”奥斯汀你的答案似乎有道理。我会调查并据此更正我的答案。你是说第二种方法<代码>zdt.toLocalDate().atStartOfDay().atZone(zdt.getZone())。带有早期偏移量verlap()@Dr.jacky是的,你已经理解了第二种方法的含义。@MenoHochschild好吧,我已经遵循了这一点:。你认为这可能有问题吗?非常感谢你找到了一个反例。我已经向你投了赞成票,也更新了我的答案。如果夏季时间(DST)从午夜开始,即一天从01:00开始,情况会如何?在任何情况下,代码都不会表达这种情况下的期望行为。它将按照其应有的行为-即在该时区(即适当的DST时区)产生午夜00:00,例如2018-01-27T00:00+11:00【澳大利亚/悉尼】vs 2018-06-27T00:00+10:00【澳大利亚/悉尼】您将从所有3种方法中得到相同的结果-原始问题中的2种方法和这个较短的版本-实际上,为了澄清,这个方法产生的结果与角落案例的ChronoUnit.DAYS版本相同