Преобразование отрицательных значений из FROM_UNIXTIME
Я пытался преобразовать дату рождения из моей БД в формат DATE FORMat, но я столкнулся с проблемой того, что в полях DOB есть некоторые отрицательные значения, которые при проверке из онлайн-калькулятора FROM_UNIXTIME дают другой результат, и если я проверяю его с помощью FROM_UNIXTIME(-957632400)
тогда он всегда возвращает NULL для отрицательных значений. Пожалуйста, дайте мне знать, как я могу получить формат даты из такого формата UNIX, как -957632400
2 ответа
FROM_UNIXTIME
функция ограничена допустимым диапазоном для TIMESTAMP
тип данных, который является стандартным 32-битным диапазоном без знака с 1970-01-01 по 2038-01-что-то. Другое программное обеспечение было обновлено для поддержки 64-битных целых чисел со знаком, но MySQL еще не обеспечивает эту функциональность (по крайней мере, в 5.1.x).
Обходной путь в MySQL - избегать использования TIMESTAMP
тип данных и использование DATETIME
вместо этого, когда вам нужен больший диапазон (например, даты до 1 января 1970 года).
Вы можете использовать функцию DATE_ADD для вычитания секунд с 1 января 1970 года, например:
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
NB Вам, вероятно, придется учитывать "смещения" часового пояса от UTC при выполнении этих типов вычислений. MySQL будет интерпретировать значения DATETIME, как указано в time_zone
установка текущего сеанса MySQL, а не UTC (time_zone = '+00:00'
)
СЛЕДОВАТЬ ЗА:
Q: Хорошо, значит, если мы выберем даты ниже '1970-01-01 00:00:00', то отрицательное значение сохранится в БД, иначе оно будет положительным. Правильно? - мягкий гений
A: Эээ, нет. Если вы выберете значения даты / даты и времени до 1 января 1970 года, MySQL вернет значения DATE или DATETIME до 1 января 1970 года. Если вы сохраните значения DATE или DATETIME до 1 января 1970 года, MySQL сохранит значение DATE или DATETIME до 1 января 1970 года. 1970, в пределах допустимого диапазона, поддерживаемого этими типами данных. (что-то вроде 0001-01-01 до 9999?)
Если вам нужно хранить действительно большие положительные и отрицательные целые числа в базе данных, вы, скорее всего, сохраните их в столбце, определенном как BIGINT
,
Внутреннее представление столбца DATE требует 3 байта памяти, а DATETIME требует 8 байтов памяти (до версии MySQL 5.6.4. Внутреннее представление и хранение значений DATE и DATETIME изменено в 5.6.4)
Так что нет, MySQL не хранит значения даты до 1970 года как "отрицательные целые числа".
Если немного подумать, MySQL может реализовать любой механизм хранения, какой захочет. (И каждый механизм хранения может сериализовать это представление на диск так, как ему хочется.)
Почему 3 байта на дату?
Один из вариантов, который есть в MySQL (и я не представляю, что это так), может состоять в том, чтобы разбить дату на составляющие года и месяца.
Представление целочисленных значений в диапазоне - требует -
0 - 9999 -
14 бит0 - 12 -
4 бита0 - 31 -
5 бит
Это в сумме 23 бита, что удобно вписывается в 3 байта. Это просто демонстрирует, что MySQL не обязательно представлять значения даты до 1 января 1970 года как отрицательные целые числа, поэтому мы не должны предполагать, что это так. (Но мы действительно были бы обеспокоены таким уровнем детализации, если бы работали над механизмом хранения для MySQL.)
От DATETIME до метки времени Unix:
SELECT TIMESTAMPDIFF(SECOND, FROM_UNIXTIME(0), '1956-12-24 01:06:49');
От метки времени до даты
SELECT DATE_ADD(convert_tz(FROM_UNIXTIME(0), @@session.time_zone,'+00:00'), INTERVAL -410914391 SECOND);