tl; dr
- Использование
java.time.Clock
, ZonedDateTime
, Instant
, ZoneId
. - Добавление измененного объекта
Clock
в качестве зависимости: Clock.fixed( … )
. - Никогда не использовать
Date
, Calendar
, SimpleDateFormat
, Timestamp
, TimeZone
.
Передать измененный Clock
объект как зависимость
Вы используете ужасные классы даты и времени, которые были вытеснены несколько лет назад классами java.time , определенными в JSR 310.
Класс java.time.Clock
предлагает несколько альтернативных вариантов поведения, подходящих для тестирования.Они включали в себя фиксированный момент времени, измененные каденции и настройку с текущего момента.
Передайте один из этих Clock
объектов различным методам в классах java.time для тестирования.
PST
не является часовым поясом.Укажите правильное имя часового пояса в формате Continent/Region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
.Никогда не используйте 2-4 буквенные сокращения, такие как EST
или IST
, поскольку они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
Создайте конкретный момент, который вы планируете для тестирования.
LocalDate ld = LocalDate.of( 2019 , 2 , 11 ) ;
LocalTime lt = LocalTime.MIN ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
zdt.toString (): 2019-02-11T00: 00-08:00 [America / Los_Angeles]
Для вызова Clock.fixed
требуется Instant
, момент в UTC.Мы можем отрегулировать от нашего зонированного значения до UTC, извлекая Instant
.Тот же момент, та же точка на временной шкале, другое время настенных часов.
Instant instant = zdt.toInstant() ;
instant.toString (): 2019-02-11T08: 00: 00Z
Укажите Clock
, который всегда сообщает текущий момент как этот конкретный момент, без увеличения.
Clock clock = Clock.fixed( instant , z ) ;
clock.toString (): FixedClock [2019-02-11T08: 00: 00Z,America / Los_Angeles]
Добавление фиксированных часов в качестве зависимости.
Instant now = Instant.now( clock ) ; // Tell me a lie.
now.toString (): 2019-02-11T08: 00: 00Z
См. Этот код, запущенный в режиме реального времени на IdeOne.com .
JDBC 4.2
Если вы создавали java.sql.Timestamp
для использования с базой данныхвместо этого используйте java.time классы.Начиная с JDBC 4.2 , мы можем обмениваться java.time объектами с базой данных.
Ваш JDBC-драйвер может иметь дополнительную поддержку Instant
.
myPreparedStatement.setObject( … , instant ) ; // Storing data.
Instant instant = myResultSet.get( … , Instant.class ) ; // Retrieving data.
Ваш драйвер должен поддерживать OffsetDateTime
.
myPreparedStatement.setObject( … , instant.atOffset( ZoneOffset.UTC ) ) ; // Storing data.
OffsetDateTime odt = myResultSet.get( … , OffsetDateTime.class ) ; // Retrieving data.
Настройка на часовой пояс .
ZonedDateTime zdt = odt.atZoneSameInstant( 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 .