Java 8 date/time: instant, could not be parsed at index 19
Asked Answered
M

3

9

I have following piece of code:

String dateInString = "2016-09-18T12:17:21:000Z";
Instant instant = Instant.parse(dateInString);

ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("Europe/Kiev"));
System.out.println(zonedDateTime);

It gives me following exception:

Exception in thread "main" java.time.format.DateTimeParseException: Text '2016-09-18T12:17:21:000Z' could not be parsed at index 19 at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851) at java.time.Instant.parse(Instant.java:395) at core.domain.converters.TestDateTime.main(TestDateTime.java:10)

When I change that last colon to a full stop:

String dateInString = "2016-09-18T12:17:21.000Z";

…then execution goes fine:

2016-09-18T15:17:21+03:00[Europe/Kiev]

So, the question is - how to parse date with Instant and DateTimeFormatter?

Maritime answered 10/2, 2017 at 20:13 Comment(0)
C
8

The "problem" is the colon before milliseconds, which is non-standard (standard is a decimal point).

To make it work, you must build a custom DateTimeFormatter for your custom format:

String dateInString = "2016-09-18T12:17:21:000Z";
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .append(DateTimeFormatter.ISO_DATE_TIME)
    .appendLiteral(':')
    .appendFraction(ChronoField.MILLI_OF_SECOND, 3, 3, false)
    .appendLiteral('Z')
    .toFormatter();
LocalDateTime instant = LocalDateTime.parse(dateInString, formatter);
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("Europe/Kiev"));
System.out.println(zonedDateTime);

Output of this code:

2016-09-18T12:17:21+03:00[Europe/Kiev]

If your datetime literal had a dot instead of the last colon, things would be much simpler.

Cartie answered 10/2, 2017 at 20:41 Comment(3)
Actually the standard is a COMMA or a FULL STOP (period), with the comma being preferred. See ISO 8601:2004 Third edition 2004-12-01, section “4.2.2.4 Representations with decimal fraction”: … the decimal fraction shall be divided from the integer part by the decimal sign specified in ISO 31-0, i.e. the comma [,] or full stop [.]. Of these, the comma is the preferred sign. …Lindberg
@basil Maybe for ISO, but not in the JDK, which uses the decimal pointCartie
any idea about my question : #57174718Octet
M
3

Use a SimpleDateFormat:

String dateInString = "2016-09-18T12:17:21:000Z";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSS");
Instant instant = sdf.parse(dateInString).toInstant();
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("Europe/Kiev"));
System.out.println(zonedDateTime);

2016-09-18T19:17:21+03:00[Europe/Kiev]

Melodiemelodion answered 10/2, 2017 at 20:22 Comment(0)
D
-3
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/MM/yyyy");

String date = "16/08/2016";

//convert String to LocalDate
LocalDate localDate = LocalDate.parse(date, formatter);

If the String is formatted like ISO_LOCAL_DATE, you can parse the String directly, no need conversion.

package com.mkyong.java8.date;

import java.time.LocalDate;

public class TestNewDate1 {

    public static void main(String[] argv) {

        String date = "2016-08-16";

        //default, ISO_LOCAL_DATE
        LocalDate localDate = LocalDate.parse(date);

        System.out.println(localDate);

    }

}

Check out this site Site here

Disengage answered 10/2, 2017 at 20:33 Comment(1)
What about the time component?Cartie

© 2022 - 2024 — McMap. All rights reserved.