Я работаю над технологическим стеком Java 8, PostgreSQL 9.6 и Hibernate 5.2.17 с веб-службами, использующими Jersey 2.24 и Jackson 2.9.10. Я думаю, что Hibernate - ключевой компонент, связанный с этим вопросом. База данных хранит все даты и время в UT C и является всемирной базой данных. У нас есть пользователи, запускающие веб-приложения в различных часовых поясах, и желательно, чтобы дата и время в веб-службах были отформатированы для их часового пояса, чтобы можно было легко визуально проверять значения. Существуют также вычисления ежедневной статистики, которая должна быть от полуночи до полуночи в запрошенном часовом поясе. В коде используется OffsetDateTime, и типичный вывод веб-службы выглядит следующим образом, где часовой пояс по умолчанию соответствует системному часовому поясу.
"reportTime" : "2020-04-29T09:18:00-06:00"
Я пытаюсь использовать следующий подход, описанный в руководстве Hibernate, чтобы сказать JDB C для использования указанного часового пояса c для вывода, и я предполагаю, что это гарантирует, что JDB C и Hibernate будут использовать один и тот же указанный часовой пояс.
Session session = sessionFactory()
.withOptions()
.jdbcTimeZone( TimeZone.getTimeZone( "UTC" ) )
.openSession();
Большая часть документации, похоже, сосредоточена при обработке часовых поясов для вставок, но при выводе сглаживает часовые пояса. Если я использую следующий код для сеанса, который используется для запроса данных для веб-служб, в выводе ничего не меняется:
Session session = sessionFactory()
.withOptions()
.jdbcTimeZone( TimeZone.getTimeZone( "America/New_York" ) )
.openSession();
Я попытался найти способ распечатать свойства сеанса, чтобы подтвердить, что часовой пояс устанавливается, но безуспешно. Мое обходное решение - обработать выходные экземпляры OffsetDateTime для сброса на другой часовой пояс:
/**
* Set the report time to use a new time zone,
* for the case where a time zone other than the system time zone is requested.
* The actual time does not change, just its ZoneId, which impacts output representation.
* For example, the following are the default output (America/Denver),
* and the output after changing the time zone (America/New_York):
* 2020-04-29T09:18:00-06:00
* 2020-04-29T11:18:00-04:00
* @param zoneId the requested time zone.
*/
public void setReportTimeZoneId ( ZoneId zoneId) {
OffsetDateTime newReportTime = OffsetDateTime.ofInstant(this.reportTime.toInstant(),zoneId);
this.reportTime = newReportTime;
}
Результат, таким образом, аналогичен следующему, что я и хочу:
2020-04-29T23:16:05-04:00
Я бы предпочел полагаться на Hibernate для обработки часового пояса, чтобы можно было избежать дополнительных манипуляций с данными. Мне интересно, работает ли часовой пояс сеанса Hibernate с запросами. В приведенном выше примере время является частью составного идентификатора, но я не понимаю, в чем проблема. Веб-службы доступны только для чтения. Любая помощь приветствуется.