我一直在尝试将出生日期从我的数据库转换为 DATE FORMat,但我面临的问题是 DOB 字段中有一些负值,当我从在线 FROM_UNIXTIME 计算器中检查时,它会给出不同的结果,如果我检查它与 FROM_UNIXTIME(-957632400)
然后它总是为负值返回 NULL 。请告诉我如何从 -957632400 等 UNIX 格式中获取日期格式
最佳答案
我们可以这样做:
FROM_UNIXTIME(0) + INTERVAL -957632400 SECOND
FROM_UNIXTIME
函数受限于 TIMESTAMP
数据类型的允许范围,这是标准的 32 位无符号整数范围 1970-01-01 到 2038-01 -某物。其他软件已更新为支持 64 位有符号整数,但 MySQL 尚未提供该功能(至少在 5.1.x 中没有)。
MySQL 中的解决方法是避免使用 TIMESTAMP
数据类型,当我们需要更大的范围时(例如,1970 年 1 月 1 日之前的日期),请改用 DATETIME
数据类型。
我们可以使用 DATE_ADD
函数从 1970 年 1 月 1 日减去秒数,如下所示:
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
注意在进行这些类型的计算时,您可能需要考虑 UTC 的时区“偏移量”。 MySQL 会将 DATETIME 值解释为在当前 MySQL session 的 time_zone
设置中指定,而不是 UTC (time_zone = '+00:00'
)
跟进:
问: 好的,意思是如果我们选择低于“1970-01-01 00:00:00”的日期,那么负值将保存在数据库中,否则它将是正值。正确的? – 软基因
答: 呃,没有。如果您选择 1970 年 1 月 1 日之前的日期/日期时间值,则 MySQL 将返回 1970 年 1 月 1 日之前的 DATE 或 DATETIME 值。如果您存储 1970 年 1 月 1 日之前的 DATE 或 DATETIME 值,则 MySQL 将存储 1 月 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 开发存储引擎,我们真的只会关心这个级别的细节。)
关于mysql - 从 FROM_UNIXTIME 转换负值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26325099/