首页 > 解决方案 > 带有即时 API 的 Java8 日期和时间

问题描述

我从我的请求中得到动态日期,

Instant duration = request.getStartDate();   // my input is 2020-03-01T00:00:01Z
for (int i = 0; i < 12; i++) {
  duration  = duration.with(TemporalAdjusters.firstDayOfNextMonth ());
}

基本上我想在每个月的第一天获得 12 个月,我尝试使用上面的代码但得到异常,

java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: DayOfMonth

我的输出可能是,

2020-04-01T00:00:01Z
2020-05-01T00:00:01Z
2020-06-01T00:00:01Z
:
:
2021-03-01T00:00:01Z

这里有什么遗漏吗?尝试使用plus()

duration.plus(30, ChronoUnit.DAYS);

我尝试将 Instant 转换为 locateDate,然后它打印得很好,但是对于我所需的格式,我需要从 localdate 转换为 Instant。我没有看到下个月的第一天。


2019-03-31T22:00:00Z
2019-04-30T22:00:00Z
2019-05-31T22:00:00Z
2019-06-30T22:00:00Z
2019-07-31T22:00:00Z
2019-08-31T22:00:00Z
2019-09-30T22:00:00Z
2019-10-31T23:00:00Z
2019-11-30T23:00:00Z
2019-12-31T23:00:00Z

任何建议表示赞赏。谢谢!

标签: datetimejava-8java-time

解决方案


比我的同名答案要简单得多:只要您转换为预先设置OffsetDateTime,使用您最初尝试使用的漂亮的人类可读调节器就没有问题。

OffsetDateTime duration = Instant.now().atOffset(ZoneOffset.UTC);
for (int i = 0; i < 12; i++) {
    duration = duration.with(TemporalAdjusters.firstDayOfNextMonth());
}

问题是 anInstant是一个明确的时间点,与任何特定的时区或地理位置无关。没有与瞬间相关的特定日期;一个地方的星期一是 1 日可能是另一个地方的 31 日星期日,但它仍然是同一时刻。这就是为什么在尝试设置每月的第一天时,您会遇到异常。

如果您转换为OffsetDateTime,则您正在应用偏移量(在本例中为 UTC,因此偏移量为零)。这会将您的数据转换为日期明确的格式。


推荐阅读