0

I am trying to convert these two strings to date and I am getting exception unparseable date.

"2015-12-03T15:00:08.868987" and "2015-12-03T17:00:08Z".Tried these two formats "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" and "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

    String s = "2015-12-03T17:00:08Z";
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    try
    {
        Date date = simpleDateFormat.parse(s);

        System.out.println("date : "+simpleDateFormat.format(date));
    }
    catch (ParseException ex)
    {
        System.out.println("Exception "+ex);
    }
mohanaki
  • 260
  • 2
  • 6
  • 15
  • You are trying to parse a date without milliseconds and with a ISO-8601 time zone, using a format that requires milliseconds and a RFC 822 time zone. Please refer to the [Documentation](http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html#SimpleDateFormat%28%29). – RealSkeptic Dec 03 '15 at 16:32
  • 1
    Slightly off topic but you may want to look at Joda-Time, it removes a lot of the frustrations associated with the core Java Date/Time classes – Lawrence Tierney Dec 03 '15 at 16:59
  • @LawrenceTierney The [Joda-Time](http://www.joda.org/joda-time/) library has been succeeded by the new java.time framework built into Java 8 and later. See [my Answer](http://stackoverflow.com/a/34079900/642706) for discussion and examples of java.time code. If Java 8 technology is not available such as Android, then certainly Joda-Time is recommended as far superior to the old date-time classes bundled with early Java. – Basil Bourque Dec 04 '15 at 02:29
  • @BasilBourque thanks. I _thought_ it had changed then convinced myself otherwise #longDay – Lawrence Tierney Dec 04 '15 at 08:39

5 Answers5

10

Reason is you are using wrong format,here Z represents timezone

 String s = "2013-09-29T18:46:19-0700";
 SimpleDateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

If time format is in above ,it will work fine. If you just mark Z in single quotes,it will just consider as a String rather than parsing it.

Edit:- If you want to use "2015-12-03T15:00:08.8689870",then pattern must be yyyy-MM-dd'T'HH:mm:ss.SSS

String s = "2015-12-03T15:00:08.8689870";
SimpleDateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");

If date time is in 2015-12-03T17:00:08Z,then you can use pattern yyyy-MM-dd'T'HH:mm:ssX where X denotes ISO 8601 time zone.The Java 7 version of SimpleDateFormat supports ISO-8601 time zones using the uppercase letter X.

String s = "2015-12-03T17:00:08Z";
SimpleDateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date dtIn = inFormat.parse(s); 

http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

If you're stuck with Java 6 or earlier, the answer recommending JodaTime is a safe bet.

String timestamp = "2011-04-15T20:08:18Z";

DateTime dateTime = ISODateTimeFormat.dateTimeParser().parseDateTime(timestamp);

This correctly recognizes the UTC timezone and allows you to then use Joda Time's extensive manipulation methods to get what you want out of it.

Naruto
  • 4,221
  • 1
  • 21
  • 32
  • @RealSkeptic Thats what i have explained in my answer.That Z here denotes time zone,like GMT,etc.. So to use it,String must be in proper format.... – Naruto Dec 03 '15 at 16:44
  • @RealSkeptic its not necessary UTC,it can be any time zone ,either PDT,UTC,GMT,etc... String s = "2001.07.04 AD at 12:08:56 PDT"; SimpleDateFormat inFormat = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss Z"); – Naruto Dec 03 '15 at 16:53
  • @RealSkeptic Updated the answer...There are two ways by which this can be acheived..Please refer answer – Naruto Dec 03 '15 at 17:09
  • Please mark the answer as "ACCEPTED", if problem is solved.In this way, it will help others looking for similar problem.Thanks – Naruto Dec 03 '15 at 17:20
1
    String s = "2015/12/03/17:00:34";
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd/HH:mm:ss");
    try
    {
        Date date = simpleDateFormat.parse(s);

        System.out.println("date : "+simpleDateFormat.format(date));
    }
    catch (ParseException ex)
    {
        System.out.println("Exception "+ex);
    }

Modify you String date same as the SimpleDateFormat.

0

Change

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

to

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
RealSkeptic
  • 33,993
  • 7
  • 53
  • 79
  • No, because the `Z` has meaning in that date string. Adding a literal `'Z'` to the format string ignores that meaning (that is, that the date is in UTC, not a local date). – RealSkeptic Dec 03 '15 at 16:39
0

The Pojava DateTime library (in Maven Central Repo) would parse both dates without needing to specify formats.

Date d1 = DateTime.parse("2015-12-03T15:00:08.868987").toDate();
Date d2 = DateTime.parse("2015-12-03T17:00:08Z").toDate();
System.out.println(d1); // Thu Dec 03 15:00:08 PST 2015
System.out.println(d2); // Thu Dec 03 09:00:08 PST 2015
phatfingers
  • 9,770
  • 3
  • 30
  • 44
0

Loss of Data

You are parsing a string input with six digits of fractional second, which means microsecond.

You are using the old java.sql.Date class which supports only milliseconds (3 digits). So even if you manage to parse that input, you will be losing some information.

java.time

The classes you are using, java.util.Date & java.text.SimpleDateFormat, have been supplanted by the new java.time framework built into Java 8 and later.

The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.

The java.time classes support nanosecond resolution, up to 9 digits of fractional second. So no loss of data given your inputs.

ISO 8601

Both of your String inputs are in the formats defined by the ISO 8601 standard.

The java.time classes use ISO 8601 by default when parsing or generating String representations of date-time values. So we can specify one of the predefined formatter rather than define a formatter pattern. For some formats we need not even bother specifying a formatter at all.

Example Code

You have two input strings, so two examples.

Example 1

The first string has no time zone or offset-from-UTC info. So we must specify a time by which to interpret the meaning of that input. I assume your intention was for UTC. We specify UTC as the time zone by calling withZone.

That time zone is also assigned as the time zone of the ZonedDateTime object. In other words, no further time zone adjustment is made.

String input = "2015-12-03T15:00:08.868987";

DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone ( ZoneOffset.UTC );
ZonedDateTime zdt = ZonedDateTime.parse ( input , formatter );

zdt: 2015-12-03T15:00:08.868987Z

Example 2

Your second string does contain time zone information, in the form of a Z which stands for Zulu and means UTC.

The java.time framework offers the Instant class to represent a moment on the timeline in UTC. You can think of a ZonedDateTime as being an Instant plus a time zone (ZoneId).

Because this second string is (a) in UTC time zone, and (b) in ISO 8601 format, we need not specify any formatter. The Instant class can directly parse such a String.

String input = "2015-12-03T17:00:08Z";
Instant instant = Instant.parse ( input );

Dump to console.

System.out.println ( "instant: " + instant );

instant: 2015-12-03T17:00:08Z

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154