7

I just try to parse a simple time! Here is my code:

   String s = "01:19 PM";
        Date time = null;
        DateFormat  parseFormat = new SimpleDateFormat("hh:mm aa");
        try {
            time = parseFormat.parse(s);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

I am getting this exception:

java.text.ParseException: Unparseable date: "01:19 PM"
    at java.text.DateFormat.parse(Unknown Source)
Burkhard
  • 14,596
  • 22
  • 87
  • 108
KostasC
  • 1,076
  • 6
  • 20
  • 40

6 Answers6

5

This works:

  public static void main(String[] args) throws Exception {
   String s = "01:19 PM";
   Date time = null;
   DateFormat parseFormat = new SimpleDateFormat("hh:mm a", Locale.ENGLISH);
   System.out.println(time = parseFormat.parse(s));
  }

ouputs:

  Thu Jan 01 13:19:00 KST 1970
Nicolas Modrzyk
  • 13,961
  • 2
  • 36
  • 40
  • Maybe there is a problem with your Locale ? I have added the field to the SDF constructor. – Nicolas Modrzyk Aug 27 '14 at 10:20
  • 1
    Yes, it's a locale specific problem, see my answer. – icza Aug 27 '14 at 10:22
  • This Answer is **now outdated**, using troublesome old classes that are now legacy, supplanted by the java.time classes. See modern solution in the [correct Answer by Ole V.V.](https://stackoverflow.com/a/45287833/642706). – Basil Bourque Jul 24 '17 at 22:43
5

The pattern letter a is the Am/pm marker, but it is locale specific. Obviously AM and PM are valid in the English locale, but they are not valid in the Hungarian locale for example.

You get ParseException because you have a non-english locale set, and in your locale PM is invalid.

// This is OK, English locale, "PM" is valid in English
Locale.setDefault(Locale.forLanguageTag("en"));
new SimpleDateFormat("hh:mm aa").parse("01:19 PM");

// This will throw Exception, Hungarian locale, "PM" is invalid in Hungarian
Locale.setDefault(Locale.forLanguageTag("hu"));
new SimpleDateFormat("hh:mm aa").parse("01:19 PM");

To get around this problem, the Locale can be specified in the constructor:

// No matter what is the default locale, this will work:
new SimpleDateFormat("hh:mm aa", Locale.US).parse("01:19 PM");
icza
  • 389,944
  • 63
  • 907
  • 827
2

LocalTime

Modern answer using LocalTime class.

LocalTime time = null;
DateTimeFormatter parseFormatter 
    = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
try {
    time = LocalTime.parse(s, parseFormatter);
} catch (DateTimeParseException dtpe) {
    System.out.println(dtpe.getMessage());
}

This turns the string from the question, 01:19 PM, into a LocalTime equal to 13:19.

We still need to provide the locale. Since AM/PM markers are hardly used in practice in other locales than English, I considered Locale.ENGLISH a fairly safe bet. Please substitute your own.

Already when this question was asked in 2014, the modern replacement for the old classes Date and SimpleDateFormat was out, the modern Java date and time API. Today I consider the old classes long outdated and warmly recommend using the modern ones instead. They have generally shown to be remarkably more programmer friendly and convenient to work with.

Just for one simple little thing, if we fail to give a locale on a system with a default locale that doesn’t recognize AM and PM, the modern formatter will give us an exception with the message Text '01:19 PM' could not be parsed at index 6. Index 6 is where it says PM, so we’re already on our way. Yes, I know there is a way to get the index out of the exception thrown by the outdated class, but the majority of programmers were never aware and hence did not use it.

More importantly, the new API offers a class LocalTime that gives us what we want and need here: just the time-of-day without the date. This allows us to model our data much more precisely. There are a number of questions on Stack Overflow caused by confusion in turn caused by the fact that a Date necessarily includes both date and time when sometimes you want only one or the other.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
1

I think that instead of "hh:mm aa" it should be "h:mm a"

Yann
  • 978
  • 2
  • 12
  • 31
0

According to the official documentation you should use this format string: "h:mm a"

But also your format string is correct because I'm getting no errors executing your code.

Alessandro Suglia
  • 1,907
  • 1
  • 16
  • 23
0

Try this format: "K:m a"

Check the docs too: SimpleDateFormat
Also, check your locale, your problem seems to be locale-specific.

peter.petrov
  • 38,363
  • 16
  • 94
  • 159