Синтаксический анализ метки времени ISO с помощью Java 8 java.api времени (только standard edition)
у меня возникли проблемы с получением миллисекунд от эпохи из строки в Примере. До сих пор я пробовал это тремя разными способами, и пример показывает последнюю попытку. Это всегда, кажется, сводится к тому, что TemporalAccessor не поддерживает ChronoField. Если бы я мог успешно построить экземпляр Instant, я мог бы использовать toEpochMilli ().
String dateStr = "2014-08-16T05:03:45-05:00"
TemporalAccessor creationAccessor = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(dateStr);
Instant creationDate = Instant.from(creationAccessor);
пожалуйста, дайте краткие ответы (не стройте форматер с нуля) и использовать только стандартный дистрибутив java 8 (я могу сделать это с помощью Joda, но хочу избежать зависимостей).
Edit: мгновенный.из кода выше выбрасывает:java.time.DateTimeException: Unable to obtain Instant from TemporalAccessor: {OffsetSeconds=-18000},ISO resolved to 2014-08-16T05:03:45 of type java.time.format.Parsed
4 ответов
это, кажется, ошибка, которую я нашел во всех проверенных версиях до и включая jdk1.8.0_20b19
но не в финале jdk1.8.0_20
. Так что загрузка обновленной версии jdk решит эту проблему. Он также решен в самом последнем jdk1.9.
обратите внимание, что старый добрый Java 7 работает во всех версиях:
long epochMillis = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")
.parse(dateStr).getTime();
Он также поддерживает получение Instant
:
Instant i=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").parse(dateStr).toInstant();
long epochMillis = i.toEpochMilli();
но, как уже было сказано, простое обновление делает ваш код Java 8 рабочим.
Ваш Код Работает, Начиная С Java 8 Update 51
ваш код работает сейчас, начиная с Java 8 Update 51 на Mac OS X Mountain Lion. The ответ by Хольгер что, возможно, была ошибка в более ранних версиях Java. Понятно, как java.Time framework является совершенно новым в Java 8.
вот измененная копия вашего кода.
String dateStr = "2014-08-16T05:03:45-05:00";
TemporalAccessor creationAccessor = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse( dateStr );
Instant instant = Instant.from( creationAccessor );
long millisSinceEpoch = instant.toEpochMilli( );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant, ZoneOffset.of( "-05:00" ) );
дамп в консоли.
System.out.println( "dateStr: " + dateStr );
System.out.println( "instant: " + instant );
System.out.println( " millis: " + millisSinceEpoch );
System.out.println( " zdt: " + zdt );
когда бежать.
dateStr: 2014-08-16T05:03:45-05:00
instant: 2014-08-16T10:03:45Z
millis: 1408183425000
zdt: 2014-08-16T05:03:45-05:00
Каноническим Методом:
parse(CharSequence text, TemporalQuery<T> query)
вы можете выполнить синтаксический анализ с помощью альтернативного метода.
класс doc для DateTimeFormatter
упоминает, что обычным способом разбора должен быть вызов DateTimeFormatter::parse(CharSequence text, TemporalQuery<T> query)
, а не DateTimeFormatter::parse(CharSequence text)
.
так вместо этого:
String input = "2007-12-03T10:15:30+01:00[Europe/Paris]" ;
TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_DATE_TIME.parse( input ) ;
...сделайте это, где мы добавляем второй аргумент, аргумент ссылка на метод в Java 8 синтаксис, чтобы вызвать преобразование from
способ (в этом примере ZonedDateTime :: from
):
String input = "2007-12-03T10:15:30+01:00[Europe/Paris]" ;
ZonedDateTime zdt = DateTimeFormatter.ISO_DATE_TIME.parse( input , ZonedDateTime :: from ) ;
дамп в консоли.
System.out.println("input: " + input );
System.out.println(" zdt: " + zdt );
при запуске.
input: 2007-12-03T10:15:30+01:00[Europe/Paris]
zdt: 2007-12-03T10:15:30+01:00[Europe/Paris]
поскольку instant не может быть правильно представлен с помощью long (они разработали API, чтобы не иметь проблем y 2040, когда long больше не достаточно), вы должны использовать комбинацию двух методов
getEpochSecond ()
и
getNano()
первый дает вам # секунд от эпохи, а последний дает вам # наносекунд, которые прошли с той же секунды.
мгновенный.от (creationAccessor).toEpochMili () должен сортировать вас, по крайней мере, в соответствии с ThreeTen javadoc для TemporalInstant. ThreeTen является ссылочной реализацией javax.время. Дайте мне знать, если это работает для вас или нет, оставив комментарий.