Как преобразовать дату UTC в UTC OffsetDateTime в java 8?

В моем случае я заметил, что ошибка при попытке установить соответствующий пакет. В моем случае python-heatclient требовал позиционного, что требовало pbr. Установка pbr не удалась. Когда я установил pbr явно перед установкой python-heatclient, он работал, как ожидалось.

Вызвать это не удалось venv/bin/pip install python-heatclient

Вызовы, которые преуспели

venv/bin/pip install pbr

venv/bin/pip install python-heatclient

0
задан Draken 13 July 2018 в 14:05
поделиться

4 ответа

tl; dr

A java.util.Date и Instant оба представляют момент в UTC. Другие часовые пояса и смещения не имеют значения.

Instant instant = myJavaUtilDate.toInstant() 

Как я могу преобразовать объект даты, который уже находится в UTC, в объект OffsetDateTime в самом UTC в Java?

необходимо OffsetDateTime. Используйте Instant, как показано выше.

Используйте ZonedDateTime, а не OffsetDateTime

Вам не нужно OffsetDateTime. Смещение-от-UTC - это всего лишь несколько часов и минут. Ни больше ни меньше. Напротив, часовой пояс - это история прошлых, настоящих и будущих изменений в смещении, используемом людьми определенного региона. Поэтому часовой пояс, если он известен, всегда предпочтительнее простого смещения. Поэтому используйте ZonedDateTime, а не OffsetDateTime, где это возможно.

Используйте OffsetDateTime только при задании смещения от UTC, например +02:00, без контекста определенного часового пояса, например Europe/Paris.

Преобразуйте Date в Instant

Если дано java.util.Date, то концерт с современным классом (Instant) заменил этот неприятный старый класс. Оба представляют момент в UTC как счетчик с той же эпохальной ссылки первого момента 1970 года в UTC. Современный класс разрешается наносекундами, а не миллисекундами. Чтобы преобразовать, вызовите новые методы, добавленные в старый класс.

Instant instant = myJavaUtilDate.toInstant() ;

Помните, что оба java.util.Date и Instant всегда представляют собой момент в UTC.

Захватить текущий момент, «сейчас»

Захватить текущий момент в UTC.

Instant instant = Instant.now() ;

now () и другие вещи исключены, я думаю.

Нет, вы всегда можете зафиксировать текущий момент, вызвав Instant.now() на любой машине в любое время. Текущий часовой пояс JVM по умолчанию не имеет значения, так как Instant всегда всегда в UTC.

Откорректируйте с UTC в другой часовой пояс. То же самое время, та же точка на временной шкале, разное время настенных часов. & lt; - Это наиболее важная концепция для понимания в этом обсуждении!

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone() ;

В качестве ярлыка вы можете пропустить Мгновенное действие при захвате текущего момента.

ZonedDateTime zdt = ZonedDateTime.now( z ) ;

Вернитесь в UTC, извлекая объект Instant.

Instant instant = zdt.toInstant() ; 

Совет: Фокусировка на UTC

Обычно лучше всего выполнять большую часть своей работы в UTC. При хранении, протоколировании, отладке или обмене моментом используйте UTC. Забудьте о своем собственном ограниченном часовом поясе во время работы в качестве программиста или системного администратора; научиться думать в UTC. Сделайте второй клик в своем офисе, установленном в UTC.

Избегайте периодического переключения между часовыми поясами. Вставить UTC. Отрегулируйте часовой пояс только при представлении пользователю или при необходимости бизнес-логики.

2
ответ дан Basil Bourque 17 August 2018 в 12:45
поделиться

Он уже работает по назначению, проблема в том, что Date.toString «помогает» преобразовать внутреннюю метку времени в ваш местный часовой пояс. Использование Date.toGMTString приведет к тому же самому методу времени для каждого из значений.

Если результирующая временная метка неверна, проблема заключается в создании экземпляра Date. Использование конструктора типа new Date(2018, 7, 11, 15, 45, 11) приведет к вычислению этой даты для системного часового пояса, а не UTC. Чтобы создать его для UTC, есть Date.UTC, но все эти API были устаревшими с Java 1.1, потому что они настолько запутывают.

0
ответ дан Kiskae 17 August 2018 в 12:45
поделиться
public static OffsetDateTime convertFrom(Date source) {
    if (source instanceof Timestamp) {
        return ((Timestamp) source).toLocalDateTime()
                .atOffset(ZoneOffset.UTC);
    }
    return source.toInstant().atOffset(ZoneOffset.UTC);
}

Объект, переданный вашему методу, был java.sql.Timestamp, а не Date. Мы можем видеть этот факт по тому, как он был напечатан: 2018-07-11 15:45:13.0 - это возвращаемое значение из Timestamp.toString(). Класс Timestamp реализуется как подкласс Date, но это не означает, что мы не можем и не должны обрабатывать его как Date. Документация предупреждает нас:

Из-за различий между классом Timestamp и классом java.util.Date, упомянутым выше, рекомендуется, чтобы код не отображал значения Timestamp в качестве экземпляра java.util.Date. Взаимодействие наследования между Timestamp и java.util.Date действительно означает наследование реализации, а не наследование типа.

В реализации выше я предположил, что вы не можете смягчить возможность получения Timestamp аргумент, поэтому я обрабатываю возможность, насколько я могу. Однако код все еще хрупкий, потому что иногда Timestamp обозначает точку во времени (я должен сказать, что это точка), в других случаях она обозначает дату и час дня. Предоставлено, что Timestamp не содержит в нем часового пояса, два не совпадают. Я понимаю, что ваш образец Timestamp обозначает дату и время 2018-07-11 15: 45: 13.0, и вы хотите, чтобы это было интерпретировано в UTC. Мой код делает это (ваш код в вопросе, с другой стороны, правильно обрабатывает ситуацию, когда Timestamp обозначает момент времени). Кроме того, даже если в моем коде не указано никакого часового пояса, его поведение по-прежнему зависит от настройки часового пояса вашего JVM.

Когда я передаю Timestamp из 2018-07-11 15:45:13.0 в мой метод выше, он возвращает OffsetDateTime из 2018-07-11T15:45:13Z.

Двойной характер Timestamp является неудачным и запутанным, и единственным реальным решением было бы, если бы вы могли полностью отказаться от этого класса. Класс Date тоже плохо разработан, и оба устарели и заменены java.time, современным Java-API датой и временем. Если вы не можете избежать старых классов в своем коде, я, безусловно, понимаю ваше желание преобразовать в современную OffsetDateTime первую вещь. Если, с другой стороны, я правильно понимаю, что дата и время проходят через JSON, вы можете проанализировать его на своей стороне без каких-либо старых классов даты и времени, что было бы хорошим решением вашей проблемы. И при любых обстоятельствах, если ваша реальная цель состоит в том, чтобы представить момент времени в нейтральном часовом поясе, я согласен с Базилем Бурком в предпочтении Instant по OffsetDateTime в UTC.

Ссылка : Документация java.sql.Timestamp

0
ответ дан Ole V.V. 17 August 2018 в 12:45
поделиться

Это то, о чем вы просите,

ZonedDateTime zonedDateTime = ZonedDateTime
    .of(LocalDateTime.of(2018, 7, 11, 15, 45, 13), ZoneId.of("UTC"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss'Z'", Locale.US);
System.out.println(zonedDateTime.format(formatter));

Вам нужно иметь DateTimeFormatter, если вам нужно отформатировать его до заданного шаблона.

0
ответ дан Ravindra Ranwala 17 August 2018 в 12:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: