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

Time:05-03

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 the parseDefaulting call you have got. You will then get 2022-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 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()

(Formatting mine.)

  • Related