0

i have the following date 2017-02-19T12:23:37.000000-00:00

And this code :

    Long tt = null;
    String date = "2017-02-19T12:23:37.000000-00:00";
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    try {
        Date parsedDate = formatter.parse(date);
        tt =  parsedDate.getTime();
    } catch (ParseException e) {
        System.out.println(e);
        tt = (long) 9999999;
    }

    System.out.println(tt);

Output :

java.text.ParseException: Unparseable date: "2017-02-19T12:23:37.000000-00:00"

9999999

Thank you for the help.

Community
  • 1
  • 1
  • 3
    Your input doesn't match your format. You've got microsecond precision in the input, and millisecond precision in the format. – Andy Turner Feb 19 '17 at 13:31
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html), and `java.text.SimpleTextFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. – Basil Bourque Feb 20 '17 at 06:39

3 Answers3

2

Your millisecond part has 6 digits not three, and the timezone is given not as an RFC 822 time zone but as an ISO 8601 time zone.

This will work:

"yyyy-MM-dd'T'HH:mm:ss.SSSSSSX"

As was correctly pointed out in the comments, this will garble up the millisecond part if it ever deviates from 000000.

Since Java 8 there is a much better way to parse dates and times. For ISO-8601 dates as yours, simply use this:

OffsetDateTime.parse("2017-02-19T12:23:37.000000-00:00")

Also see Basil Bourque's great answer for a more detailed explanation.

Community
  • 1
  • 1
Leviathan
  • 2,468
  • 1
  • 18
  • 24
  • 3
    S is for milliseconds, not microseconds. If the string was "2017-02-19T12:23:37.000999-00:00", your way of parsing would add 999 milliseconds instead of 999 microseconds (i.e. nothing, since a Date has a millisecond precision) to the date. So, basically, it only works if the microseconds part is always 000000. – JB Nizet Feb 19 '17 at 13:40
  • 2
    As JB Nizet points out, this code *fails* if you do not always have zeros. Another example: "2017-02-19T12:23:37.123456-00:00" gives **incorrect result** of `1487507140456`. See this [code run live at IdeOne.com](http://ideone.com/6px98W). The legacy date-time classes are limited to milliseconds resolution, and your suggested formatting pattern is behaving improperly. Use the java.time classes instead. – Basil Bourque Feb 20 '17 at 06:20
  • @JB Nizet and Basil Bourque: Thanks for the illuminating comments, I updated my answer to reflect this. – Leviathan Feb 20 '17 at 19:08
2

tl;dr

OffsetDateTime.parse( "2017-02-19T12:23:37.000000-00:00" )

Use java.time

You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes.

Milliseconds vs nanoseconds

The legacy classes support only milliseconds resolution, limited to three decimal places of fractional second. The java.time classes use nanoseconds resolution, for up to nine decimal places of fractional second. Your example data of six decimal places is for microseconds.

ISO 8601

Your input string happens to be in standard ISO 8601 format.

Well, almost standard: Your example has a negative zero offset-from-UTC. A negative zero offset is explicitly forbidden by the ISO 8601 standard. The standard requires a zero offset be marked with as a positive number with the + sign rather than - sign. However, RFC 3339 which claims to be a profile of ISO 8601 violates this rule with the unfortunate and unwise choice as a different connotation.

The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to specify a formatting pattern at all.

OffsetDateTime

Fortunately for you, the OffsetDateTime class tolerates the negative zero offset when parsing your input.

String input = "2017-02-19T12:23:37.123456-00:00" ;
OffsetDateTime odt = OffsetDateTime.parse( input );

See this code run live at IdeOne.com.

odt.toString(): 2017-02-19T12:23:37.123456Z

Notice the use of ISO 8601 formatting by OffsetDateTime::toString when generating a string from our OffsetDateTime. The Z on the end is short for Zulu, and means UTC.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

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

Your input date doesn't match the pattern you specified. Try changing the pattern:

    String date = "2017-02-19T12:23:37.000000-00:00";
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX");

For more information, you can look at documentation examples here.

Juras
  • 9
  • 1
    S is for milliseconds, not microseconds. If the string was "2017-02-19T12:23:37.000999-00:00", your way of parsing would add 999 milliseconds instead of 999 microseconds (i.e. nothing, since a Date has a millisecond precision) to the date – JB Nizet Feb 19 '17 at 13:40