79536639

Date: 2025-03-26 13:58:35
Score: 0.5
Natty:
Report link

DateTimeFormatterBuilder.parseDefaulting()

Perhaps surprising this formatter works for your task:

    private static final DateTimeFormatter formatter
            = new DateTimeFormatterBuilder()
                    .appendPattern("uuuu[-MM[-dd['T'HH[:mm[:ss]]]]]")
                    .parseDefaulting(ChronoField.MONTH_OF_YEAR, 12)
                    .parseDefaulting(ChronoField.DAY_OF_MONTH, 31)
                    .parseDefaulting(ChronoField.HOUR_OF_DAY, 23)
                    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 59)
                    .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 59)
                    .parseDefaulting(ChronoField.NANO_OF_SECOND, 999_999_999)
                    .toFormatter(Locale.ROOT);

I have specified 31 as the day of month to pick when no day of month is in the string. For February 2025, which has 28 days, this gives — 2025-02-28T23:59:59.999999999, so the last day of February. It seems that java.time is smart enough to just pick the last day of the month.

Full demonstration:

    String[] inputs = { "2025", "2025-01", "2025-02", "2025-01-15", "2025-01-15T09", "2025-01-15T09:15" };
    for (String input : inputs) {
        LocalDateTime localDateTime = LocalDateTime.parse(input, formatter);
        System.out.format(Locale.ENGLISH, "%16s -> %s%n", input, localDateTime);
    }

Output:

            2025 -> 2025-12-31T23:59:59.999999999
         2025-01 -> 2025-01-31T23:59:59.999999999
         2025-02 -> 2025-02-28T23:59:59.999999999
      2025-01-15 -> 2025-01-15T23:59:59.999999999
   2025-01-15T09 -> 2025-01-15T09:59:59.999999999
2025-01-15T09:15 -> 2025-01-15T09:15:59.999999999

You said in a comment:

Yeah, but for simplification of the question lets truncate this Dates to the ChronoUnit.SECONDS and without zones :)

So just leave out .parseDefaulting(ChronoField.NANO_OF_SECOND, 999_999_999).

            2025 -> 2025-12-31T23:59:59
         2025-01 -> 2025-01-31T23:59:59
         2025-02 -> 2025-02-28T23:59:59
      2025-01-15 -> 2025-01-15T23:59:59
   2025-01-15T09 -> 2025-01-15T09:59:59
2025-01-15T09:15 -> 2025-01-15T09:15:59
Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • Unregistered user (0.5):
  • Filler text (0.5): 999999999
  • Low reputation (1):
Posted by: Lily Devi