SQL中Unix时间戳转Timestamp:632689920000000000转换求助
哦,这个问题我之前踩过坑!你给出的时间戳632689920000000000根本不是标准的Unix时间戳,它是**.NET DateTime的Ticks值**——也就是从公元1年1月1日00:00:00开始计数的100纳秒间隔数,和Unix时间戳(以1970-01-01为起点的秒/毫秒)完全不是一个体系,这就是你之前用Unix转换逻辑得到奇怪结果的原因。
针对SQL Server的解决方案
首先要明确:.NET Ticks的起点到Unix纪元(1970-01-01 00:00:00 UTC)的固定Ticks差是621355968000000000。我们需要用这个差值来转换:
方法1:用纳秒精度转换
SELECT DATEADD(NANOSECOND, (632689920000000000 - 621355968000000000) * 100, '1970-01-01') AS ConvertedTimestamp;
解释:先计算目标Ticks与Unix纪元Ticks的差值,再乘以100转成纳秒(因为1 Tick=100纳秒),最后用DATEADD基于Unix纪元累加纳秒数。
方法2:转成毫秒精度(更常用)
SELECT DATEADD(MILLISECOND, (632689920000000000 - 621355968000000000) / 10000, '1970-01-01') AS ConvertedTimestamp;
解释:1 Tick=0.0001毫秒,所以差值除以10000得到毫秒数,再用DATEADD累加即可。
两种方法都会得到结果:2005-12-08 00:00:00.000(UTC时间,若你的SQL Server时区不同会自动转换)。
针对MySQL的解决方案
如果是MySQL环境,逻辑类似,只是函数不同:
SELECT FROM_UNIXTIME((632689920000000000 - 621355968000000000) / 10000000) AS ConvertedTimestamp;
解释:1秒=10^7 Ticks,所以差值除以10000000得到Unix时间戳的秒数,再用FROM_UNIXTIME转换为DateTime。
关键提醒
以后碰到这种超长的数字时间戳,先判断是不是.NET Ticks——Unix时间戳哪怕是毫秒级也不会超过19位(2038年之前),而.NET Ticks是18位左右,起点是公元1年,这是核心区别。
内容的提问来源于stack exchange,提问作者Ganesh Pitchai

