В чем разница между java.util.Date и Zoneddatetime?

Согласно MSDN

The scope of a using directive is limited to the file in which it appears.

Итак, ответ № Нет. Вы не можете определить псевдоним в одном файле и использовать его во всей сборке

0
задан Ole V.V. 28 February 2019 в 05:10
поделиться

3 ответа

Шестнадцать лет назад я написал статью для JavaWorld , озаглавленную Каков ваш часовой пояс , в которой описана проблема, которую вы описываете при использовании класса java.util.Date. Чтобы «увидеть» значение экземпляра класса java.util.Date, вы должны преобразовать его в String. До Java 1.8 это преобразование всегда также учитывало часовой пояс. Это одна из причин, почему в Java 1.8 был представлен новый API Date-Time. Новый код, написанный для Java версии 1.8 и выше, должен использовать новый API. Я полагаю, что вам следует также рассмотреть возможность преобразования старого кода в новый API, если это возможно.

0
ответ дан Abra 28 February 2019 в 05:10
поделиться

java.util.Date является почти устаревшим классом, который обеспечивает обертку вокруг миллисекундного значения. Он не предоставляет никакой информации о часовом поясе, не имеет никаких полезных методов, и вы всегда должны избегать его использования.

ZonedDateTime - это класс из нового JDK8 API даты, который предоставляет дату-время с часовым поясом в календарной системе ISO-8601. Вы должны проверить

объяснение Oracle для нового формата даты

0
ответ дан ByeBye 28 February 2019 в 05:10
поделиться

tl; dr

В чем разница между java.util.Date и Zoneddatetime?

  • Date представляет момент в UTC, в то время как ZonedDateTime представляет момент в конкретном часовом поясе.
  • Date - ужасный класс, изобилующий недостатками дизайна, которые никогда не должны использоваться, в то время как ZonedDateTime - современный класс из пакета java.time , который вы найдете довольно полезно.

Java поставляется с двумя очень разными средами для обработки работы с датой и временем: ужасно неуклюжим и неудачным набором унаследованных классов и современным ведущим в отрасли набором классов, найденным в [1180 ] java.time пакет.

Legacy ➙ modern:

  • java.util.Date был заменен на java.time.Instant
    • Оба представляют момент в UTC.
  • java.util.GregorianCalendar был заменен на java.time.ZonedDateTime
    • Оба представляют момент, наблюдаемый в определенном часовом поясе.

table of legacy and modern classes for date-time handling in Java

java.util.Date

Класс Date представляет момент в UTC. То есть дата, время суток плюс контекст UTC.

Внутренне это счет в миллисекундах с эталонной даты первого момента 1970 года в UTC, 1970-01-01T00: 00: 00Z.

Чтобы усложнить ситуацию:

  • Существует захват часового пояса при создании, который хранится глубоко внутри, без геттеров или сеттеров. Таким образом, по большей части мы можем игнорировать эту зону, хотя она применима к таким вопросам, как реализация этого класса equals.
  • При вызове toString этот класс имеет очень сбивающее с толку поведение динамического применения текущего часового пояса JVM при генерации текста для представления значения этого объекта. Несмотря на благие намерения, эта анти-функция причинила неисчислимые страдания программистам Java, пытающимся научиться работать с датой и временем.

В замешательстве? Да, этот класс сбивает с толку, жалкий беспорядок плохих дизайнерских решений. Усугубляется последующим добавлением java.util.Calendar & amp; GregorianCalendar.

Все эти проблемные классы даты и времени в комплекте с самой ранней версией Java теперь полностью вытеснены классами java.time .

В частности, java.util.Date заменяется на java.time.Instant. Оба представляют момент в UTC, считая с эпохи 1970 UTC. Но Instant имеет более высокое разрешение, наносекунд , а не миллисекунд .

Вы можете конвертировать туда-обратно между унаследованным классом Date и современным классом Instant, вызывая новые методы, добавленные к старому классу. Обычно вы избегаете использования Date. Но при взаимодействии со старым кодом, который еще не обновлен до java.time , вам может понадобиться конвертировать.

java.time.ZonedDateTime

Современный класс ZonedDateTime представляет момент, наблюдаемый во время настенных часов, используемых людьми определенного региона (часового пояса).

Итак, Instant и ZonedDateTime похожи в том, что они оба представляют момент, конкретную точку на этой временной шкале. Разница в том, что ZonedDateTime знает о правилах часового пояса. Таким образом, ZonedDateTime знает, как учитывать аномалии, такие как переход на летнее время (DST) или другие изменения в хронометраже, требуемые политиками.

Вы можете думать об этом как:

ZonedDateTime = (Instant + ZoneId)

Мы можем легко настроить из UTC для некоторого часового пояса путем применения часового пояса (ZoneId) к объекту Instant.

Instant instant = Instant.now() ;             // Capture the current moment as seen in UTC.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;     // Apply a time zone to see the same moment through the wall-clock time in use by the people of a particular region (a time zone). 

См. Этот код, запущенный на IdeOne.com . Обратите внимание на другую дату и другое время суток, но в то же время одновременно.

instant.toString (): 2019-02-27T19: 32: 43.366Z

zdt.toString (): 2019-02-28T04: 32: 43.366 + 09: 00 [Азия / Токио]

Важная концепция: Instant и ZonedDateTime оба представляют один и тот же момент, одну и ту же одновременную точку на временной шкале. Они отличаются по времени настенных часов. Например, если кто-то в Японии звонит кому-то в Исландии ( где UTC используется для своих часов все время), и они оба смотрят на часы, висящие на их соответствующих стенах, они увидят другое время суток и, возможно, даже другую дату в месячном календаре. В тот же момент, разное время настенных часов.

Что касается унаследованных классов, то эквивалентом ZonedDateTime является GregorianCalendar , конкретная реализация java.util.Calendar . Действительно, старый класс GregorianCalendar получил новые методы для преобразования в / из ZonedDateTime.

ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime();  // Convert from legacy to modern class.

… и…

GregorianCalendar gc = GregorianCalendar.from( zdt ) ;      // Convert from modern to legacy class.

Заключение

Таким образом, Date эквивалентно Instant, оба являются моментом в UTC. Но ZonedDateTime отличается от обоих тем, что часовой пояс скорректировал восприятие момента, применяя линзу регулировки времени на часах людей региона.

Советы:

  • Никогда не используйте Date. Когда вручите Date, немедленно преобразуйте в Instant. Затем перейдите к вашей бизнес-логике.
  • Большая часть работы выполняется в UTC. Отслеживание моментов, отладка, ведение журнала, обмен значениями даты и времени и сохранение в базе данных, как правило, должны выполняться в UTC. Учитесь забывать о своем собственном приходском часовом поясе, когда работаете программистом. Держите вторые часы на вашем столе, настроенные на UTC.

База данных

Вопрос затрагивает работу базы данных. Вот краткое резюме. Поиск переполнения стека для более подробной информации, поскольку это уже было обработано много раз.

Начиная с JDBC 4.2, мы можем напрямую обмениваться объектами java.time с базой данных. Используйте PreparedStatement::setObject и ResultSet::getObject. Больше не нужно трогать ужасные java.sql.* классы, такие как java.sql.Timestamp.

Вы , возможно, сможете обменять Instant, но спецификация JDBC этого не требует. Спецификация вместо этого требует OffsetDateTime.

индексирование.

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

И хранение.

myPreparedStatement.setObject( … , odt ) ;

Если у вас под рукой Instant, конвертируйте в OffsetDateTime , используя константу ZoneOffset.UTC .

OffsetDateTime odt = Instant.atOffset( ZoneOffset.UTC ) ;

Чтобы просмотреть этот момент через время настенных часов некоторого региона, примените ZoneId.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

Чтобы сохранить ZonedDateTime в базе данных, преобразуйте в OffsetDateTime. Это лишает информацию о часовом поясе (историю прошлых, настоящих и будущих изменений, внесенных в смещение, используемое жителями этого региона по решению их политиков), оставляя дату, время дня и смещение -из UTC (количество часов, минут, секунд).

OffsetDateTime odt = zdt.toOffsetDateTime(); 

Большинство баз данных хранят момент в UTC для столбца стандартного типа SQL TIMESTAMP WITH TIMESTAMP. При отправке вашего OffsetDateTime в базу данных ваш драйвер JDBC, скорее всего, отрегулирует смещение в OffsetDateTime до нуля часов-минут-секунд (для самого UTC). Но мне нравится делать это явно. Это облегчает отладку и демонстрирует читателю мое понимание момента, хранящегося в UTC.

OffsetDateTime odt = zdt.toOffsetDateTime().withOffsetSameInstant( ZoneOffset.UTC ) ; 
0
ответ дан Basil Bourque 28 February 2019 в 05:10
поделиться
Другие вопросы по тегам:

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