SQL中日期时间的历元转换

SQL中日期时间的历元转换,sql,sql-server,function,Sql,Sql Server,Function,我有一个SQL函数,可以将历元转换为日期时间 该sql函数在1970年1月3日之前的日期不起作用的问题。是否有人有任何想法,使这项工作的日期少于1970年 DECLARE @total bigint --if greater than 12/31/9999 return null IF @total > 253402232400000 RETURN NULL --if less than or equal 1/3/1970 return null IF @tota

我有一个SQL函数,可以将历元转换为日期时间

该sql函数在1970年1月3日之前的日期不起作用的问题。是否有人有任何想法,使这项工作的日期少于1970年

DECLARE @total bigint
--if greater than 12/31/9999 return null
IF @total > 253402232400000
    RETURN NULL

--if less than or equal 1/3/1970 return null        
IF @total <= 18000000
  RETURN NULL

DECLARE @seconds int = @total / 86400000;
DECLARE @milliseconds int = @total % 86400000;

DECLARE @result datetime = '1970-1-1';

SET @result = DATEADD(DAY, @seconds,@result);
SET @result = DATEADD(MILLISECOND, @milliseconds,@result);

RETURN @result;
试试这个。 应适用于0001-01-01T00:00:00.000至9999-12-31T23:59:59.999的所有日期


您是否尝试过使用负值?对于什么值?请阅读代码中的第二条注释。这告诉你什么?有什么吗?根据定义,我不相信你能。历元时间是一个时间点,表示自UTC 1970-1-1 00:00:00以来经过的秒数。无需运行代码。这一评论非常明确。代码查找下限并返回NULL。我们为您提供了一个函数,至少是一个不完整的脚本,它故意为1970年7月28日之前的日期返回NULL,而不是1月3日。为什么?去问问医生。你可以了解这一切,谢谢。我会试试这个。这与您提供的代码基本相同,只是您的代码明确限制为1970-01-01T05:00:00.000到9999-12-31T05:00:00.000。我想知道为什么最初的程序员在两个极限上都使用上午5点。@Apollo,你运气好吗?
-- UnixTimeToDateTime2
--
-- Parameter:  64-bit integer
-- Number of milliseconds 
-- since 1970-01-01T00:00:00.000
-- May be negative before 1970
--
-- Returns datetime2
-- Works with all values in  
-- range   0001-01-01T00:00:00.000
-- through 9999-12-31T23:59:59.999

-- Returns NULL if parameter is out of range

create function dbo.UnixTimeToDateTime2(@x bigint)
returns datetime2 
as 
begin 
  return
    case 
      -- If the parameter is out of range,
      -- return NULL
      when    ( @x < -62135596800000 ) 
           or ( @x > 253402300799999 ) then null
      else

      -- We would like to add this number of milliseconds
      -- directly to 1970-01-01T00:00:00.000, but this 
      -- can lead to an overflow.
      -- Instead we break the addition into a number of days
      -- and a number of milliseconds. 
      -- To get the number of days, we divide by the number 
      -- of milliseconds in a day. Then add the remainder.

        dateadd ( millisecond, 
                  @x % 86400000, 
                  dateadd ( day, 
                            @x / 86400000, 
                            cast( '1970-01-01T00:00:00.000' 
                                  as datetime2 )) )
    end
end