【问题标题】:MySQL from_unixtime after 2038-01-19?2038-01-19 之后的 MySQL from_unixtime?
【发布时间】:2015-08-04 14:06:12
【问题描述】:

我们将日期存储为 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-timestamp。然而,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 as 参数。

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


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

【问题讨论】:

  • 有什么理由不将数据类型更改为datetime
  • @juergend 是的,不幸的是,数据是由我们无法更改的应用程序的一部分创建的。 (第三方库)
  • 您是否尝试将时间戳列的数据类型更改为bigint
  • 这个有一个10岁的bug/feature request
  • 是的,但您可能需要等到 2037 年才能使用它:)

标签: mysql timestamp


【解决方案1】:

一种解决方法可能是使用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
...

如果有的话,应该尽量减少对性能的影响。

【讨论】:

  • 它似乎解决了这个问题,直到我偶然发现这个(GMT+1 时区):SELECT FROM_UNIXTIME( 1469230446 ) make: 2016-07-23 01:34:06 @ 987654325@ make: 2016-07-23 00:34:06 有什么想法吗?
  • @TamásMárton,使用带有适当偏移量的CONVERT_TZ。 Unix-Time 始终是 UTC。 DATE_ADD 正在使用您的时区 GMT+1,因此您需要解决此问题。
  • 谢谢,将客户端时区设置为“+00:00”确实解决了问题。
  • @TamásMárton 这也是一个选项。 (我也更喜欢让“服务器”在 UTC-Timezone 中运行,无论它实际部署在哪里)
  • 是的,我完全同意。不幸的是,这是一个具有配置限制的共享虚拟主机(:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 2013-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多