postgresql Дата против Java Мгновенное действие

Предположим, у меня есть поле в приложении Java типа Instant и сохранить его в базе данных PostgreSQL как тип DATE,

Если я сохраню, например, 21.02.2019 14:03:59 будет храниться как 21.02.2019 но как он будет переведен, когда я прочитал из базы данных?

Это случится:

  • 21.02.2019 00:00:00.000 или же
  • 21.02.2019 23:59:59.000?

PS. Я знаю, что я должен использовать Timestamp вместо:)

2 ответа

ТЛ; др

  • DATE Столбец в базе данных, соответствующей стандарту SQL, такой как Postgres, хранит только дату, время и зону.
  • использование LocalDate для значения только для даты, без времени и зоны.
  • Чтобы получить LocalDate из Instant укажите время на часах, используемое людьми определенного региона (часового пояса), по которым вы хотите определить дату.
  • Если вы хотите сохранить момент (как представлено Instant объект), используйте тип стандарта SQL TIMESTAMP WITH TIME ZONE скорее, чем DATE,

подробности

Instant в UTC

Instant Объект представляет момент в UTC, всегда в UTC. Другими словами, момент со смещением от UTC, равным нулю, часам, минутам и секундам.

Для определения даты требуется часовой пояс

Получение даты от Instant поэтому требуется часовой пояс (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, такой как Postgres, вы получаете дату, только дату - без времени и без часового пояса.

Если вы храните LocalDate стоимости 2019-02-21 в DATE столбец, вы получите то же самое: 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. 

универсальное глобальное время

Если вы хотите извлечь дату из вашего Instant используя UTC в качестве часового пояса, то есть смещение от UTC, равное нулю часов, минут и секунд, используйте OffsetDateTime класс с константой ZoneOffset.UTC,

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
LocalDate ld = odt.toLocalDate() ;
myPreparedStatement.setObject( … , ld ) ; 

О java.time

Инфраструктура java.time встроена в 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 и многое другое.

Это зависит от того, как вы читаете это. Instant и SQL DATE не эквивалентны, и я не знаю ни одной надежной библиотеки, которая позволила бы вам читать DATE в Instant, Если вы пишете свой собственный код, который позволяет это, тогда вы можете заставить его заполнять часы, минуты, секунды и миллисекунды любым удобным для вас способом, даже если это не имеет смысла (поэтому реальный ответ на ваш вопрос будет " ни ", если вы явно не пишете код для преобразования java.sql.Date в java.time.Instant).

Если вы разрабатываете программное обеспечение, которое хранит моменты как даты, значит, ваш дизайн имеет недостатки. Либо использовать LocalDate на стороне Java, или TIMESTAMP в базе данных.

Другие вопросы по тегам