#java #mysql #datetime #timestamp
Вопрос:
У меня есть определенная таблица в mysql с полем refresh_time
Type
as timestamp
.
В моем коде я обновляю refresh_time
поле до будущей даты следующего месяца. Для этого я рассчитываю миллисекунды на дату следующего месяца, используя следующую логику :
periodRefresh = currentTime MyServiceUtils.calculateNoOfDaysInMonth(currentTime)*86400000L;
А затем значение periodRefresh (milliseconds)
, в которое я преобразую java.sql.Timestamp
и передаю его на сторону бд, чтобы удалить поле :
new Timestamp(periodRefresh);
Но произошло то, что текущая дата в бд была 2021-04-03 15:57:13
, и когда была запущена вышеуказанная логика для обновления времени до следующего месяца, в то же время, она обновила время, 2021-05-03 13:57:13
которое на 2 часа меньше, чем ожидалось.
Наш сервер следует часовому поясу UTC, но я вижу, что пользователь был из Австралии, и в тот день (4 апреля 2021 года) в AEST было летнее время. Но даже в этом случае это не добавляет к вышесказанному, как если бы я перешел 2021-04-03 15:57:13 UTC
на AEST, это происходит так же, как 2021-04-03 01:57:13
и переход на летнее время в 3 часа ночи.
Все вышесказанное немного смутило меня следующими вопросами:
- Если я следую часовым поясам UTC, то также влияет
sql.Timestamp
иmysql
может повлиять летнее время? - Как летнее время влияет на моего пользователя в Австралии, когда я следую часовому поясу UTC?
- Даже если бы влияло летнее время, это должно было увеличить/уменьшить время на 1 час, но как в моем случае произошла разница в 2 часа?
Комментарии:
1.
Timestamp
ничего не знает о DST или часовых поясах. По сути, это просто число, выражающее смещение от эпохи. Какое бы программное обеспечение ни отображало его, оно будет интерпретировать его в контексте региона и часового пояса, в котором оно просматривается2. @g00se Итак, когда я проверяю таблицу mysql, время в поле на 2 часа меньше, чем ожидалось. Итак, какова может быть возможная причина этого?
3. mysql имеет внутреннюю логику для экономии дневного света см. dev.mysql.com/doc/refman/8.0/en/time-zone-support.html используйте thqat
4.
MyServiceUtils
что-то не так? Трудно сказать без информации5. @g00se Речь идет не о MyServiceUtils, если вы видите, что это просто указывает количество дней. Но здесь ошибка в часах.
Ответ №1:
В MySQL TIMESTAMP
типы данных всегда хранятся в таблицах в формате UTC. Когда вы помещаете их в базу данных, она сначала переводит их из time_zone
настроек вашего подключения в UTC. И когда вы их извлекаете, это переводит их в другую сторону. Это не относится DATETIME
к типам данных.
Такое TIMESTAMP
поведение удобно, если у вас есть глобальное приложение. Вы можете запросить у каждого пользователя предпочтительный часовой пояс и сохранить его в качестве параметра пользовательских предпочтений.
Если вы возьмете необработанное значение (секунды с момента эпохи UNIX в UTC) TIMESTAMP
и добавите к нему секунды за месяц, полученное значение метки времени может находиться в другом режиме дневного времени. Так что это будет переведено по-другому.
Любой
- выполните обработку меток времени в MySQL, например, с помощью
UPDATE tbl SET periodRefresh = periodRefresh INTERVAL 1 MONTH;
- сделайте все это в своем приложении и
DATETIME
не используйтеTIMESTAMP
типы данных (чтобы избежать перевода часового пояса базы данных или - сделайте все это в своем приложении и используйте
SET time_zone='UTC'
; при каждом подключении.
Комментарии:
1. Под 3-м вариантом вы имели в виду установку time_zone=’UTC’ как @@session.time_zone; ? В качестве часового пояса настройки подключения будет выбрана только временная зона сервера