Search code examples
javalocaldate

Use DateTimeFormatterBuilder for parsing dates of missing day and default to end of month


I need to parse dates in various formats. Some of these are missing the "day". Now I want to default to end of month. I am not sure if there is a direct way where we can default to end of month

DateTimeFormatter f = new DateTimeFormatterBuilder()
        .appendPattern("MM.yyyy")
        .parseDefaulting(DAY_OF_MONTH, 1) // can we default to end of month?
        .toFormatter();

LocalDate.parse("11.2017", f)

But if not, how can I know that the original date was missing the day (or that a default was used) and therefore I need to adjust it manually by using LocalDate.parse("11.2017", f).with(TemporalAdjusters.lastDayOfMonth()).


Solution

  • DateTimeFormatter f = new DateTimeFormatterBuilder()
          .appendPattern("MM.yyyy")
          .parseDefaulting(DAY_OF_MONTH, 31) // set 31
          .toFormatter();
    

    Just set DAY_OF_MONTH with 31, DAY_OF_MONTH will base on rangeUnit to choose the last day of parse month.

    /**
     * The day-of-month.
     * <p>
     * This represents the concept of the day within the month.
     * In the default ISO calendar system, this has values from 1 to 31 in most months.
     * April, June, September, November have days from 1 to 30, while February has days
     * from 1 to 28, or 29 in a leap year.
     * <p>
     * Non-ISO calendar systems should implement this field using the most recognized
     * day-of-month values for users of the calendar system.
     * Normally, this is a count of days from 1 to the length of the month.
     */
    DAY_OF_MONTH("DayOfMonth", DAYS, MONTHS, ValueRange.of(1, 28, 31), "day"),
    

    Example:

    LocalDate parse = LocalDate.parse("02.2017", f);
    System.out.println(parse.getDayOfMonth());
    

    Output:

    28