将 Epoch 转换为 DateTime SQL Server(超过 2038 年)

问题描述 投票:0回答:5

如果 epoch 超过 2038 年,如何将 Epoch 转换为 DateTime SQL Server?

Convert Epoch to DateTime SQL Server中的答案将不起作用。

例子:

SELECT DATEADD(ss, 2713795200000 / 1000, '19700101')

格林威治标准时间 2055 年 12 月 30 日星期四 16:00:00

sql-server limit epoch year2038
5个回答
2
投票

DATEADD 函数假定 INT 作为日期的增量,要绕过 INT 的限制,您可以降低纪元的精度,或者做一个稍微复杂的代码来保持纪元的精度。

这将精度降低到分钟:

SELECT DATEADD(MINUTE,@YourEpoch/60/1000, '1/1/1970')

这个将你的纪元拆分为几天和几毫秒,然后将它们组合成一个日期时间

CREATE FUNCTION [dbo].[fn_EpochToDatetime] (@Epoch BIGINT)
RETURNS DATETIME
AS
BEGIN
    DECLARE @Days AS INT, @MilliSeconds AS INT
    SET @Days = @Epoch / (1000*60*60*24)
    SET @MilliSeconds = @Epoch % (1000*60*60*24)

    RETURN (SELECT DATEADD(MILLISECOND, @MilliSeconds, DATEADD(DAY, @Days, '1/1/1970')))
END;

但是,我不太确定为什么第二个解决方案不如我预期的那么精确。


0
投票

基于上面的响应,提供的解决方案有效但不能防止尝试转换为超出 SQL Server 范围的日期。

创建函数 dbo.unixTimestampConversion ( @unixTime bigInt ) 返回日期时间 2(7) 作为 开始

    declare
        @output dateTime2(7)
        , @days int
        , @ms   int
        , @x    int = (1000 * 60 * 60 * 24)
    ;


    set @days = @unixTime / @x
    ;
    set @ms = @unixTime % @x
    ;
    if (@unixTime < 32503593600000 and @unixTime > -2208988800000)
        begin
            set @output = dateAdd (millisecond, @ms, dateAdd (day, @days, '1/1/1970'))
            ;
        end
        ;
    else if (@unixTime <= -2208988800000)
             begin
                 set @output = '1/1/1900'
                 ;
             end
             ;
    else if (@unixTime >= 32503593600000)
             begin
                 set @output = '12/31/2999'
                 ;
             end
             ;
    return @output
    ;


end

;


0
投票

您可以直接将纪元时间分配给您的日期时间(我在 SQL Server 15.0 上试过)。尽管它将数字视为自 1900-1-1 00:00:00 以来的天数,因此您必须添加 2208988800(70 年的秒数)然后除以 86400(一天的秒数)。

DECLARE @time DATETIME = (2208988800.0 + [your epoch time in seconds])/86400;

然而,它似乎比给定的纪元晚了 0.007 秒或 0.003 秒。另外,我不确定这是否比

DATEADD()
函数快。


0
投票

老问题,但是支持

DATETIMEOFFSET
数据类型的 SQL Server 的更高版本使这更容易:

DATEADD(CAST('1970-01-01T00:00:00Z' AS DATETIMEOFFSET),s,<epoch time as bigint>))

DATEADD
可以与
s
/
second
ms
/
millisecond
mcs
/
microsecond
ns
/
nanosecond
一起工作。

然后,如果您在特定时区需要它,请使用

SELECT <date> AS TIME ZONE <timezone>


-2
投票

创建一个将纪元转换为日期时间的函数,并在您的查询中使用它们,例如 下面

create FUNCTION [dbo].[from_unixtime] (@Datetime BIGINT)
RETURNS DATETIME
AS
BEGIN
    DECLARE @LocalTimeOffset BIGINT
           ,@AdjustedLocalDatetime BIGINT;
    SET @LocalTimeOffset = DATEDIFF(second,GETDATE(),GETUTCDATE())
    SET @AdjustedLocalDatetime = @Datetime - @LocalTimeOffset
    RETURN (SELECT DATEADD(second,@AdjustedLocalDatetime, CAST('1970-01-01 00:00:00' AS datetime)))
END;

然后在您的查询中使用此功能

© www.soinside.com 2019 - 2024. All rights reserved.