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

回到顶部