我在Instant
和LocalDate
之间转换日期并返回时遇到问题。我需要将当前日期更改为当前星期的星期一(如果是星期三,那么我要更改为星期一):
public static Instant getStartDateAsMonday(Instant startTime) {
LocalDate monday = startTime.atZone(ZoneId.systemDefault()).toLocalDate()
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
startTime = monday.atStartOfDay(ZoneId.systemDefault()).toInstant();
return startTime;
}
我测试时...
@Test
public void testGetStartDateAsMonday() {
Instant instant = DateHelperService.getStartDateAsBeginningOnMonday(
Instant.parse("2020-05-27T00:00:00Z"));
assertThat(instant).isEqualTo("2020-05-25T00:00:00Z");
}
...测试未通过并提供输出:
Expected : 2020-05-25T00:00:00Z
Actual : 2020-05-24T22:00:00Z
我的系统默认时区为GMT + 2。当我执行atStartOfDay(ZoneId.of("UTC"))
时测试通过,但是我不明白为什么我不能在该转换中使用系统默认值。
让我们逐个检查它:
LocalDate monday = startTime // startTime is 2020-05-27 00:00:00 as Instant
// 2020-05-27 02:00:00, but with GMT+2 information as it is a ZonedDateTime now
.atZone(ZoneId.systemDefault())
// (1) 2020-05-27 02:00:00 without zone information
// (2) 2020-05-27 00:00:00 because hour is dropped as it's a LocalDate here
.toLocalDate()
// changed to 2020-05-25 00:00:00, which is what you want
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
startTime = monday // monday is 2020-05-25 00:00:00 as LocalDate
// you say this is at GMT+2 and you want the start of day
// you get a ZonedDateTime 2020-05-25 00:00:00 with information about GMT+2
.atStartOfDay(ZoneId.systemDefault())
// Instant has no zone offset, so this is what the ZonedDateTime needs to remove
// 2020-05-25 00:00:00 becomes 2020-05-24 22:00:00 where the +2 offset is subtracted
.toInstant();
[当您使用ZoneId.of("UTC")
时,则不会发生任何问题,因为ZoneId.of("UTC")
的偏移量为零(为简便起见,忽略了夏令时的内容)。日期时间减去零小时是相同的日期时间。