java.time相当于Joda-Time`withTimeAtStartOfDay`?(获得当天的第一时刻)

Bas*_*que 12 java datetime java-time

Joda-Time库中,DateTime该类提供了withTimeAtStartOfDay获取当天第一时刻的方法.你可能会认为那个时刻是"午夜".第一个时刻通常是时间,00:00:00.000但并非总是如此.

在Java 8及更高版本中找到的java.time包是否具有等效功能?

Ste*_*ner 5

你可以LocalDate这样做:

// or a similar factory method to get the date you want
LocalDateTime startOfDay = LocalDate.now().atStartOfDay();
Run Code Online (Sandbox Code Playgroud)

将此日期与午夜时间相结合,以在此日期开始时创建LocalDateTime.这将返回在此日期开始时的午夜00:00从此日期开始形成的LocalDateTime.

https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html#atStartOfDay--

  • @Jesper请再次查看代码示例.JSR-310(Java-8)不使用公共构造函数,而是使用静态工厂方法. (3认同)

Men*_*ild 5

等效项是在类中使用特殊方法atStartOfDayLocalDate

ZoneId zoneId = ZoneId.of("America/New_York");
ZonedDateTime zdt = LocalDate.now(zoneId).atStartOfDay(zoneId);
Run Code Online (Sandbox Code Playgroud)

另请注意,相当于Joda-Time DateTime的不是LocalDateTime,而是ZonedDateTime。该zoneId参数事项在这里。迁移的具体示例- 有关巴西的夏令时(DST)转换的详细信息,另请参见时区网站

Joda-Time(旧方式)

DateTime dt = 
  new DateTime(2015, 10, 18, 12, 0, DateTimeZone.forID("America/Sao_Paulo"));
dt = dt.withTimeAtStartOfDay();
System.out.println(dt); // 2015-10-18T01:00:00.000-02:00
Run Code Online (Sandbox Code Playgroud)

请注意,此代码甚至会在构造函数调用的第一行中午夜抛出异常。

java.time(新方法)

ZoneId zoneId = ZoneId.of("America/Sao_Paulo");
ZonedDateTime zdt =
  ZonedDateTime.of(2015, 10, 18, 12, 0, 0, 0, zoneId);
zdt = zdt.toLocalDate().atStartOfDay(zoneId);
System.out.println(zdt); // 2015-10-18T01:00-02:00[America/Sao_Paulo]
Run Code Online (Sandbox Code Playgroud)

第二个程序语句的行为与Joda-Time有所不同,因为它不会引发异常,但会静默将本地时间偏移所讨论的间隔大小(此处为一小时)。这意味着,如果您选择午夜,则结果将是相同的(即在1:00)。如果您选择00:30,则结果将为01:30。上面给出的示例选择中午作为输入。

引用ZonedDateTime.of(...)的文档:

在大多数情况下,本地日期时间只有一个有效偏移量。在重叠的情况下,当时钟调回时,有两个有效的偏移量。此方法使用通常对应于“夏季”的更早偏移量。

在间隙的情况下,当时钟向前跳时,没有有效的偏移量。取而代之的是,将本地日期时间调整为晚一些间隔时间。对于典型的一小时夏令时更改,本地日期时间将在一小时后移入通常对应于“夏季”的偏移量中。

由于两个库的差异太大,因此不可能将所有详细信息(例如异常行为和应用的DST转换策略)进行100%的迁移。但这是您的准则:

  • 替换DateTimeZonedDateTime
  • 考虑切换到LocalDate进行中间计算(请参见示例)
  • 使用对时区的显式引用并替换DateTimeZoneZoneId