java.time
Эта проблема неоднократно освещалась при переполнении стека, поэтому я буду краток. И вы забыли предоставить важную информацию, такую как, какая база данных и какой тип данных столбца, поэтому я не могу дать конкретное решение для кода.
Чтобы извлечь момент из базы данных, используйте OffsetDateTime
.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Чтобы увидеть этот момент через настенные часы, используемые людьми определенного региона (часового пояса), примените ZoneId
, чтобы получить ZonedDateTime
объект.
Обратите внимание, что "ET time" это , а не часовой пояс. Укажите собственное имя часового пояса в формате Continent/Region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
. Никогда не используйте 2-4 буквенные сокращения, такие как EST
или IST
, так как они не истинных часовых поясов, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Для столбцов типа, схожего с стандартом SQL TIMESTAMP WITH TIME ZONE
, многие базы данных перед сохранением вводят значения UTC . Поэтому при получении объект OffsetDateTime
, скорее всего, будет в UTC. Но чтобы быть уверенным, просто извлеките Instant
. Instant
всегда находится в UTC по определению.
Instant instant = odt.toInstant() ; // Adjust to UTC (if not already in UTC).
Если ваш столбец имеет тип, похожий на стандарт SQL TIMESTAMP WITHOUT TIME ZONE
, вы используете неправильный тип для отслеживания момента, определенногоуказать на временной шкале. Вы не знаете, какой часовой пояс был у предыдущих сохраненных значений, потому что любая предоставленная информация о часовом поясе или смещении игнорируется и удаляется из всех входных данных. Так что у вас в руках беспорядок. Вы должны реорганизовать вашу базу данных , чтобы использовать правильный тип. Вы можете попытаться угадать предполагаемый часовой пояс и применить эту зону во время рефакторинга, но вы будете только догадываться.
// Extract old value without zone/offset info.
LocalDateTime ldt = myResultSet.getObject( oldColumn , LocalDateTime.class ) ;
// Guessing this time zone was originally intended.
ZoneId z = ZoneId.of( "America/New_York" ) ;
// Arbitrarily apply the time zone that we assume, but do not truly know, was intended when that date-time was originally stored.
ZonedDateTime zdt = ldt.atZone( z ) ;
OffsetDateTime odt = zdt.toOffsetDateTime() ;
// Store the new value in a new column.
myPreparedStatement.setObject( newColumn , odt ) ;
По завершении удалите старый столбец или переименуйте, чтобы указать, что он больше не должен использоваться.
Ваш драйвер JDBC может обрабатывать ZonedDateTime
. Но спецификация JDBC требует поддержки только для OffsetDateTime
.