为更正而更新:
在大多数情况下是相同的 ,从冬季切换到夏季时,请参见以下巴西示例:
ZonedDateTime zdt = ZonedDateTime.of(2015, 10, 18, 0, 30, 0, 0, ZoneId.of("America/Sao_Paulo")); // switch to summer timeZonedDateTime 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();
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)