1

I'm trying to parse a ISO 8601 date to a Date object, but I can't.

I'm trying the following:

        String date = "2021-05-14T09:26:20";
        
        SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss");
        Date newDate = parser.parse(date);
        System.out.println(format.format(newDate));

But I get this error:

Exception in thread "main" java.text.ParseException: Unparseable date: "2021-05-14T09:26:20"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at com.pruebas.pruebas.fechas.main(fechas.java:14)

How can I solve this?

geanakuch
  • 778
  • 7
  • 13
  • 24
  • 3
    Your format has a space in the middle. Your string has a T in the middle. – Michael Jun 11 '21 at 10:28
  • 1
    Does this answer your question? [Converting ISO 8601-compliant String to java.util.Date](https://stackoverflow.com/questions/2201925/converting-iso-8601-compliant-string-to-java-util-date) – Beshambher Chaukhwan Jun 11 '21 at 10:30
  • 1
    @Michael - There is one more problem which I've mentioned in point#2 of my answer. Apart from these two problems, another major problem is using the error-prone legacy API. – Arvind Kumar Avinash Jun 11 '21 at 10:58
  • 1
    The `java.util` Date-Time API and their formatting API, `SimpleDateFormat` are outdated and error-prone. It is recommended to stop using them completely and switch to the [modern Date-Time API](https://www.oracle.com/technical-resources/articles/java/jf14-Date-Time.html). – Arvind Kumar Avinash Jun 11 '21 at 10:59
  • @BeshambherChaukhwan - The duplicate target you have marked this question with is not a correct target. Learn how to mark a question as a duplicate from [this article](https://stackoverflow.blog/2009/04/29/handling-duplicate-questions/) by the founder of StackOverflow. – Arvind Kumar Avinash Jun 11 '21 at 13:30
  • 1
    @ArvindKumarAvinash there could be a perfectly valid reason for why he's using it and it doesn't actually fix his specified issue to use another API. It completely changes what he's doing. It should be a comment not an answer to suggest switching APIs. – Burkely91 Jun 13 '21 at 08:25

2 Answers2

5

Problems with your code:

  1. The pattern for parsing should match with the given date-time string. You have missed 'T' in the pattern for parsing.
  2. Also, you have used M instead of m for "Minute in hour". The symbol, M is used for "Month in year". Read the documentation carefully.

Demo with correct patterns:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Main {
    public static void main(String[] args) throws ParseException {
        String date = "2021-05-14T09:26:20";
        SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date newDate = parser.parse(date);
        System.out.println(format.format(newDate));
    }
}

ONLINE DEMO

Introducing java.time, the modern Date-Time API:

Note that the java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*, released in March 2014 as part of Java SE 8 standard library.

Solution using java.time, the modern Date-Time API:

The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String date = "2021-05-14T09:26:20";
        LocalDateTime ldt = LocalDateTime.parse(date);
        System.out.println(ldt);
        
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
        System.out.println(dtf.format(ldt));
    }
}

Output:

2021-05-14T09:26:20
2023-02-14 09:02:20

ONLINE DEMO

Here, you can use y instead of u but I prefer u to y.

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


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • I would like the output was something like this "2021-05-14 09:26:20", but I cant get this result. –  Jun 11 '21 at 10:30
  • @JuanGracia - I've put the links to the online editor with the code giving the desired result. Feel free to let me know if you have any doubt. – Arvind Kumar Avinash Jun 11 '21 at 10:52
  • @Michael - At least by using `java.time`, the OP would not have encountered the issue in parsing. Don't you think it's worth educating beginners with all these things? – Arvind Kumar Avinash Jun 11 '21 at 11:04
  • @ArvindKumarAvinash I think it's worth starting with "*here's why your specific code doesn't work ... by the way, there is a more modern approach*". – Michael Jun 11 '21 at 11:09
  • 1
    @Michael I do not agree. When the good solution is so different from the asker’s own code, I think it’s better to start with *here’s how to do*. Whether you also want to explain what was wrong is an open question. The risk is we end up helping people use the API that they should not use, which is doing them a serious misfavour (if that’s a word). On the other hand there is also a point in satisfying curiosity. – Ole V.V. Jun 19 '21 at 11:42
0

Though @Arvind gave some good explanations and examples your issue in this particular instance is simply a typo. The string:

String date = "2021-05-14T09:26:20";

includes a T literal to separate the date from the time as per the ISO-8601 standard. You have simply forgotten this in your SimpleDateFormat:

SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss");

You should have this:

SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

And all should work.

Burkely91
  • 902
  • 9
  • 28