Alvin Masih
Alvin Masih

Reputation: 33

Can't parse year-month string to LocalDate

I get this error while trying to pass the date 2024-12 in the following code:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM");
LocalDate expiration = LocalDate.parse(exp, formatter);

Error:

java.time.format.DateTimeParseException: Text '2024-12' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {Year=2024, MonthOfYear=12},ISO of type java.time.format.Parsed

I even tried with the format yyyy-MM but I still get the same error

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
LocalDate expiration = LocalDate.parse(exp, formatter);

Upvotes: -1

Views: 125

Answers (1)

Basil Bourque
Basil Bourque

Reputation: 339845

tl;dr

the date 2024-12

No, “2024-12” is not a date. That is a year-with-month. So use java.time.YearMonth.

YearMonth.parse( "2024-12" )

LocalDate

Your input 2024-12 represents a year and a month. In contrast, LocalDate represents a year, a month, and a day. So your input lacks enough information to construct a LocalDate object. You did not provide a day-of-month value.

YearMonth

Java 8+ provides the YearMonth class to represent, well, a year and a month.

YearMonth ym = YearMonth.parse( "2024-12" ) ;

Notice that your input requires no specified formatting pattern. Your input is already in standard ISO 8601 format used by default.

Dates

From that year-with-month object you can determine a date.

LocalDate firstOfMonth = ym.atDay( 1 ) ;
LocalDate lastOfMonth = ym.atEndOfMonth() ;

Get a list of the dates of that month.

SequencedCollection< LocalDate > datesOfMonth = 
    ym.atDay( 1 )              // Start with the first of the month, inclusive.
    .datesUntil(               // Ending is *exclusive* (Half-Open), so we need the first of following month to end up with all the days of the month. 
        ym
            .plusMonths( 1 )   // Next month.
            .atDay( 1 )        // First of next month. 
    )                          // Returns a `Stream` of `LocalDate` objects, one for each day of month.
    .toList() ;                // Collect the objects of that stream into a `List`, which is a sub-interface of `SequencedCollection`. 

Length

And you can get a count of the days in that month.

int days = ym.lengthOfMonth() ;

Upvotes: 7

Related Questions