当前位置: 首页 > 面试题库 >

Java 8日期时间:从ZonedDateTime开始新的一天

毕霖
2023-03-14
问题内容

这些之间有什么区别:

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();


 类似资料:
  • 问题内容: 从DATETIME中删除 日期 的最佳方法是什么,以便仅剩下 时间 进行比较? 我知道我可以执行以下操作: 但这涉及转换和字符。如果我想检查DATETIME列中是否存储了另外两个时间之间的时间(包括分钟),是否有一种优雅的方法可以执行此操作而不必依赖转换为字符串? 问题答案: 从Essential SQL Server日期,时间和DateTime函数中 尝试使用TimeOnly函数:

  • 也许有人能给我举个例子?我在问自己,新的日期和时间API的改进来自哪里。

  • 何时何地哪个更可取? 我不知道他们之间到底有什么区别。 来自LocalDateTime的文档 ...时间表示为纳秒精度。例如,值“2007 年 10 月 2 日 13:45.30.123456789”可以存储在 LocalDateTime 中。 我假设LocalDateTime也可以接受纳秒。所以我想,我可以用LocalDateTime替换我的代码,它们被声明为TimeStamp。如果我错了,请纠

  • 所以我有: < code >日期开始日期,即< code > EEST 2022年3月27日17时32分01秒 和 ,即 我需要根据这两个值生成一个新日期。我需要将240H周期添加到开始日期。240H意味着我需要添加到开始日期的10天,我最终需要一个新的日期,应该是EEST 2022年4月6日星期三17:32.01。 PS.我是Java的新手,希望我不会问愚蠢的事情。

  • 我需要一些解释为什么这个代码不编译: 错误: 类型Duration中的(TemporalAmount)方法不适用于参数(ChronoUnit) 正如本文所述: public static Duration from(TemporalAmount amount)从时间量中获取持续时间的实例。这将根据指定的金额获得持续时间。TemporalAmount表示一个时间量,可以是基于日期的,也可以是基于时间

  • 问题内容: 如果可能的话,在以下情况下,我希望使用joda或非joda解决方案 假设我的一周从2012年5月2日开始,给定的当前日期为02/22/2011。我需要计算给定当前日期的星期开始和结束日期。因此,我的解决方案的星期应该从02/19开始,而星期在02/25结束。为简单起见,我将我的工作日设置为02/05/2011,但是可能是任何一天,我的工作日始终为7天。 我现有的代码如下,但似乎无法按预