aconsuegra
aconsuegra

Reputation: 186

Parsing day of month with one digit in Java

I want to parse the string "OCTOBER81984" to a Java LocalDate. I'm using the following code but don't works

LocalDate.parse("OCTOBER81984",
    new DateTimeFormatterBuilder() 
         .parseCaseInsensitive()
         .appendPattern("MMMMdyyyy")
         .toFormatter(Locale.US)
);

The exception is

Exception in thread "main" java.time.format.DateTimeParseException: Text 'OCTOBER81984' could not be parsed at index 12
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    at java.time.LocalDate.parse(LocalDate.java:400)

The pattern used is

MMMM --> Full month name
d    --> Day of month with 1 or 2 digits
yyyy --> Year

I have read the docs twice and my pattern looks fine but really doesn't work.

What am I missing?

Upvotes: 0

Views: 203

Answers (1)

Michael
Michael

Reputation: 44150

The problem is that you have 2 variable-width fields, the day and the year. The parser is not really clever enough to work out that your string doesn't mean 81st October 984 (OCTOBER-81-984).

That's an example where you'd think it might be clever enough to know 81st October is gibberish, but suppose your input were OCTOBER11984. It could easily be October 11 984.

If you can handle the addition of a constraint that says the year must be 4 digits, the parser can then tolerate the fact that the day of the month is not a fixed width.

Try this:

LocalDate.parse("OCTOBER81984", 
    new DateTimeFormatterBuilder()
        .parseCaseInsensitive()
        .appendPattern("MMMM") // or .appendText(ChronoField.MONTH_OF_YEAR)
        .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER)
        .appendValue(ChronoField.YEAR_OF_ERA, 4)
        .toFormatter(Locale.US)
)

Upvotes: 4

Related Questions