Java 8日期时间:从ZonedDateTime开始新的一天
这些之间有什么区别:
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]
截断发生在本地时间轴上。如果选择DAYS,则选择午夜。根据javadoc,truncate()
-method最终会转换回新的方法ZonedDateTime
,并将时间向前移动间隔的大小(1小时)。
在这种情况下,首先将zdt转换为LocalDate
(切断时间部分),然后ZonedDateTime
在给定时区中查找其-part实际上是相同的。
但是,对于从夏令时切换回冬季的相反情况,有
(非常感谢@Austin提出了反例)。问题在于重叠过程中何时决定使用哪个偏移量。通常,将类ZonedDateTime
设计/指定为使用先前的偏移量,另请参见Javadoc的以下摘录:
对于“重叠”,一般的策略是,如果本地日期时间落在“重叠”的中间,则将保留以前的偏移量。如果没有先前的偏移量,或者先前的偏移量无效,则使用先前的偏移量,通常是“夏令时”时间。
如果该类ZonedDateTime
因此遵循其自己的规范,则这两个过程仍然是等效的:
zdt.truncatedTo(ChronoUnit.DAYS);
应该等于
zdt.toLocalDate().atStartOfDay().atZone(zdt.getZone()).withEarlierOffsetAtOverlap();
但是根据@Austin的示例并由我在自己的测试中确认的真实行为是:
zdt.toLocalDate().atStartOfDay().atZone(zdt.getZone()).withLaterOffsetAtOverlap();
看起来像是班上一个隐藏的矛盾之处ZonedDateTime
,口语柔和。如果您问我哪种方法更可取,那么我宁愿提倡第二种方法,尽管它要长得多并且需要更多的击键。但是,这样做的最大优势是使其工作更加透明。选择第二种方法的另一个原因是:
它实际上获得本地时间等于一天开始时间的第一个瞬间。否则,在使用第一种方法时,您必须编写:
zdt.truncatedTo(ChronoUnit.DAYS).withEarlierOffsetAtOverlap();
以上是 Java 8日期时间:从ZonedDateTime开始新的一天 的全部内容, 来源链接: utcz.com/qa/405058.html