0

I have a date as string as below

String test Date = "1/31/2020";

I am using the below code

public static String getPeriodMonth(String periodEndDate) {
        LocalDate localDate;
        YearMonth yearMonth = null;
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
            localDate = LocalDate.parse(periodEndDate, formatter);
            yearMonth = YearMonth.from(localDate);
        }catch (Exception e) {
             LOGGER.error("Error: "+ e.getMessage() + ">>" +   e.getCause());
        }
        return yearMonth.toString();

    }

I am getting the below Exception when excuting this code:

Error: Text '1/31/2020' could not be parsed at index 0>>null

Can someone help me what I am doing wrong here?

M. Justin
  • 14,487
  • 7
  • 91
  • 130
PV_PN
  • 103
  • 2
  • 7
  • Does this answer your question? [How to parse a 1 or 2 digit hour string with Java?](https://stackoverflow.com/questions/61820460/how-to-parse-a-1-or-2-digit-hour-string-with-java) – Ole V.V. Jul 01 '20 at 06:39
  • Incidentally, it looks like you can parse directly into the `YearMonth` without first parsing into the `LocalDate`: `yearMonth = YearMonth.parse(periodEndDate, formatter);` – M. Justin Sep 26 '20 at 21:47

2 Answers2

3

You should pass 01/31/2020or update the format to M/dd/yyyy

DateTimeFormatter documentation

The month is considered as a number and in the documentation :

Number: If the count of letters is one, then the value is output using the minimum number of digits and without padding. Otherwise, the count of digits is used as the width of the output field, with the value zero-padded as necessary.

Airy
  • 748
  • 2
  • 10
  • 27
2

The error is due to the format string being used. "MM" requires the month portion of the input string to be exactly two digits long, but "1" is only one digit. In other words, "MM/dd/yyyy" works for "01/31/2020", but not for "1/31/2020".

What's needed here instead of "MM" is "M", which doesn't require the value to be preceded by "0":

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/dd/yyyy");

If the date portion should also be allowed to be a single digit and not be 0-padded for days 0-9, the "M/d/yyyy" pattern should be used instead.

This is described the DateTimeFormatter Javadocs:

All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters. The following pattern letters are defined:

Symbol  Meaning                     Presentation      Examples
------  -------                     ------------      -------
[...]
 M/L     month-of-year               number/text       7; 07; Jul; July; J
[...]

Text: [...]

Number: If the count of letters is one, then the value is output using the minimum number of digits and without padding. Otherwise, the count of digits is used as the width of the output field, with the value zero-padded as necessary. [...]

Number/Text: If the count of pattern letters is 3 or greater, use the Text rules above. Otherwise use the Number rules above.

Since "M" uses the "number/text" presentation, and the count of its letters in the "MM/dd/yyyy" format is 2 ("MM"), it requires exactly two digits for the month. Switching the format to a single "M" causes it to use the minimum number of digits (one digit for months 1-9, and two digits for months 10-12).

M. Justin
  • 14,487
  • 7
  • 91
  • 130