Преобразование строки даты, которая до 1970 года в timestamp в MySQL
Не очень хороший титул, поэтому мои извинения.
По какой-то причине (я не был тем человеком, который сделал это, я отвлекся), у нас есть структура таблицы, где тип поля для даты - varchar. (Нечетные).
У нас есть несколько дат, например:
1932-04-01 00:00:00 and 1929-07-04 00:00:00
Мне нужно сделать запрос, который преобразует эти строки даты в метку времени unix, однако в mySQL, если вы конвертируете дату, которая до 1970 года, она вернет 0.
Любые идеи?
Большое спасибо!
EDIT: неправильный формат даты. по электронной почте Ой.
Ответы
Ответ 1
Ага! Мы нашли решение!
SQL для этого:
SELECT DATEDIFF( STR_TO_DATE('04-07-1988','%d-%m-%Y'),FROM_UNIXTIME(0))*24*3600 -> 583977600
SELECT DATEDIFF( STR_TO_DATE('04-07-1968','%d-%m-%Y'),FROM_UNIXTIME(0))*24*3600 -> -47174400
Это может быть полезно для использования в будущем.
Вы можете протестировать его здесь: http://www.onlineconversion.com/unix_time.htm
Ответ 2
Я адаптировал обходное решение DATEDIFF, чтобы включить время, а не только дни. Я завернул его в сохраненную функцию, но вы можете просто извлечь часть SELECT, если вы не хотите использовать функции.
DELIMITER |
CREATE FUNCTION SIGNED_UNIX_TIMESTAMP (d DATETIME)
RETURNS BIGINT
DETERMINISTIC
BEGIN
DECLARE tz VARCHAR(100);
DECLARE ts BIGINT;
SET tz = @@time_zone;
SET time_zone = '+00:00';
SELECT DATEDIFF(d, FROM_UNIXTIME(0)) * 86400 +
TIME_TO_SEC(
TIMEDIFF(
d,
DATE_ADD(MAKEDATE(YEAR(d), DAYOFYEAR(d)), INTERVAL 0 HOUR)
)
) INTO ts;
SET time_zone = tz;
return ts;
END|
DELIMITER ;
-- SELECT UNIX_TIMESTAMP('1900-01-02 03:45:00');
-- will return 0
-- SELECT SIGNED_UNIX_TIMESTAMP('1900-01-02 03:45:00');
-- will return -2208888900
Ответ 3
преобразовать эти строки даты в unix time stamp
Традиционные временные метки Unix представляют собой число без знака целых секунд, так как с 1 января по 1970 год не может представлять дату до этого.
Ответ 4
В лучшем случае у вас будут смешанные результаты в зависимости от используемой вами системы для представления метки времени.
От wikipedia
Первоначально были некоторые разногласия следует ли Unix time_t быть подписанным или неподписанным. Если без знака, его диапазон в будущем будет удваивается, откладывая 32-битный переполнение (на 68 лет). Однако это тогда будет неспособна представляя времена до 1970 года. Деннис Ритчи, когда его спрашивают об этом вопрос, сказал, что он не думал очень глубоко об этом, но мнение о том, что способность представлять все времена в течение его жизни были бы хороший. (Рождение Ричи, в 1941 году, около времени Unix -893 400 000.) консенсус заключается в том, что время_t должно быть подписано, и это обычная практика. платформа разработки программного обеспечения для версия 6 операционной системы QNX имеет неподписанное 32-битное время_t, хотя более старые версии использовали подписанный тип.
Похоже, что MySQL обрабатывает временные метки как целое число без знака, то есть время до того, как Epoc все решится на 0.
В этом случае у вас всегда есть возможность реализовать свой собственный тип времени без знака и использовать его для ваших вычислений.
Ответ 5
Если это будет возможно для вашей проблемы, вы можете перевести все ваши mysql-времена на, скажем, 100 лет, а затем работать с теми скорректированными метками времени или пересчитать отрицательное значение временной отметки.
Как говорили некоторые, убедитесь, что ваша система использует 64 бита для представления временной метки, иначе вы столкнетесь с проблемой 2038 года.
Ответ 6
Чтобы получить макс. Range +/- используйте этот запрос в поле вашего дня рождения, в моем случае "yyyy-mm-dd", но вы можете изменить его на свои нужды.
select name, (@bday:=STR_TO_DATE(birthday,"%Y-%m-%d")),if(year(@bday)<1970,UNIX_TIMESTAMP(adddate(@bday, interval 68 year))-2145916800,UNIX_TIMESTAMP(@bday)) from people
Ответ 7
Использовать дату вместо временных меток. Дата решит ваши проблемы.
проверьте ссылку