tl; dr
- A
DATE
столбец в базе данных, соответствующей стандарту SQL, такой как Postgres, хранит только дату, время и зону. - Используйте
LocalDate
для значения только для даты, без времени и зоны. - Чтобы получить
LocalDate
из Instant
, укажите время настенных часов, используемое людьмиопределенного региона (часового пояса), по которому вы хотите определить дату. - Если вы хотите сохранить момент (представленный объектом
Instant
), используйте стандартный тип SQL TIMESTAMP WITH TIME ZONE
вместо DATE
.
Подробности
Instant
в UTC
Объект Instant
представляет момент в UTC , всегда в UTC.Другими словами, момент с смещением от UTC равен нулю часов-минут-секунд.
Для определения даты требуется часовой пояс
Получение даты из *Поэтому для 1034 * требуется часовой пояс (ZoneId
).Момент после полуночи в Париже Франция - это новая дата, скажем, 23 , в то время как в Монреале-Квебеке она все еще «вчера» 22-го .В любой момент времени дата меняется по всему земному шару в зависимости от зоны.
Поэтому, если вы имели в виду дату, показанную в Квебеке, укажите часовой пояс "Америка / Монреаль".
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Вы сказали, что столбец вашей базы данных имеет тип DATE
. В Postgres, как и в стандарте SQL, это означает значение только для даты, без времени суток и без часового пояса.
Чтобы сохранить только дату, без времени суток и без часового пояса, извлеките LocalDate
. Слово «местный» означает любой населенный пункт или все населенных пунктов, но не какой-либо одной конкретной местности.
LocalDate ld = zdt.toLocalDate() ;
JDBC 4.2
Обменяйте LocalDate
через заполнитель в подготовленном выражении.
myPreparedStatement.setObject( … , ld ) ;
Извлечение:
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
Дата сохранена, дата извлечена
как она будет переведена снова, когда я буду читать из базы данных?
Будет ли этобыть:
21.02.2019 00: 00: 00.000 или…
Этот вопрос не имеет смысла. Когда вы читаете DATE
с SQL-стендаArd-совместимая база данных, такая как Postgres, вы получаете дату, только дату - без времени и без часового пояса.
Если вы храните LocalDate
значения 2019-02-21
в DATE
столбец, вы получите то же самое: a LocalDate
значения 2019-02-21
.
Первый момент дня
Если вы хотите добавить время дня для первого моментадня, пусть java.time определит это для вас.В некоторые даты в некоторых часовых поясах день не начинается в 00:00:00, а может начинаться в 01:00: 00.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ; // Returns a `ZonedDateTime` object set to the first moment of the day as seen on that date in that time zone. May or may not be the time 00:00:00.
UTC
Если вы хотите извлечь дату из вашего Instant
, используя UTC в качестве часового пояса, что означает смещение от UTC, равное нулю часов, минут и секунд, используйте класс OffsetDateTime
с константой * 1106.*ZoneOffset.UTC
.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
LocalDate ld = odt.toLocalDate() ;
myPreparedStatement.setObject( … , ld ) ;
О java.time
java.time *Платформа 1120 * встроена в Java 8 и более поздние версии.Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
и & SimpleDateFormat
.
Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .
Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на java.time классы.
Вы можете обмениваться java.time объектами напрямую с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Вы можете найти здесь несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и more .