【问题标题】:Convert unix epoch timestamp to TSQL datetime将 unix 纪元时间戳转换为 TSQL 日期时间
【发布时间】:2013-01-08 13:56:58
【问题描述】:

我只找到了one similar question,但对于 MySQL。

我正在开发 Web 服务,并且必须查询数据库(MS SQL 服务器)。由于我无法得到正确的结果,我决定通过 SQL 客户端测试查询。 Web 服务使用 Hibernate 访问数据库,所有时间值始终表示为长值(unix 纪元时间)。为了测试它,我需要将 unix 时间戳转换为 TSQL 时间戳。这是我想出的:

select dateadd(ms,123,'1970-01-01 00:00:00.0');

哪个输出:

1970-01-01 00:00:00.123

但是,我的实际数据有点大

select dateadd(ms,1359016610667 ,'1970-01-01 00:00:00.0');

哪个输出:

Error code 0, SQL state 22001: Data truncation
Error code 8115, SQL state 22003: Arithmetic overflow error converting expression to data type int.

所以,我尝试了:

select dateadd(ms,CAST (1359016610667 AS BIGINT) ,'1970-01-01 00:00:00.0');

输出完全相同的错误。为了安全起见,我试过了:

select CAST (1359016610667 AS BIGINT) 

哪个输出:

1359016610667

我确保 java long 等同于 TSQL bigint - 它们都是 8 B 长。重读dateadd() documentation 发现以下内容:

DATEADD(日期部分,数字,日期)
....
号码
是一个表达式,可以解析为添加到日期的日期部分的 int。用户自定义变量有效。

如果我理解正确,这意味着这种方法不能用于将 unix 时间戳转换为 TSQL 时间戳,这是,原谅我的语言,但只是愚蠢的。

我的问题是:

  • 我对这种情况的解释是否正确?
  • 是否有任何其他单线可以在 TSQL 中进行此转换?

PS
修改日期参数 ('1970-01-01 00:00:00.0') 是不可接受的解决方案。我正在调试,我不想重新计算毫秒数:)

【问题讨论】:

  • 投反对票的人能否解释一下为什么这个问题被投反对票?
  • 大声笑,又来了?好吧,看上面的评论...

标签: tsql unix-timestamp epoch


【解决方案1】:

很简单,先添加整天,然后添加剩余的毫秒。一天有 86,400,000 毫秒。

declare @unixTS bigint
set @unixTS = 1359016610667


select dateadd(ms, @unixTS%(3600*24*1000), 
    dateadd(day, @unixTS/(3600*24*1000), '1970-01-01 00:00:00.0')
)

结果是2013-01-24 08:36:50.667

【讨论】:

  • 结果是 2013-01-24 08:36:50.667,但是在哪个时区呢? UTC?
  • @luisdev 如果输入的 unix 时间戳采用 UTC,则结果将采用 UTC。如果不是,那就不是。
【解决方案2】:

这对于那些漫长的时代来说应该是完美的。

SELECT DATEADD(SECOND, 1359016610667 / 1000, '19700101 00:00')

【讨论】:

  • 当 SQL 尝试将日期转换为“2099 年 12 月 31 日”时,这种仅添加秒数而不是毫秒数和天数(来自 @ben 的答案)的方法会导致算术溢出错误添加到 int 中的秒数。
猜你喜欢
  • 2018-08-03
  • 2021-02-19
  • 2014-01-25
  • 2016-09-15
  • 2018-12-27
  • 2020-10-19
  • 2018-10-01
  • 2013-04-02
相关资源
最近更新 更多