Search code examples
javadatesimpledateformat

How to resolve Unparseable date Exception in Java 8 with Date format yyyy-MM-dd hh:mm a


I have a text file from which I am reading and setting transaction POJO class data, to get the difference between start and end time I need to parse the time information in date object.

DateFormat format = new SimpleDateFormat(dateFormat);
System.out.println("Date format in play:"+dateFormat);
Transaction transaction = storageRepositroy.getTransaction(key);
Date start = format.parse(transaction.getStartDate() + " " + transaction.getStartTime());//line no. 29
Date end = format.parse(transaction.getEndDate() + " " + transaction.getEndTime());

I am getting exception while running this code

Exception is

Date format in play:yyyy-MM-dd hh:mm a
java.text.ParseException: Unparseable date: "2020–03–01 03:15 PM"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at dc.tech.transaction.util.TimeUtil.calculateAverageTime(TimeUtil.java:29)

yyyy-MM-dd hh:mm a is the date format which I am passing to SimleDateFormat constructor. I am unable to understand and debug why I am getting this error.


Solution

  • java.time

    I recommend that you use java.time, the modern Java date and time API, for your date and time work.

        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu\u2013MM\u2013dd");
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
        
        String dateString = "2020–03–01";
        String timeString = "03:15 PM";
        
        LocalDate date = LocalDate.parse(dateString, dateFormatter);
        LocalTime time = LocalTime.parse(timeString, timeFormatter);
        LocalDateTime dateTime = date.atTime(time);
        
        System.out.println(dateTime);
    

    Output:

    2020-03-01T15:15

    With java.time it is straightforward to combine date and time after parsing, so I prefer to parse them individually.

    What went wrong in your code?

    Credits go to Ajeetkumar for noticing and reporting in comments: The hyphen in your date string is not a usual minus sign or hyphen with character value 2D hexadecimal (45 decimal), but a en dash with character value 2013 hexadecimal (8211 decimal). So when you specify a usual hyphen in your format pattern string, they don’t match, and parsing fails. Instead I am using a Unicode escape for putting the en dash into the format pattern string. Simply pasting it in there would have worked too (provided that you save your .java file with a character encoding that supports it), but I wanted to make the reader aware that something special was going on here, so I preferred the Unicode escape with \u.

    There is another problem with your code: You are not providing any locale for your formatter. So it uses the default locale of your JVM. As long as that locale expects PM, parsing will work. If one day you change your locale setting or run your code on a computer or JVM with a different default locale, parsing will suddenly fail, at you may have a hard time figuring out why. I have specified English locale for parsing the time. Some would prefer doing it for the date too even though technically it isn’t necessary.

    Links