MySQL from_unixtime 在 2038 年 1 月 19 日之后?

问题描述 投票:0回答:2

我们将日期存储为 unix 时间戳。为了允许用户根据时区设置搜索特定日期,我们在查询中转换该时间戳,以确保搜索“2012-05-03”不会找到上一个/下一个的结果日期取决于用户设置的时区。

即如果日期存储为

2012-05-03 23:00 (UTC)
具有正确时区偏移量的用户搜索
2012-05-04
应该会找到此条目。

目前是这样完成的:

CONVERT_TZ(FROM_UNIXTIME(`javaTimeStampColumn`/1000),'+00:00','+00:00')

在哪里。偏移量根据用户时区设置。

我们目前面临的问题:Java 成功地将

2038
年之后的日期存储为 unix 时间戳。然而,MySQL 方法
from_unixtime
不支持任何大于
2147483647
的值转换,因为它的整数类型限制:

SELECT FROM_UNIXTIME(2147483647); //2038-01-19 04:14:07

SELECT FROM_UNIXTIME(2147483648); //null

MySQL服务器本身是64位的,但是ofc。

FROM_UNIXTIME
需要接受一个 long 作为参数。

我现在找不到合适的替代品,有什么提示吗?


我们可以。将时间戳加载为 Long 并在应用程序中处理它 - 但是对于 lazylaoding,我们还需要能够在查询期间正确转换它。

mysql timestamp
2个回答
8
投票

解决方法可能是使用

DATE_ADD
,但我不确定它的性能表现如何:

SELECT DATE_ADD(FROM_UNIXTIME(0), INTERVAL 2147483647 SECOND); //2038-01-19 04:14:07
SELECT DATE_ADD(FROM_UNIXTIME(0), INTERVAL 2147483648 SECOND); //2038-01-19 04:14:08
...
SELECT DATE_ADD(FROM_UNIXTIME(0), INTERVAL 4147483647 SECOND); //2101-06-06 07:47:27

所以现在我正在使用

...
CASE 
  WHEN `javaTimeStampColumn` > 2147483647 THEN
    CONVERT_TZ(DATE_ADD(FROM_UNIXTIME(0), INTERVAL `javaTimeStampColumn`/1000 SECOND),'+00:00','+00:00')
  ELSE  
    CONVERT_TZ(FROM_UNIXTIME(`javaTimeStampColumn`/1000), '+00:00','+00:00')
END as ts
FROM table
...

这应该最大限度地减少对性能的影响(如果有的话)。


0
投票

看起来 MySQL 的 Epochalypse 已增加到 Jan 18 3001, 3:59:59pm

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