Search code examples
javaandroiddatesimpledateformatparseexception

java.text.ParseException: Unparseable date for "hh:mm a"


I am struggling converting date from "hh:mm a" into "HH:mm" in android. While I don't get any errors on simple java application, I get an error on android. Here is the code:

String time = "02:00 PM";
String formattedTime = "";
SimpleDateFormat displayFormat = new SimpleDateFormat("HH:mm");
String parseFormats[] = new String[]{"HH:mm", "HHmm", "hh:mm a", "hh a"};

for (String parseFormat : parseFormats) {
    SimpleDateFormat formatting = new SimpleDateFormat(parseFormat);
    try {
        Date date = formatting.parse(time);
        formattedTime = displayFormat.format(date);
        System.out.println(formattedTime);
    } catch (ParseException e) {
        System.out.println(parseFormat);
        e.printStackTrace();
    }
}

in case of Java I get as expected:

02:00
HHmm
java.text.ParseException: Unparseable date: "02:00 PM"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at HelloWorld.main(HelloWorld.java:31)
14:00
hh a
java.text.ParseException: Unparseable date: "02:00 PM"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at HelloWorld.main(HelloWorld.java:31)

in android application the same code returns exception for "hh:mm a" as well:

I/System.out: hh:mm a
W/System.err: java.text.ParseException: Unparseable date: "02:00 PM"

Imports are the same:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

In case of Java app, it succeeds for "HH:mm" and "hh:mm a". In case of Android, it only succeeds for "HH:mm".


Solution

  • Found the problem thanks to @ArnaudDenoyelle. I checked SimpleDateFormat class, turns out 1 valued constructor calls 2 valued with defaul Locale:

    public SimpleDateFormat(String pattern)
        {
            this(pattern, Locale.getDefault(Locale.Category.FORMAT));
        }
    

    AM/PM is seen as an error for my country, as it uses 24 hour system. As my phone and simple java application return different default Locale values, I was getting different results.

    While it is not a solution, I used Locale.France to avoid the problem:

    SimpleDateFormat formatting = new SimpleDateFormat(parseFormat, Locale.FRANCE);