I am trying to parse strings in the format of "<year> <quarter>" ("2022 1", "2022 2") into java.time.LocalDate objects. The closest related question I could find is this, but there the author also has the month. If I try to use
DateTimeFormatter quarterFormatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy q")
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1).toFormatter();
LocalDate.parse("2022 2", quarterFormatter);
I get the error java.time.format.DateTimeParseException: (...) Unable to obtain LocalDate from TemporalAccessor: {Year=2022, QuarterOfYear=2, DayOfMonth=1}
, which doesn't really make sense to me, since that is all the data required to figure out a calendar date.
What am I doing wrong?
Also, as a related question, the original format is actually without a whitespace between the year and the quarter, but if I try to run
DateTimeFormatter quarterFormatter = new DateTimeFormatterBuilder()
.appendPattern("yyyyq")
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1).toFormatter();
LocalDate.parse("20222", quarterFormatter);
I get java.time.format.DateTimeParseException: Text '20222' could not be parsed at index 0
. That is also confusing, since parsing from other formats seems to work even without separators.
CodePudding user response:
@OleV.V.'s comment contains the right solution of using .parseDefaulting(IsoFields.DAY_OF_QUARTER, 1)
.
CodePudding user response:
Here's a compilation of the information given in the comments:
Why do I get the Unable to obtain LocalDate message? And how to fix it?
That is because the parser does not have all necessary information, as OH GOD SPIDERS already said:
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.
How to fix it, was mentioned by Ole V.V.:
Simply
.parseDefaulting(IsoFields.DAY_OF_QUARTER, 1)
instead of theparseDefaulting
call you have got. You will then get2022-04-01
, the first day of the 2nd quarter.
How do I fix the Text '20222' could not be parsed at index 0 error?
As mentioned by Ole V.V.:
DateTimeFormatter
is not good at separatingyyyy
fields from other fields. For your related question of20222
you may usenew DateTimeFormatterBuilder() .appendValue(ChronoField.YEAR, 4) .appendValue(IsoFields.QUARTER_OF_YEAR, 1) .parseDefaulting(IsoFields.DAY_OF_QUARTER, 1) .toFormatter()
(Formatting mine.)