ТЛ; др
Использовать только java.time классы.
Никогда не используйте Date
класс.
Используйте UTC при регистрации.
Instant.now().toString()
2018-01-23T01: 23: 45.123456Z
Подробнее
Это уже много раз решалось при переполнении стека.
Ужасные старые классы даты и времени изобилуют неудачным выбором дизайна. Среди этих неудачных вариантов - поведение метода Date::toString
динамического применения текущего часового пояса JVM по умолчанию при генерации строки. Благонамеренный, но вводящий в заблуждение, как java.util.Date
, как java.time.Instant
, представляет момент в UTC.
6 сентября этого года в 22:00 по западному побережью большей части Северной Америки одновременно происходит 21:00 по UTC со смещением от UTC на семь часов после UTC в летнее время (DST). Тот же самый момент, та же самая точка на временной шкале, другое время настенных часов.
Почему ФДТ?
Почему, в частности, тихоокеанское летнее время? Ваша JVM всегда имеет текущий часовой пояс по умолчанию. По-видимому, для вашей JVM установлена текущая зона по умолчанию, такая как America/Los_Angeles
(PDT не является часовым поясом реального времени).
Способ установки этого значения по умолчанию зависит от реализации JVM и ваших настроек. Обычно JVM при запуске обнаруживает текущую зону по умолчанию операционной системы хоста. Вы можете передать аргументы при запуске JVM, чтобы указать зону, а не выбрать по умолчанию хост-ОС.
После запуска любой код в любом потоке любого приложения в JVM может в любой момент изменить текущий часовой пояс по умолчанию с вызовом на TimeZone.setDefault
, чтобы немедленно повлиять на весь другой код в этом JVM.
Это означает, что вы никогда не должны полагаться на текущую зону по умолчанию для чего-то критического, так как ее значение не зависит от вас, как программиста. Всегда указывайте желаемый / ожидаемый часовой пояс в явном виде. Даже если вы хотите использовать текущее значение по умолчанию, сделайте явный вызов ZoneId.systemDefault
.
Бонусный совет: То же самое для Locale
. Всегда текущий по умолчанию. Но указывайте явно, а не полагайтесь неявно по умолчанию.
Использование java.time
Никогда не используйте устаревшие классы дат. Используйте только java.time классы.
При ведении журнала всегда используйте UTC. Визуализация текста в стандартном формате ISO 8601, как показано в Instant::toString
.
Instant instant = Instant.now() ;
Если вы хотите просмотреть этот момент в часах настенного времени, используемых людьми определенного региона, примените часовой пояс (ZoneId
), чтобы получить ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
О java.time
Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
и & SimpleDateFormat
.
Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на java.time классы.
Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Вы можете обмениваться java.time объектами напрямую с вашей базой данных. Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти некоторые полезные классы, такие как Interval
, YearWeek
, YearQuarter
и more .