Какое смещение используется для демаршализации OffsetDateTime из Postgres timestampTZ? - PullRequest
2 голосов
/ 30 января 2020

Я прочитал отметки времени и часовые пояса в postgresql и понял, что отметка времени TZ сохраняется в качестве отметки времени UT C с любой временной зоной / смещением, преобразованными и потерянными.

Итак, при загрузке JPA / Hibernate Entity с полем OffsetDateTime, связанным с таким полем timestampTZ, откуда берется Offset? Всегда ли он преобразуется в часовой пояс JDB C -Connection?

Это своего рода усечение информации, при котором мы фактически теряем исходную информацию о часовом поясе, поэтому мы возвращаемся к любому часовому поясу JDB * 1013. * -соединение ограничено, и поэтому нам необходимо дополнительно хранить информацию о часовом поясе, если бы нам это было нужно?

Если все вышеперечисленное выполнено, разве это не будет намного яснее / точнее в использовании Instant вместо OffsetBigTime, который представляет UT C -точку во времени точно так же, как timestampTZ? Тогда я должен был бы хотя бы явно применить «надлежащий часовой пояс» в коде, а не применять его «магически» каким-либо DB-соединением ...

1 Ответ

2 голосов
/ 30 января 2020

при загрузке JPA / Hibernate Entity с полем OffsetDateTime, связанным с таким полем timestampTZ, откуда смещение берется из

Пока я не использую JPA или Hibernate ( Я использую прямую JDB C), я ожидаю, что вы получите OffsetDateTime, где смещение равно нулю часов-минут-секунд вперед / позади UT C. Мы можем называть это «UTC» для краткости.

Вы можете убедиться сами. Получите объект OffsetDateTime и вызовите toString. Если полученный текст показывает +00:00 или Z в конце, hat означает смещение нуля.

мы обязаны дополнительно хранить информацию о часовом поясе, если бы нам это было нужно?

Да, если вы заботитесь о часовом поясе или смещении, передаваемом в базу данных, вы должны сохранить эту информацию во втором столбце самостоятельно с помощью собственного дополнительного программирования. По умолчанию Postgres использует предоставленную информацию о зоне или смещении для настройки на UT C, а затем отбрасывает эту информацию о зоне или смещении.

Я ожидаю, что большинству бизнес-приложений все равно, какой была исходная зона или смещение. Имейте в виду, что момент, точка на временной шкале, не изменилась. Только время настенных часов кажется другим. Postgres похоже на человека в Исландии (где UT C - его постоянный часовой пояс, действующий круглый год), получающего звонок от кого-то из Токио или Монреаля. Если оба человека смотрят на часы на своих стенах, человек в Токио видит время дня на несколько часов раньше, чем Postgres человек в Исландии. Человек из Монреаля видит время на часах, висящих на собственной стене, на несколько часов меньше, чем у человека Postgres в Исландии.

Когда вы извлекаете этот объект OffsetDateTime со смещением нуля, вы можете легко настроить любой часовой пояс по вашему желанию.

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

Не было бы намного яснее / точнее использовать Мгновенное

Да !!

По каким-то причинам люди, управляющие API JDB C, в JDB C 4.2 сделали странный выбор, требуя поддержки OffsetDateTime, но не требуют поддержки Instant или ZonedDateTime. Эти два других класса используются намного чаще в большинстве приложений, которые я себе представляю. Так что логика c по своему выбору ускользает от меня.

Ваш драйвер JDB C может поддерживать Instant или ZonedDateTime. Просто попробуйте и посмотрите. API JDB C 4.2 не запрещает такую ​​поддержку; API не упоминает эти типы. Поэтому поддержка Instant или ZonedDateTime является необязательной.

Тогда мне нужно было бы хотя бы явно применить «надлежащий часовой пояс» в коде, а не применять его «магически» каким-либо db-соединением ...

Если вы извлекаете объекты java .time через драйверы, совместимые с JDB C 4.2, я был бы очень удивлен, увидев, что они применяют зону или смещение к полученным значениям. Я ожидаю, что вы получите только OffsetDateTime объекты со смещением нуля. Но я не помню, чтобы его поведение было так или иначе предписано в спецификации. Поэтому всегда проверяйте поведение вашего конкретного драйвера JDB C.

Остерегайтесь того, что получение значений в виде текста или использование других инструментов промежуточного программного обеспечения, таких как PgAdmin, вполне может внедрить некоторую зону или смещение по умолчанию. Несмотря на благие намерения, я считаю это антифункцией, создающей иллюзию определенной зоны, сохраненной в базе данных, когда ее фактически не было.

Какой часовой пояс используется для демаршализации OffsetDateTime из Postgres timestampTZ?

Во-первых, знайте, что смещение - это просто количество часов, минут и секунд вперед или позади основного меридиана. Часовой пояс гораздо больше. Часовой пояс - это история прошлых, настоящих и будущих изменений в смещении, используемом людьми определенного региона.

Так что формулировка вашего названия противоречива. Часовой пояс не связан с OffsetDateTime, поэтому название. Для часового пояса используйте класс ZonedDateTime.

enter image description here

...