тл; д-р
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 Підручник . І шукайте в Stack Overflow багато прикладів та пояснень. Специфікація - JSR 310 .
Проект Joda-Time , який зараз перебуває в режимі обслуговування , радить перейти на класи java.time .
Ви можете обмінювати об'єкти java.time безпосередньо зі своєю базою даних. Використовуйте драйвер JDBC, сумісний з JDBC 4.2 або новішою. Не потрібні рядки, не потрібні java.sql.*
класи.
Де отримати класи java.time?