如何使用 java.time 从年份和季度解析日期

How to parse date from year and quarter using java.time

我正在尝试将格式为“ ”(“2022 1”、“2022 2”)的字符串解析为 java.time.LocalDate 个对象。我能找到的最接近的相关问题是 ,但作者也有月份。 如果我尝试使用

DateTimeFormatter quarterFormatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy q")
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1).toFormatter();
LocalDate.parse("2022 2", quarterFormatter);

我收到错误 java.time.format.DateTimeParseException: (...) Unable to obtain LocalDate from TemporalAccessor: {Year=2022, QuarterOfYear=2, DayOfMonth=1} ,这对我来说没有任何意义,因为这是计算日历日期所需的所有数据。 我做错了什么?

此外,作为一个相关问题,原始格式实际上在年份和季度之间没有空格,但是如果我尝试 运行

DateTimeFormatter quarterFormatter = new DateTimeFormatterBuilder()
.appendPattern("yyyyq")
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1).toFormatter();
LocalDate.parse("20222", quarterFormatter);

我得到 java.time.format.DateTimeParseException: Text '20222' could not be parsed at index 0。这也令人困惑,因为即使没有分隔符,从其他格式解析似乎也能正常工作。

@OleV.V.'s 包含使用 .parseDefaulting(IsoFields.DAY_OF_QUARTER, 1).

的正确解决方案

这里是评论中给出的信息的汇编:

为什么我会收到 无法获取 LocalDate 消息?以及如何修复它?

那是因为解析器没有所有必要的信息,正如 OH GOD SPIDERS 已经说过的:

Not really. Year=2022, QuarterOfYear=2, DayOfMonth=1 could be 2022-04-01, or 2022-05-01 or 2022-06-01. A Quarter isn't a specific month.

Ole V.V 提到了如何修复它。:

Simply .parseDefaulting(IsoFields.DAY_OF_QUARTER, 1) instead of the parseDefaulting call you have got. You will then get 2022-04-01, the first day of the 2nd quarter.

如何修复 无法在索引 0 处解析文本“20222”错误?

正如 Ole V.V 所提到的那样:

DateTimeFormatter is not good at separating yyyy fields from other fields. For your related question of 20222 you may use

new DateTimeFormatterBuilder()
    .appendValue(ChronoField.YEAR, 4)
    .appendValue(IsoFields.QUARTER_OF_YEAR, 1)
    .parseDefaulting(IsoFields.DAY_OF_QUARTER, 1)
    .toFormatter()

(格式化我的。)