java.util.Dateникогда не является датой локального компьютера. Он всегда определяется как прошедшие миллисекунды с 01.01.1970 относительно UTC + 00:00. Возможно, toString()вас смущает поведение его метода , который действительно использует представление в местном часовом поясе.
OffsetDateTime utc =OffsetDateTime.now(ZoneOffset.UTC);
Чтобы ответить на ваш комментарий, вы можете затем преобразовать его в дату (если вы не зависите от устаревшего кода, я не вижу причин почему) или в миллисекунды с эпох:
Date date =Date.from(utc.toInstant());long epochMillis = utc.toInstant().toEpochMilli();
Спасибо. можно ZonedDateTime преобразовать в Date или в long (ms)?
Марк
7
Хотя код этого ответа технически работает, не было бы более подходящим использовать OffsetDateTime, ZonedDateTimeесли бы мы работали с простым смещением от UTC, а не с полным часовым поясом?
Basil Bourque
1
Не было utc.toInstant().toEpochMilli()бы более точного преобразования в миллис?
toStringМетод создает объект типа String с текстом , представляющим значение даты и время , используя один из стандартных ISO 8601 форматов.
String output = instant.toString();
2016-06-27T19: 15: 25.864Z
InstantКласс является основным классом многокомпонентного в java.time. Это должен быть ваш класс при обработке даты и времени, так как обычно лучше всего отслеживать, хранить и обмениваться значениями даты и времени в формате UTC.
OffsetDateTime
Но Instantимеет ограничения, такие как отсутствие параметров форматирования для создания строк в альтернативных форматах. Для большей гибкости конвертируйте из Instantв OffsetDateTime. Укажите смещение от UTC . В java.time это означает ZoneOffsetобъект. Здесь мы хотим придерживаться UTC (+00), чтобы мы могли использовать удобную константу ZoneOffset.UTC.
Теперь, имея OffsetDateTimeобъект в руках, вы можете использовать его DateTimeFormatterдля создания объектов String с текстом в альтернативных форматах. Найдите множество примеров использования DateTimeFormatter.
В этом примере мы применяем часовой пояс Монреаля. Летом при ерунде перехода на летнее время (DST) зона имеет смещение -04:00. Итак, обратите внимание, что время суток в выводе на четыре часа раньше, 15а не 19часов. Instantи ZonedDateTimeоба представляют собой один и тот же одновременный момент, только рассматриваемый через две разные линзы.
ZoneId z =ZoneId.of("America/Montreal");ZonedDateTime zdt = instant.atZone( z );
Хотя вам следует избегать старых классов даты и времени, при необходимости вы можете преобразовать, используя новые методы, добавленные к старым классам. Здесь мы используем java.util.Date.from( Instant )и java.util.Date::toInstant.
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в java.sql.*занятиях. Поддержка Hibernate 5 и JPA 2.2 java.time .
Благодарю за то, что говорят, что летнее время - это
ерунда
так что, если бы DST не существовало ZonedDateTime, не было бы необходимости, так как все ZoneIdбыло бы сопоставлено с тем, что ZoneOffsetмы могли бы просто использовать OffsetDateTime?
Wilmol
1
@wilmol Нет. Переход на летнее время (DST) - лишь одна из многих причин, по которым политики решают переопределить границы часовых поясов и смещения внутри этих зон. Недавно Северная Корея изменила свои часы на полчаса, чтобы синхронизировать их с Южной Кореей по дипломатическим причинам. Во время войны захватчики / оккупанты могут изменить смещение, чтобы оно соответствовало смещению в родной стране. В настоящее время появилась новая мода, когда правительства предпочитают прекратить переход на летнее время, но постоянно остаются на летнем времени, а не возвращаются к своему предыдущему стандартному времени. Всегда планируйте смещение каждой смены зоны, иначе ваше приложение в конечном итоге сломается.
Basil
1
Фантастический ответ! Я очень ценю время, которое вы вложили в это. :)
drognisep 04
ZoneId.of («Америка / Монреаль»); зачем кому-то изобретать такое в jdk? он уродлив, отвратителен, не говорит, что что-то не так, до времени выполнения, кто может запомнить весь этот жесткий код? почему бы не использовать это в классе ENUM?
workplaylifecycle
4
В java8 я бы использовал Instantкласс, который уже находится в UTC и с которым удобно работать.
import java.time.Instant;Instant ins =Instant.now();long ts = ins.toEpochMilli();Instant ins2 =Instant.ofEpochMilli(ts)
В качестве альтернативы вы можете использовать следующее:
import java.time.*;Instant ins =Instant.now();OffsetDateTime odt = ins.atOffset(ZoneOffset.UTC);ZonedDateTime zdt = ins.atZone(ZoneId.of("UTC"));
Нет, в этом Instantесть не по местному времени. По Instantопределению находится в формате UTC. Так что нет необходимости в махинациях, замеченных в этом Ответе, при попытке попасть в UTC; Instantуже находится в UTC. См. Мой ответ для получения дополнительной информации и более простого кода.
java.util.Date
никогда не является датой локального компьютера. Он всегда определяется как прошедшие миллисекунды с 01.01.1970 относительно UTC + 00:00. Возможно,toString()
вас смущает поведение его метода , который действительно использует представление в местном часовом поясе.Ответы:
С Java 8 вы можете написать:
Чтобы ответить на ваш комментарий, вы можете затем преобразовать его в дату (если вы не зависите от устаревшего кода, я не вижу причин почему) или в миллисекунды с эпох:
источник
OffsetDateTime
,ZonedDateTime
если бы мы работали с простым смещением от UTC, а не с полным часовым поясом?utc.toInstant().toEpochMilli()
бы более точного преобразования в миллис?tl; dr
java.time
Утомительные старые классы даты и времени, входящие в состав самых ранних версий Java, были вытеснены классами java.time, встроенными в Java 8 и более поздних версий . См. Учебное пособие по Oracle . Большая часть функциональности была перенесена на Java 6 и 7 в ThreeTen-Backport и дополнительно адаптирована для Android в ThreeTenABP .
Instant
Значок
Instant
представляет собой момент на временной шкале в формате UTC с разрешением до наносекунд .toString
Метод создает объект типа String с текстом , представляющим значение даты и время , используя один из стандартных ISO 8601 форматов.Instant
Класс является основным классом многокомпонентного в java.time. Это должен быть ваш класс при обработке даты и времени, так как обычно лучше всего отслеживать, хранить и обмениваться значениями даты и времени в формате UTC.OffsetDateTime
Но
Instant
имеет ограничения, такие как отсутствие параметров форматирования для создания строк в альтернативных форматах. Для большей гибкости конвертируйте изInstant
вOffsetDateTime
. Укажите смещение от UTC . В java.time это означаетZoneOffset
объект. Здесь мы хотим придерживаться UTC (+00), чтобы мы могли использовать удобную константуZoneOffset.UTC
.Или пропустите
Instant
занятия.Теперь, имея
OffsetDateTime
объект в руках, вы можете использовать егоDateTimeFormatter
для создания объектов String с текстом в альтернативных форматах. Найдите множество примеров использованияDateTimeFormatter
.ZonedDateTime
Если вы хотите отобразить время на настенных часах для определенного часового пояса, примените a,
ZoneId
чтобы получитьZonedDateTime
.В этом примере мы применяем часовой пояс Монреаля. Летом при ерунде перехода на летнее время (DST) зона имеет смещение
-04:00
. Итак, обратите внимание, что время суток в выводе на четыре часа раньше,15
а не19
часов.Instant
иZonedDateTime
оба представляют собой один и тот же одновременный момент, только рассматриваемый через две разные линзы.Преобразование
Хотя вам следует избегать старых классов даты и времени, при необходимости вы можете преобразовать, используя новые методы, добавленные к старым классам. Здесь мы используем
java.util.Date.from( Instant )
иjava.util.Date::toInstant
.И иду в другом направлении.
Точно так же ищите новые методы, добавленные к
GregorianCalendar
(подклассуCalendar
) для преобразования в и изjava.time.ZonedDateTime
.О java.time
Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как
java.util.Date
,Calendar
, иSimpleDateFormat
.Чтобы узнать больше, см. Oracle Tutorial . И поищите в Stack Overflow множество примеров и объяснений. Спецификация - JSR 310 .
Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в
java.sql.*
занятиях. Поддержка Hibernate 5 и JPA 2.2 java.time .Где взять классы java.time?
источник
ZonedDateTime
, не было бы необходимости, так как всеZoneId
было бы сопоставлено с тем, чтоZoneOffset
мы могли бы просто использоватьOffsetDateTime
?В java8 я бы использовал
Instant
класс, который уже находится в UTC и с которым удобно работать.В качестве альтернативы вы можете использовать следующее:
Вернуться к
Instant
источник
Instant
есть не по местному времени. ПоInstant
определению находится в формате UTC. Так что нет необходимости в махинациях, замеченных в этом Ответе, при попытке попасть в UTC;Instant
уже находится в UTC. См. Мой ответ для получения дополнительной информации и более простого кода.В Java8 вы используете новый API времени и конвертируете Instant в ZonedDateTime, используя часовой пояс UTC.
источник
Однострочное решение в Java 8:
источник
java.util.Date
устарела.