21
votes

I'm trying to use Java 8's java.time.format.DateTimeFormatter to parse a formatted string into a java.time.LocalTime object. However, I'm running into some problems with parsing some input strings. When my input string has "AM" it parses correctly, but when my string has "PM" it throws an exception. Here's a simple example:

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class FormatterExample {
    private static final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm a");
    public static void main(String[] args) {
        parseDateAndPrint("08:06 AM");
        parseDateAndPrint("08:06 PM");
    }
    public static void parseDateAndPrint(String time) {
        LocalTime localTime = LocalTime.parse((time), timeFormatter);
        System.out.println(localTime.format(timeFormatter));
    }
}

Output:

08:06 AM
Exception in thread "main" java.time.format.DateTimeParseException: Text '08:06 PM' could not be parsed: Conflict found: Field AmPmOfDay 0 differs from AmPmOfDay 1 derived from 08:06
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1919)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1854)
    at java.time.LocalTime.parse(LocalTime.java:441)
    at FormatterExample.parseDateAndPrint(FormatterExample.java:11)
    at FormatterExample.main(FormatterExample.java:8)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.time.DateTimeException: Conflict found: Field AmPmOfDay 0 differs from AmPmOfDay 1 derived from 08:06
    at java.time.format.Parsed.crossCheck(Parsed.java:582)
    at java.time.format.Parsed.crossCheck(Parsed.java:563)
    at java.time.format.Parsed.resolve(Parsed.java:247)
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1954)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1850)
    ... 8 more

So 08:06 AM is parsed correctly, but 08:06 PM throws the DateTimeParseException with the message:

Text '08:06 PM' could not be parsed: Conflict found: Field AmPmOfDay 0 differs from AmPmOfDay 1 derived from 08:06

But this is where I got stuck.. I'm not really sure what that error means exactly, but it is definitely related to the AM/PM part of my input string. I also tried searching for similar errors but I wasn't able to find anything. I have a feeling I'm probably making a simple mistake here with defining my formatter pattern but I'm stuck. Any help would be appreciated!

2

2 Answers

50
votes

You are using the wrong pattern, H is hour-of-day (0-23); you need h.

The error is telling you that H is a 24 hour hour, and 8 is therefore obviously AM. Hence when you tell the parser to use 8 on the 24 hour clock and also tell the parse that it's PM it blows up.

In short, read the documentation.

5
votes

The pattern symbol H stands for 24-hour-clock. So the parser tells you in case of "PM" that "08"-hour can only be in the scope of AM that is the first half of day.

Solution: Use pattern symbol "h" instead (for 12-hour-clock).