我有bigInt:635307578922100000
我需要转换为DateTime
。
我尝试过几种方法:
SELECT
DATEADD(S, CONVERT(bigint,635307578922100000) / 1000, CONVERT(DATETIME, '1-1-1970 00:00:00'))
和
SELECT
DATEADD(ms, 635307578922100000 / 86400000, (635307578922100000 / 86400000) +25567)
虽然我发现上面的代码与bigInts
类似:1283174502729
,但是我的bigInt会出现以下错误:
Msg 8115 ...将表达式转换为数据的算术溢出错误 输入日期时间。
有没有人知道如何解决它?
答案 0 :(得分:3)
我认为它是蜱(产量2014-03-18 16:44:52.210)。这是解决方案:
SELECT DATEADD(
MILLISECOND,
FLOOR(((635307578922100000-599266080000000000)%(10000000*60))/10000),
DATEADD(
MINUTE,
FLOOR((635307578922100000-599266080000000000)/(10000000*60)),
'01-01-1900'))
此神奇值599266080000000000是在PowerShell中计算的0001-01-01和1900-01-01之间的刻度数,如下所示:
([DateTime]::Parse('1900-01-01')-[DateTime]::MinValue).Ticks
转换是必需的,因为DATEADD不能使用bigint(需要int)。 SQL Server DateTime也限于1753年1月1日。
答案 1 :(得分:3)
以下是一些可以计算bigint到日期时间的计算。
SELECT
tick.value
-- Subtrack the amount of ticks for 1900-01-01 and divide that number by the ticks in 1 day.
-- Then cast or convert that smaller number to a datetime
-- But only accurate to the second.
-- 864000000000 = (10000000 * 24 * 60 * 60)
, CAST((tick.value - 599266080000000000) / 864000000000 AS datetime) as DateTimeCalc1
-- Subtrack the amount of ticks for 1900-01-01 and divide by the ticks in 1 minute.
-- Then add that smaller number as minutes to 1900-01-01
-- Only accurate to the minute
, DATEADD(MINUTE, ((tick.value - 599266080000000000) / 600000000), CAST('1900-01-01' AS DATETIME)) as DateTimeCalc2
-- Same method as for DateTimeCalc2, but include the milliseconds.
-- Accurate to the millisecond
, DATEADD(MILLISECOND, FLOOR((((tick.value - 599266080000000000)/10000)%60000)), DATEADD(MINUTE, FLOOR((tick.value - 599266080000000000)/600000000), CAST('1900-01-01' AS DATETIME))) as DateTimeCalc3
FROM (values
(convert(bigint,635307578922100000))
,(convert(bigint,599266080000000000))
,(convert(bigint,630823257457000000))
,(convert(bigint,646602048000000000))
) AS tick(value);
<强>结果:强>
value DateTimeCalc1 DateTimeCalc2 DateTimeCalc3
------------------ ----------------------- ----------------------- -----------------------
635307578922100000 2014-03-18 16:44:52.207 2014-03-18 16:44:00.000 2014-03-18 16:44:52.210
599266080000000000 1900-01-01 00:00:00.000 1900-01-01 00:00:00.000 1900-01-01 00:00:00.000
630823257457000000 2000-01-01 12:15:45.697 2000-01-01 12:15:00.000 2000-01-01 12:15:45.700
646602048000000000 2050-01-01 00:00:00.000 2050-01-01 00:00:00.000 2050-01-01 00:00:00.000
通过一些篡改,可以在秒上截断或舍入这些日期时间。
SELECT tick.value
-- Truncated
, CAST(CONVERT(varchar, CAST((tick.value - 599266080000000000) / 864000000000 AS datetime),20) AS datetime) as DateTimeTruncated
-- Rounded
, CAST(CAST(CAST((tick.value - 599266080000000000) / 864000000000 AS datetime) as datetime2(0)) AS datetime) as DateTimeRounded
-- For dates between 1981-12-14 and 2118-01-19, one could add seconds to 2050-01-01.
, DATEADD(SECOND, ((tick.value - 646602048000000000) / 10000000), cast('2050-01-01' as datetime)) as DateTimeSecondsAdded
FROM (values
(630823257457000000),
(635307578922100000),
(662380857456770000)
) tick(value);