Фильтрация поля где хранится дата в формате timestamp()

Yoskaldyr

"Спамер"
Партнер клуба
@AnrDaemon Из unixtimestamp в дату конвертация пройдет всегда для всех дат юникс эпохи (хотя да, может быть одинаковая дата для разных юникстаймстампов), но не наоборот. Т.к. иногда одна и та же дата может быть как валидной, так и нет.
Я говорил о проблеме когда в базу записали данные, а после смены настроек таймзоны, она стала невалидная.

Т.е. еще раз повторюсь надо понимать где можно юзать datetime/timestamp, а где лучше дату в юникстаймстамп.
 

fixxxer

К.О.
Партнер клуба
Кстати, я раньше не задумывался, щас посмотрел - конкретно постгресовая реализация timestamptz хранит просто юникстайм.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Вы обсуждаете как хранить временную метку и делать по ней выборку.
Хранить и проверять. Не как рассчитывать, а в int хранить, или в datetime.

С таким подходом можно цены во float хранить, ничего при хранении и сравнении не потеряется.

Форматы времени - не кодировки кириллицы, их не от упоротости все одновременно используют. Каждый формат нужен в каких-то случаях.
У mysql свой путь - а php создан чтобы умирать, пальцем в небо.
Из unixtimestamp в дату конвертация странная - а вообще зачем она может быть нужна? С новым годом поздравить - нет, не надо ничего конвертировать. Просто добавь поле с указанием временной зоны.
Дата не может быть и валидной, и невалидной, потому что дата - это объективная реальность. Откуда ты ее невалидную возьмешь? Пользовательский ввод? Сам молодец.
Если нужно записать время события - пиши в UTC. Если нужно запустить что-то по таймеру - создавай задачу в шине, и проверяй статус задачи.
Выбрать все записи продаж за сутки - TZ не влияет, за час - переводи в UTC со сдвигом.
Чисто теоретически можно обсудить расчет по иранскому календарю.
 

Yoskaldyr

"Спамер"
Партнер клуба
@grigori Да все это понятно. Но дата может быть невалидной - например тот же DATETIME с собственным виденьем от мускуля.
Я написал, что выбирать надо исходя из задач, а не всегда юзаем одно или другое. И там и там есть нюансы, на которые почти все программисты тупо забивают
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
дай пример невалидного DATETIME с собственным виденьем от мускуля
 

Yoskaldyr

"Спамер"
Партнер клуба
бинарное представление DATETIME у мускуля (отсюда):
DATETIME: Eight bytes: A four-byte integer for date packed as YYYY×10000 + MM×100 + DD and a four-byte integer for time packed as HH×10000 + MM×100 + SS
Т.е. фактически там может лежать что угодно.
Но уже давно мускуль не дает записать неправильную дату. Обойти можно только спец флагами при запуске, но кто это будет делать и кому это нужно?

Возьмем такую дату и время как 28 март 2021 3:30. Это невалидное время для часового пояса Украины, т.к. перевод часов происходит как раз 28 март 2021 в 3:00 на 1 час вперед (отсюда). Но это время полностью валидно для Гринвича.
И самый типичный пример - дамп базы с такими датами, сделанный на сервере с UTC, нельзя поднять на сервере UTC +2. Ну и еще целый набор глюков из-за неправильно работающих запросов. Самая веселуха когда база на отдельном сервере/в отдельном контейнере с другим TZ

Аналогично с переводом времени назад. Здесь ситуация наоборот - фактически время разное, но в базу будет писаться одинаковые значения в течении часа. Это уже привет тем кто любит использовать DATETIME для полей типа created_at и когда им важен порядок сортировки по этим полям. Только вот забывают что на сервере БД не обязательно будет UTC.
 

Yoskaldyr

"Спамер"
Партнер клуба
И самые веселые баги это когда используется DATETIME в будущем и например изначально перевода часов для конкретной TZ не планировалось или планировалось на другой день, а потом поменяли и соответственно изменились свойства конкретной TZ и валидное значение DATETIME после обновление системы стало невалидным.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
тебе можно писать продолжение "Сказок Венского леса" :)

RTFM:
MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval.
Когда клиент указал в переменной time_zone значение "EEST" - MySQL пересчитает из UTC, и отдаст правильное время.
Когда time_zone для клиента не указана - MySQL сам не сменит значение переменной default_time_zone.

В каком чудесном usecase в приложении может появиться 28 март 2021 3:30 в зоне EEST?
 
Последнее редактирование:

Yoskaldyr

"Спамер"
Партнер клуба
@grigori Читаем плиз внимательно. тип поля DATETIME, а не TIMESTAMP.
сам datetime вообще ничего не знает ни о каких TZ и ни о TZ приложения, но мускуль при записи проверяет валидность даты исходя из системных TZ/локали где крутится база. При использовании магии в datetime можно вообще запихнуть мусор.
И если приложение работает с несколькими TZ и хочет писать DATETIME (а TZ например отдельно), то TZ системы где крутится база должна быть UTC
и невалидная дата может получиться легко, даже при полностью валидном коде но с будущими датами. Неизвестно как в будущем изменят локаль (свойства TZ) и валидная дата для какой-то локали, может стать невалидной. Это при условии что база крутится на системе с этими локалью/TZ

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

Я здесь в срачи не вступаю пока все не перепроверил и точно не знаю и уверен на 100%. Но весело смотреть как любят читать по диагонали пропуская много из написанного.. А насчет типа datetime это реально головная боль потому что на это я наступал при поддержке абсолютно различных продуктов (и массмаркет и полный самодел). И косяки при переводе времени возникали у 100% продуктов независимо от языка разработки. И баги различные от битой сортировки, что нестрашно, до полностью неработающего продукта в течении часа. Просто вообще никто никогда не задумывается о смене часовых поясов и о переводе времени, все тупо юзают datertime, а не timestamp или тот же int.
 

fixxxer

К.О.
Партнер клуба
Исторически timestamp в mysql был специальным типом, в котором вообще по дефолту писался текущее время, null было нельзя, и вроде даже в мануале на старые версии не рекомендовалось его использовать для чего-либо другого кроме автоматического current timestamp.

С тех пор уже все поменялось, но старые привычки никуда не деваются.
 

Yoskaldyr

"Спамер"
Партнер клуба
@fixxxer timestamp можно хоть как-то использовать, а что делать с datetime, который слабо применим в мультиTZ приложениях? Постоянный контроль чтобы база крутилась под UTC это такое себе "удовольствие"
 
Последнее редактирование:

AmdY

Пью пиво
Команда форума
@fixxxer timestamp можно хоть как-то использовать, а что делать с datetime, который слабо применим в мультиTZ приложениях? Постоянный контроль чтобы база крутилась под UTC это такое себе "удовольствие"
всё везде в utc это наоборот норма и ожидаемое поведение. хочешь часовые пояса, указывай явно.
 

fixxxer

К.О.
Партнер клуба
@fixxxer timestamp можно хоть как-то использовать, а что делать с datetime, который слабо применим в мультиTZ приложениях? Постоянный контроль чтобы база крутилась под UTC это такое себе "удовольствие"
В принципе обычно-то по utc все и сетапится. Неаккуратненько, конечно, но не припоминаю, чтобы из-за этого возникли проблемы, они чаще с кодом аппликейшена, который подразумевает что-нибудь веселое, типа что в сутках всегда 86400 секунд.

Тебе с твоими коробками понятно, что проблема. :)
 

Yoskaldyr

"Спамер"
Партнер клуба
Тебе с твоими коробками понятно, что проблема. :)
Да тут не только с коробками. Куча и самописа и ларавеле и на симфони, да на чем угодно. Просто разработчики ну вообще не думают о том что могут быть переводы часов и не думают как именно хранится этот datetime. Вот тупо ни разу не видел кода где бы datetime не косячил при граничных условиях (переводы часов, смена региона работы сайта и т.д.)
 

Yoskaldyr

"Спамер"
Партнер клуба
и еще насчет utc - не всегда есть возможность выноса базы на отдельный сервер. Т.е. ситуация система в UTC, у пхп прописано например +2, и начинается веселуха, особенно при работе с временем файлов (часто именно когда что-то запускается из под пхп).
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@grigori Читаем плиз внимательно. тип поля DATETIME, а не TIMESTAMP.

и невалидная дата может получиться легко, даже при полностью валидном коде но с будущими датами. Неизвестно как в будущем изменят локаль (свойства TZ) и валидная дата для какой-то локали, может стать невалидной. Это при условии что база крутится на системе с этими локалью/TZ
Я не просто читаю, я уже 2 раза спрашивал: покажи как возникнет невалиданя дата. "Легко" она не появляется.
Ниоткуда невалидная дата сама не появится. Чтобы записать мусор в datetime должна быть ошибка в приложении. Мы не полагаемся на валидацию пароля на уровне СУБД, почему мы должны полагаться на валидацию даты?

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

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Да тут не только с коробками. Куча и самописа и ларавеле и на симфони, да на чем угодно. Просто разработчики ну вообще не думают о том что могут быть переводы часов и не думают как именно хранится этот datetime. Вот тупо ни разу не видел кода где бы datetime не косячил при граничных условиях (переводы часов, смена региона работы сайта и т.д.)
так все-таки: в базе сама собой может появится невалидная дата при валидации пользовательского ввода, или разработчики не думают про валидацию?

дай пример, когда datetime косячит на переводе часов
 

fixxxer

К.О.
Партнер клуба
Любой datetime в будущем, если он не в utc, а в каком-то региональном часовом поясе, потенциально невалиден :)
 
Сверху