tl; dr
String sql = "SELECT CURRENT_TIMESTAMP ;
…
OffsetDateTime odt = myResultSet.getObject( 1 , OffsetDateTime.class ) ;
Избегайте зависимости от ОС хоста или JVM для часового пояса по умолчанию
Я рекомендую вам написать весь свой код, чтобы явно указать желаемый / ожидаемый часовой пояс. Вам не нужно зависеть от текущего часового пояса JVM по умолчанию. И имейте в виду, что текущий часовой пояс JVM по умолчанию может измениться в любой момент во время выполнения с любым кодом в любом потоке любого вызываемого приложения TimeZone.setDefault
. Такой вызов немедленно влияет на все приложения в этой JVM.
java.time
Некоторые другие ответы были правильными, но теперь устарели. Ужасные классы времени и даты, связанные с самыми ранними версиями Java, были ошибочными, написанными людьми, которые не понимали сложности и тонкости обработки даты и времени.
Унаследованные классы даты и времени были заменены классами java.time, определенными в JSR 310.
Чтобы представить часовой пояс, используйте ZoneId
. Чтобы представить смещение от UTC, используйте ZoneOffset
. Смещение - это просто количество часов, минут и секунд вперед или назад от нулевого меридиана. Часовой пояс - это гораздо больше. Часовой пояс - это история прошлых, настоящих и будущих изменений смещения, используемого людьми определенного региона.
Мне нужно принудительно установить любые операции, связанные со временем, в GMT / UTC
Для смещения нуля часов-минут-секунд используйте константу ZoneOffset.UTC
.
Instant
Чтобы зафиксировать текущий момент в формате UTC, используйте расширение Instant
. Этот класс представляет момент в формате UTC, всегда по определению в формате UTC.
Instant instant = Instant.now() ; // Capture current moment in UTC.
ZonedDateTime
Чтобы увидеть тот же самый момент через время на настенных часах, которое используют жители определенного региона, настройте часовой пояс. Тот же момент, та же точка на временной шкале, другое время на настенных часах.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
База данных
Вы упоминаете базу данных.
Чтобы получить момент из базы данных, ваш столбец должен иметь тип данных, близкий к стандарту SQL TIMESTAMP WITH TIME ZONE
. Получите объект, а не строку. В JDBC 4.2 и новее мы можем обмениваться объектами java.time с базой данных. OffsetDateTime
Требуется JDBC, в то время как Instant
и не ZonedDateTime
являются обязательными.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Я предполагаю, что в большинстве баз данных и драйверов вы получите момент, который отображается в формате UTC. Но если нет, вы можете настроить любой из двух способов:
- Извлеките
Instant
: odt.toInstant()
- Отрегулируйте от заданного смещения до смещения нуля: OffsetDateTime odtUtc = odt.withOffsetSameInstant (ZoneOffset.UTC); `.
О 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.*
занятиях.
Где взять классы java.time?