javajava-timelocaldatedatetimeformatter

LocalDateTime (or any other suitable class) with time as optional paramter


I am trying to parse an incoming string which might contain time or not. Both the following dates should be accepted

"2022-03-03" and "2022-03-03 15:10:05".

The DateTimeFormatter that I know will fail in any one of the cases. This is one answer I got, but I don't know if in any ways time part can be made optional here.

ISO_DATE_TIME.format() to LocalDateTime with optional offset

The idea is if the time part is not present I should set it to the end of the day, so the time part should be 23:59:59.

Any help is appreciated. Thanks!


Solution

  • Well, you could utilize a DateTimeFormatterBuilder to specify defaults for missing fields:

    private static LocalDateTime parse(String str) {
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-MM-dd[ HH:mm:ss]")
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 23)
            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 59)
            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 59)
            .toFormatter();
        return LocalDateTime.parse(str, formatter);
    }
    

    The pattern specifies the pattern it will try to parse. Note that the square brackets ([]) are optional parts. Everything between them will be either completely consumed, or entirely discarded.

    With parseDefaulting you can specify the default values for when fields are missing. In your case, if the user provides only the date, the hour-of-day, minute-of-hour and second-of-minute fields are missing, that's why it is needed to provide defaults for them.


    Example

    System.out.println(parse("2022-03-03"));
    System.out.println(parse("2022-03-03 15:10:05"));
    System.out.println(parse("2025"));
    

    Outputs the following:

    2022-03-03T23:59:59
    2022-03-03T15:10:05
    Exception in thread "main" java.time.format.DateTimeParseException: Text '2025' could not be parsed at index 4