从FROM_UNIXTIME转换负值

时间:2012-07-20 22:06:12

标签: mysql

我一直在尝试将我的数据库中的出生日期转换为DATE FORMat,但我面临的问题是在DOB字段中有一些负值,当我从在线检查FROM_UNIXTIME calclator然后它给出不同的结果,如果我检查它与FROM_UNIXTIME(-957632400)然后它总是为负值返回NULL。 KIndly让我知道如何从诸如-957632400

之类的UNIX格式获取日期格式

2 个答案:

答案 0 :(得分:10)

我们可以这样做:

FROM_UNIXTIME(0) + INTERVAL -957632400 SECOND

FROM_UNIXTIME函数受TIMESTAMP数据类型的允许范围限制,该数据类型是标准的32位无符号int范围1970-01-01至2038-01-something。其他软件已更新为支持64位有符号整数,但MySQL尚未提供该功能(至少不在5.1.x中)。

MySQL中的解决方法是避免使用TIMESTAMP数据类型,而是使用DATETIME数据类型,当我们需要更大的范围时(例如1970年1月1日之前的日期)。

我们可以使用DATE_ADD函数从1970年1月1日减去秒数,如下所示:

SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)

N.B。您可能需要考虑时区"抵消"来自UTC进行这些类型的计算。 MySQL将把DATETIME值解释为在当前MySQL会话的time_zone设置中指定,而不是UTC(time_zone = '+00:00'


随访:

问:好的,意味着如果我们选择以下日期' 1970-01-01 00:00:00'然后负值保存在数据库中,否则它将是正数。对? - 柔软的基因

A:呃,没有。如果您在1970年1月1日之前选择日期/日期时间值,MySQL将在1970年1月1日之前返回DATE或DATETIME值。如果您在1970年1月1日之前存储DATE或DATETIME值,那么MySQL将在Jan 1之前存储DATE或DATETIME值,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没有必要在1970年1月1日之前将日期值表示为负整数,因此我们不应该做出假设。 (但是,如果我们正在研究MySQL的存储引擎,我们真的只关心这个细节级别。)

答案 1 :(得分:1)

从DATETIME到unix时间戳:

SELECT DATE_ADD(convert_tz(FROM_UNIXTIME(0), @@session.time_zone,'+00:00'), INTERVAL -410914391 SECOND);

从时间戳到DATETIME:

inputNode