Разметка временной метки ISO с использованием Java 8 java.time api (только стандартная версия)
У меня возникли проблемы с получением миллисекунд из эпохи из строки в примере. Я пробовал эти три разных способа до сих пор, и пример показывает последнюю попытку. Всегда кажется, что 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, но хочу избежать зависимостей).
Изменить: Мгновенно. Из приведенного выше кода выбрано: 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
Ответы
Ответ 1
Кажется, это ошибка, которую я обнаружил во всех тестируемых версиях до и после 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.
Ответ 2
Работает ваш код, начиная с Java 8 Update 51
Теперь ваш код работает, начиная с Java 8 Update 51 в Mac OS X Mountain Lion. Отвечать Holger, что, возможно, была ошибка в более ранних версиях Java. Понятно, что java.time-платформа совершенно новая в 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]
Ответ 3
Поскольку момент не может быть правильно представлен длинным (они разработали API, чтобы не иметь проблем с Y 2040, когда длинного уже недостаточно), вы должны использовать комбинацию из двух методов
getEpochSecond()
и
getNano()
Первый получает вас от секунды от эпохи, а второй дает вам наносекунды, прошедшие с той же секунды.
Ответ 4
Instant.from(creationAccessor).toEpochMili() должен сортировать вас, по крайней мере, согласно ThreeTen javadoc для TemporalInstant. ThreeTen - эталонная реализация javax.time. Сообщите мне, если это сработает для вас или нет, оставив комментарий.