将1970年之前的日期字符串转换为MySQL中的时间戳

问题描述 投票:15回答:8

不是很好的标题,所以我道歉。

出于某种原因,(我不是那个人,我离题了)我们有一个表结构,其中日期的字段类型是varchar。 (奇)。

我们有一些日期,例如:

1932-04-01 00:00:00 and 1929-07-04 00:00:00

我需要做一个查询,将这些日期字符串转换为unix时间戳,但是,如果你转换1970年以前的日期,它将返回0。

有任何想法吗?

非常感谢!

编辑:错误的日期格式。哎呀。

mysql
8个回答
17
投票

啊哈!我们找到了解决方案!

要做的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


4
投票

我已经改编了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

2
投票

将这些日期字符串转换为unix时间戳

传统的Unix时间戳是自1970年1月1日以来的无符号整数计数秒,因此不能代表之前的任何日期。


2
投票

根据您用于表示时间戳的系统,您最多会得到混合结果。

来自wikipedia

关于Unix time_t是应该签名还是未签名,最初存在一些争议。如果未签名,其未来的范围将加倍,推迟32位溢出(68年)。然而,它将无法代表1970年之前的时间。当被问及这个问题时,Dennis Ritchie说他没有深入思考这个问题,但他认为能够代表他一生中的所有时间。会好的。 (Ritchie的诞生,在1941年,大约是Unix时间-893 400 000.)共识是time_t签署,这是通常的做法。 QNX操作系统版本6的软件开发平台具有无符号的32位time_t,但旧版本使用了签名类型。

似乎MySQL将时间戳视为无符号整数,这意味着Epoc之前的时间将全部解析为0。

在这种情况下,您始终可以选择实现自己的无符号时间戳类型,并将其用于计算。


2
投票

如果它对您的问题可行,您可以将所有mysql时间换算,比如说100年,然后使用这些调整后的时间戳或重新计算负时间戳值。

正如一些人所说,确保你的系统使用64位代表时间戳,否则你将遇到2038年的问题。


1
投票

我没有尝试过上面的解决方案,但如果您无法以时间戳的形式从MySQL数据库中检索日期值,那么也可以尝试此操作

SELECT TIMESTAMPDIFF(第二,FROM_UNIXTIME(0),'1960-01-01 00:00:00');


0
投票

获得最大值范围+/-明智地在您的生日区域使用此查询,在我的情况下“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

-2
投票

使用日期而不是时间戳。日期将解决您的问题。检查这个link

© www.soinside.com 2019 - 2024. All rights reserved.