MySQL: DATE_SUB / DATE_ADD, который учитывает DST?

Это возвращает 1 (он же TRUE)

SELECT DATE_SUB(NOW(), INTERVAL 24*100 HOUR) = DATE_SUB(NOW(), INTERVAL 100 DAY);

100 дней назад час дня не менялся. Но из-за перехода на летнее время (США) 100 периодов по 24 часа назад на самом деле на час раньше, чем если бы вы считали по дням. Если в приведенном выше заявлении учитывается летнее время, оно вернет 0 или FALSE.

Могу ли я сказать, что нужно учитывать летнее время для данного оператора или сеанса? Я бы предпочел не использовать UNIX_TIMESTAMP, поскольку он отключит все, что происходит после 2038 года.


person 700 Software    schedule 21.04.2011    source источник
comment
Это может быть полезно stackoverflow.com/questions/1646171/ (вряд ли есть лекарство в mysql)   -  person ajreal    schedule 07.09.2011
comment
Мальчик! Сделайте Я бы хотел написать собственный тип данных что работает правильно!   -  person 700 Software    schedule 07.09.2011
comment
Вам нужно будет написать собственную функцию DATE_SUB, которая учитывает DST. Кстати, я бы хотел задушить того, кто придумал этот кошмар летнего времени.   -  person Johan    schedule 07.09.2011
comment
Не могу дождаться, пока 64-битные временные метки unix станут нормальными. y293billionK просто не будет проблемой ...   -  person Marc B    schedule 07.09.2011


Ответы (3)


Как отрезание чего-либо после 2038 года может стать реальной проблемой, если вы можете быть уверены, что 64-битные целочисленные временные метки будут внедряться повсюду, по крайней мере, за 20 лет до этого?

Серьезно, существует так много проблем с типами datetime / timestamp в MySQL, что вы должны стараться избегать их, когда это возможно.

Вы храните много дат после 2038 года?

И почему бы не попробовать использовать PostgreSQL, который имеет гораздо более продвинутую поддержку типов?

person Morg.    schedule 23.09.2011
comment
Ограничение до 2038 года немного усложняет. Например, повторяющиеся события в календаре. Очевидно, 2038 год - не настоящая проблема, но мне нравится делать все правильно, если есть правильный путь. Что касается 4-го абзаца, мы уже используем MySQL, я не думаю, что есть много причин для такого серьезного изменения. - person 700 Software; 23.09.2011

Вам нужно будет создать настраиваемую функцию, примерно так.

DELIMITER $$

CREATE FUNCTION DST(ADatetime DATETIME) RETURNS DATETIME
BEGIN
  DECLARE result DATETIME;
  SET Result = ADatetime;
  IF ADatetime >= startDST AND ADateTime <= endDST THEN 
    result = DATE_SUB(ADatetime, INTERVAL 1 HOUR);
  END IF;
  RETURN result;
END $$

DELIMITER ;
person Johan    schedule 07.09.2011

На самом деле это просто преобразование в UTC и обратно:

 CONVERT_TZ(DATE_SUB(CONVERT_TZ(NOW(),@@session.time_zone,'UTC'), INTERVAL 24*100 HOUR),'UTC',@@session.time_zone);

Предполагается, что у вас есть таблицы часовых поясов, настроенные для использования именованных часовых поясов. Если нет, вы можете использовать «+0: 00» вместо «UTC».

person Garr Godfrey    schedule 27.02.2017
comment
Будьте осторожны с этим ответом, поскольку convert_tz не работает с датами старше эпохи (включая эпоху), а также после 2038 года: jira.mariadb.org/browse/MDEV-10135 - person Buğra Gedik; 18.03.2019