Подтвердить что ты не робот

Разметка временной метки 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

4b9b3361

Ответ 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. Сообщите мне, если это сработает для вас или нет, оставив комментарий.