0

I have a piece of code written to parse date string -

    DateFormat cal = new SimpleDateFormat("yyyy-MM-dd hh:mm");
    cal.setLenient(false);
    try {
        cal.parse("2018-01-01 14:42");
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

But I get an exception saying -

java.text.ParseException: Unparseable date: "2018-01-01 14:42"
at java.base/java.text.DateFormat.parse(DateFormat.java:388)
at MyClass.main(MyClass.java:10)

I am not sure why I am seeing this error as the date string and the format given is right. Please help

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Prateek Narendra
  • 1,837
  • 5
  • 38
  • 67
  • 6
    use `HH` not `hh` – Youcef LAIDANI Jan 09 '18 at 14:53
  • 2
    @YCF_L - Good eye. I missed it it. – PM 77-1 Jan 09 '18 at 14:53
  • 1
    or maybe just `LocalDateTime.parse("2018-01-01 14:42".replace(' ', 'T'));` – Youcef LAIDANI Jan 09 '18 at 15:00
  • 1
    For your own best, drop `SimpleDateFormat` and friends, they are long outdated and have proven unnecessarily troublesome to work with. java.time, the modern Java date and timme API, is so much nicer. – Ole V.V. Jan 09 '18 at 16:21
  • 1
    Search Stack Overflow before posting. This topic has been addressed many times already. You would have found working code examples to compare to your faulty code. – Basil Bourque Jan 09 '18 at 16:43
  • Related: [Why does parsing '23:00 PM' with SimpleDateFormat(“hh:mm aa”) return 11 a.m.?](https://stackoverflow.com/questions/1154903/why-does-parsing-2300-pm-with-simpledateformathhmm-aa-return-11-a-m) – Ole V.V. Jan 09 '18 at 17:10

4 Answers4

6

From the documentation https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html:

Lowercase h in the SimpleDateFormat indicates hour in the 12 hour format, whereas 24-hour format is indicated with uppercase H. As 14 > 12, the date 14:42 fails to be parsed.

Ondra K.
  • 2,767
  • 4
  • 23
  • 39
3

hh is used for the time of the day with hours going from 1 to 12. 14 is not a valid hour for this kind of hour-representation, so you have to use HH or kk. The former is used for times that are shown from 0-23, the latter for times shown between 1-24. Most likely you have to use HH or H/k if the single digit hours aren't preceded by a 0.

Lothar
  • 5,323
  • 1
  • 11
  • 27
2

You should be using HH instead of hh for hour pattern if the hour is displayed in 24 hour format. See the documentation below for more information.

https://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html

Can
  • 599
  • 4
  • 13
1

TL;DR

    DateTimeFormatter cal = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm");
    LocalDateTime.parse("2018-01-01 14:42", cal);

This runs without exception or other error.

java.time

The date-time classes you use, DateFormat and SimpleDateFormat, are long outdated and furthermore notoriously troublesome. I recommend you stop using them immediately. Instead use java.time, the modern Java date and time API. It came out nearly four years ago after having been described in Java Specification Request (JSR) 310 (a name that somehow still clings to the API).

As others have correctly pointed out, your error was that you used lowercase hh in your format pattern string, where you should have used uppercase HH for hour of day. Just one little example of where the modern classes try to be more helpful, try the same. If I insert hh in the format pattern in the code above, my program crashes (because there is no try-catch construct) with an DateTimeParseException with the following message:

Text '2018-01-01 14:42' could not be parsed: Invalid value for ClockHourOfAmPm (valid values 1 - 12): 14

While perhaps still a bit esoteric, it is very precise. And I would dare hope that in combination with the documentation it would tell you what you did wrong.

The exception is unchecked, so no try-catch is required around the parsing. On the other hand, you may use one if you like (and if you are not very certain that the format of your date-time string is correct, you should).

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161