-2

The value 12/16/2022, 1:33 pm looks to match to expected format pattern M/d/yyyy, h:mm a, what is incorrect at index 17?

Java unit test:

@Test
public void testLocalDateTime_shortDateTimePattern() {
    String pattern = "M/d/yyyy, h:mm a";
    System.out.println(pattern);
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);

    String dateString = "12/16/2022, 1:33 pm";
    System.out.println(dateString);

    LocalDateTime result = LocalDateTime.parse(dateString, formatter);
    System.out.println(result);
}

Console output:

M/d/yyyy, h:mm a
12/16/2022, 1:33 pm

Text '12/16/2022, 1:33 pm' could not be parsed at index 17
java.time.format.DateTimeParseException: Text '12/16/2022, 1:33 pm' could not be parsed at index 17
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
    at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492)
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
bobbyrne01
  • 6,295
  • 19
  • 80
  • 150
  • 2
    are you sure `pm` is the correct spelling for your default `Locale`? (I had no problem with posted code - using `Locale.UK`) – user16320675 Dec 16 '22 at 14:21
  • Is it common to use lower-case AM/PM in UK? That's interesting, I have to check it out soon… – deHaar Dec 16 '22 at 14:32

1 Answers1

3

tl;dr
Index 17 is AM/PM of day
Problems:

  • it's lower case in the String
  • its format and language depend on the Locale of the JVM if you don't apply one explicitly

If you can change the input String, you should make the pm (or am) upper case, otherwise use a DateTimeFormatter that parses case insensitive(ly). You can use a DateTimeFormatterBuilder for that.

In any case add a Locale since AM/PM is not everywhere exactly one of those two abbreviations (on my German JVM it would be nachm., abbreviating nachmittags, which means something like at noon).

Here's an example:

public static void main(String[] args) {
    // define the pattern (your original one should do)
    String pattern = "M/d/yyyy, h:mm a";
    // build a formatter that handles the lower-case AM/PM of day
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                                            .parseCaseInsensitive()
                                            .appendPattern(pattern)
                                            .toFormatter(Locale.ENGLISH);
    // example input / datetime
    String dateString = "12/16/2022, 1:33 pm";
    // parse with the formatter
    LocalDateTime resultB = LocalDateTime.parse(dateString, formatter);
    // print the result
    System.out.println(resultB);
}

Output:

2022-12-16T13:33

Small hint (because I just made that mistake myself):
the call to .parseCaseInsensitive() must come before appending the (relevant part of) the pattern. Otherwise the formatter would only know to parse case insensitively afterwards, which then fails with the same DateTimeParseException.


Update:
Obviously, UK's standard is lower case, so you can use DateTimeFormatter.ofPattern(pattern, Locale.UK), too. There may be more such Locales, but a fix one is less flexible than a formatter that parses case insensitively (IMHO).

deHaar
  • 17,687
  • 10
  • 38
  • 51