Порядок JPA/Hibernate по времени дня Joda не работает правильно в Гонконге

моя проблема в том, что когда я делаю запрос к базе данных с порядком по startTime, где startTime - это время Joda, он возвращает время, начинающееся в 16:00.

Итак, 16:00 — это ровно 8 часов до полуночи, и по совпадению я живу в Гонконге, и это мой часовой пояс, а часовой пояс Гонконга — 8 часов до полуночи.

Мое поле startTime JPA:

@Index(name = "bookingStartTimeIndex")
@Column(name = "start_time")
@Type(type="org.joda.time.contrib.hibernate.PersistentLocalTimeAsTime")
private LocalTime startTime;

Я использую JPA/Hibernate, и мой запрос в основном состоит в том, чтобы выбрать * где:

order by b.startTime asc

Теперь у меня есть объекты со временем с 9 утра до 6 вечера, хранящиеся в этой таблице. Что возвращается из этого «упорядочения по», так это объекты, начинающиеся с 16:00 до 18:00, а затем с 9:00 до 16:00. Так что, похоже, он каким-то образом решил, что 4 часа дня — это полночь.

Это база данных postgresql, когда я смотрю на свою базу данных, столбец имеет тип данных time_without_time_zone.

Итак, как я могу заставить его заказывать объекты в обычном режиме с 9 утра до 6 вечера?


Обходной путь, который я нашел, состоит в том, чтобы перейти на использование PersistentLocalTimeExact, это работает для меня в условиях, которые я упомянул, и решает все проблемы, которые у меня были с 16:00...

@Index(name = "bookingStartTimeNumberIndex") @Column(name = "start_time_number", nullable = true) @Type(type="org.joda.time.contrib.hibernate.PersistentLocalTimeExact") private LocalTime startTimeNumber;


person Phil    schedule 27.12.2011    source источник


Ответы (3)


Это звучит как вопрос представления данных, а не фундаментальная проблема, хотя это немного неясно.

Вы говорите, что для записи в базе данных со временем 0:00 она отображается как 16:00 часов, когда вы возвращаете ее из базы данных? Если это так, то я думаю, что есть некоторая путаница при чтении даты из базы данных, и где-то в расширении Hibernate для Joda Time создается экземпляр LocalTime, предполагая, что время базы данных — UTC, а затем создается экземпляр LocalTime с вашим локальным часовым поясом, таким образом применяя -8 часов смещения.

Как говорит Эрвин, лучше всего хранить часовой пояс в базе данных, а если вы не можете этого сделать, то сохраняйте только даты и/или время в формате UTC.

Я просмотрел сайт Joda Time, и они рекомендуют другое расширение Hibernate, которое лучше поддерживается, чем исходное, которое вы используете.

Вы также можете попробовать поставить точку останова на класс PersistentLocalTimeAsTime и посмотреть, как создается LocalTime.

person SteveD    schedule 27.12.2011
comment
Вообще-то я этого не говорил: storing a timezone in the database is the better way. Тип данных time with time zone не рекомендовать, потому что это неоднозначный тип. Вы, должно быть, неправильно прочитали мою отметку времени, которую я представил как универсальное исправление, для любой возможной путаницы в упорядочении точек во времени (но не гарантируя точного представления). - person Erwin Brandstetter; 27.12.2011

Универсальным решением этой проблемы было бы использование типа данных timestamp вместо времени в таблице. Если информация о дате для вас не имеет значения, вы можете просто выбрать любой фиктивный день, например «2011-11-11 16:00»::метка времени для 16:00. и '2011-11-11 09:00'::timestamp для 9:00.

Или, конечно, есть способы исправить ваш запрос с временем типа данных...

Но обо всем по порядку: может ли ваша первоначальная оценка быть неверной? PostgreSQL никогда не сортирует time without time zone (или только time, что по умолчанию равнозначно) таким образом. Вы правильно ввели время "4pm"? Я подозреваю, что вы ввели «4am» по ошибке, или, может быть, вы преобразовали тип данных в текст перед сортировкой?

Что показывает этот запрос?

SELECT startTime FROM tbl ORDER BY startTime;
person Erwin Brandstetter    schedule 27.12.2011

могу ли я порекомендовать вам вместо этого использовать проект Jadira Usertype (Отказ от ответственности: я являюсь автором Usertype) — я считаю, что проблема, с которой вы столкнулись, обсуждается по следующей ссылке: см. http://blog.jadira.co.uk/blog/2010/5/1/javasqldate-types-and-the-offsetting-problem.html

person Chris Pheby    schedule 08.01.2012