2017-02-10 2 views
2

я следующий кусок кода:Java 8 дата/время: мгновенный, не может быть разобрано на индекс 19

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); 

Это дает мне следующее исключение:

Исключение в потоке «основной» java.time.format.DateTimeParseException: Текст '2016-09-18T12: 17: 21: 000Z' не может быть проанализирован по индексу 19 в java.time.format.DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:1949) at java.time.format.DateTimeFormatter.parse (DateTimeForm atter.java:1851) на java.time.Instant.parse (Instant.java:395) при core.domain.converters.TestDateTime.main (TestDateTime.java:10)

Когда я изменить это последнее двоеточие до полной остановки:

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

... то выполнение идет отлично:

2016-09-18T15: 17: 21 + 03: 00 [Европа/Киев]

Итак, вопрос в том, как разобрать дату с Instant и DateTimeFormatter?

ответ

3

«Проблема» является двоеточие перед тем миллисекундах, который не является стандартной (стандарт десятичной точки).

Чтобы заставить его работать, вы должны создать пользовательские DateTimeFormatter для пользовательского формата:

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); 

Выход этого кода:

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

Если DateTime буквальным имел точку вместо из последней толстой кишки, было бы намного проще.

+0

Фактически стандартом является COMMA * или * FULL STOP (период), причем ** запятая является предпочтительной **. См. * ISO 8601: 2004 * Третье издание 2004-12-01, раздел «4.2.2.4 Представления с десятичной дробью»: ... десятичная дробь делится с целой части на десятичный знак, указанный в ISO 31-0, т.е. запятая [,] или полная остановка [.]. Из них запятая является предпочтительным знаком.... –

+0

@basil Возможно, для ISO, но не в JDK, [который использует десятичную точку] (http://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatterBuilder.html# appendFraction-java.time.temporal.TemporalField-INT-INT-boolean-) – Bohemian

1

Используйте 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 [Европа/Киев]

-1
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/MM/yyyy"); 

String date = "16/08/2016"; 

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

Если String отформатирован как ISO_LOCAL_DATE, вы можете проанализировать строку напрямую, без необходимости преобразования.

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); 

    } 

} 

Проверить этот сайт Site here

+0

Как насчет времени? – Bohemian

Смежные вопросы