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)
tl;dr
Index 17 is AM/PM of day
Problems:
String
Locale
of the JVM if you don't apply one explicitlyIf 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 Locale
s, but a fix one is less flexible than a formatter that parses case insensitively (IMHO).