Denis Makovsky
Denis Makovsky

Reputation: 490

Simple date format. Date parsing

I try to parse date like: Tue, 08 Sep 2015 12:32:55 +0300 and appy next pattern:SimpleDateFormat inputFormat = new SimpleDateFormat("EEE, d MMM yyyy hh:mm:ss zzzz"); But I catch exception java.text.ParseException: Unparseable date: "Sun, 13 Sep 2015 17:25:26 +0300" (at offset 0)

Upvotes: 4

Views: 203

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 78975

Major problems in your code

There are two major problems in your code:

  1. You have used h, which is used for hour in am/pm (1-12) and makes sense only with the symbol a, which is used for the am/pm marker. Since you do not have an am/pm marker in your date-time string, you need to use H, which is used for hour-of-day (0-23).
  2. You have missed a crucial thing, Locale while parsing the date-time string. Therefore, even if you correct the above problem, your code will work merely by coincidence - only when the JVM on which you execute your code, has an English Locale set. Check Always specify a Locale with a date-time formatter for custom formats to learn more about it.

There is another problem with your pattern but SimpleDateFormat, known for being error-prone, often silently parses strings with incorrect patterns giving undesired results. You have used zzzz but if you check the SimpleDateFormat documentation, you will realise that you should have used either Z or XX. If you had used zzzz with java.time, the modern date-time API, it would have thrown an exception prompting you to correct your pattern.

java.time

In March 2014, Java 8 introduced the modern, java.time date-time API which supplanted the error-prone legacy java.util date-time API. The new code should use the java.time API*.

Solution using modern date-time API

Your date-time string has a time zone offset of +0300. So, parse your date-time string into an OffsetDateTime.

As suggested by Annonymous, it is best to use the built-in formatter DateTimeFormatter.RFC_1123_DATE_TIME in this case. Alternatively, you can use DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH) or DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss XX", Locale.ENGLISH).

Demo:

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odt = OffsetDateTime.parse("Sun, 13 Sep 2015 17:25:26 +0300", DateTimeFormatter.RFC_1123_DATE_TIME);
        
        // or
        // DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss XX", Locale.ENGLISH);
        // OffsetDateTime odt = OffsetDateTime.parse("Sun, 13 Sep 2015 17:25:26 +0300", dtf);
        
        // or
        // DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
        // OffsetDateTime odt = OffsetDateTime.parse("Sun, 13 Sep 2015 17:25:26 +0300", dtf);

        System.out.println(odt);        
    }
}

Output:

2015-09-13T17:25:26+03:00

Online Demo

Note: For whatever reason, if you need an instance of java.util.Date from this object of OffsetDateTime, you can do so as follows:

java.util.Date date = Date.from(odt.toInstant());

Learn more about the modern date-time API from Trail: Date Time.


* If you are receiving an instance of java.util.Date, convert it tojava.time.Instant, using Date#toInstant and derive other date-time classes of java.time from it as per your requirement.

Upvotes: 2

Derek Fung
Derek Fung

Reputation: 8211

Try changing the code to

SimpleDateFormat inputFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss zzzz", Locale.US);

Edit:

Additional amendment I have changed hh in your code to HH for 24 hours format

Upvotes: 3

Related Questions