0

I am getting exception while trying to parse a date string to java.util.Date.

Here is what I am doing,

String format = "yyyy-MM-dd hh:mm a";
String strDateTime = "2016-03-04 11:30 am";

SimpleDateFormat sdformat = new SimpleDateFormat(format);
        try {
            Date date = sdformat.parse(strDateTime);
            System.out.println(sdformat.format(date));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

and got this

java.text.ParseException: Unparseable date: "2016-03-04 11:30 am"
    at java.base/java.text.DateFormat.parse(DateFormat.java:396)
    at testing.MainClass.main(MainClass.java:18)

I have done this so many times and pattern looks correct to. may be I am not seeing what I did wrong here I am using Java 8 and my execution environment in eclipse is 8 too. until today this code was working fine.

However if I change date string to a.m. => "2016-03-04 11:30 a.m."
it parses successfully output: 2016-03-04 11:30 a.m.

This behavior is same wit LocalDateTime.

java.time.format.DateTimeParseException: Text '2016-03-04 11:30 am' could not be parsed at index 17
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2050)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1952)
    at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:493)
    at testing.MainClass.main(MainClass.java:27)

All the examples of SimpleDateFormat I have seen on internet just uses "am/pm" and not "a.m./p.m." What could I be doing wrong here. -Thanks

  • Your code runs successfully for me, under Oracle JDK 15.0.1. Javadoc for `SimpleDateFormat` doesn't show dots in 'am' and 'pm' either. Which is to say: I don't know! Which JDK/JVM are you using (i.e., Oracle, OpenJDK, IBM J9, ...)? And, what's your locale? I'm en_US. – Aron Nov 29 '20 at 01:32
  • I use oracle jdk – jaimin kansara Nov 29 '20 at 01:34
  • 1
    I would suspect a locale issue. Does it work if you explicitly specify the US locale? `SimpleDateFormat sdformat = new SimpleDateFormat(format, Locale.US);` – Aron Nov 29 '20 at 01:37
  • if I use Locale then SimpleDateFormat works but LocalDateTime doesnt – jaimin kansara Nov 29 '20 at 01:50
  • Playing with `LocalDateTime`, it seems that the AM/PM markers are case-sensitive, and with `en_US` locale, it works with 'AM' but fails with 'am'. – Aron Nov 29 '20 at 01:59
  • 1
    FYI, both `Date` and `SimpleDateFormat` are terrible date-time classes that were supplanted years ago by the modern *java.time* classes defined in JSR 310. – Basil Bourque Nov 29 '20 at 04:36

1 Answers1

1

I believe this is a locale issue - in the en_US locale your code works successfully. You can print out the AM/PM marker text associated with each locale using a loop like:

for (Locale locale : SimpleDateFormat.getAvailableLocales()) {
    SimpleDateFormat sdformat = new SimpleDateFormat(format, locale);
    String[] amPmStrings = sdformat.getDateFormatSymbols().getAmPmStrings();
    System.out.println("Locale " + locale + ": " + amPmStrings[0] + ", " + amPmStrings[1]);
}

This shows that, e.g., the en_CA locale uses the format you describe:

Locale en_CA: a.m., p.m.

If you want to use 'am' and 'pm' (or 'AM' and 'PM' - it appears to be case-insensitive), you can force the en_US locale when creating the formatter:

SimpleDateFormat sdformat = new SimpleDateFormat(format, Locale.US);
Aron
  • 1,552
  • 1
  • 13
  • 34