【问题标题】:Convert UTC Milliseconds to DATETIME in SQL server在 SQL Server 中将 UTC 毫秒转换为 DATETIME
【发布时间】:2012-09-13 12:32:27
【问题描述】:

我想在 SQL Server 中将 UTC 毫秒转换为 DateTime。

这可以通过以下代码在 C# 中轻松完成:

DateTime startDate = new DateTime(1970, 1, 1).AddMilliseconds(1348203320000);

我需要在 SQL Server 中执行此操作。我找到了一些脚本here,但这是从 1900-01-01 开始的。

我使用了如下的DATEADD 函数,但这是通过将毫秒作为差异来给出算术溢出异常:

SELECT DATEADD(MILLISECOND,1348203320000,'1970-1-1')

如何正确进行转换?

【问题讨论】:

    标签: sql-server datetime sql-server-2005 utc


    【解决方案1】:
    DECLARE @UTC BIGINT
    SET @UTC = 1348203320997 
    
    SELECT DATEADD(MILLISECOND, @UTC % 1000, DATEADD(SECOND, @UTC / 1000, '19700101'))
    

    【讨论】:

    • 值 3429993600000 失败,出现“将表达式转换为数据类型 int 的算术溢出错误。”。已检查 SQL Server 2019 最新 CU。
    • @Oleksandr 这是因为 dateadd 的参数是一个整数。如果 dateadd 可以将 bigint 作为参数,那就容易多了。在这里投票:feedback.azure.com/forums/908035-sql-server/suggestions/…
    • @Oleksandr select dateadd(millisecond, @UTC % 86400000, dateadd(day, @UTC / 86400000, '19700101'));
    【解决方案2】:

    在将毫秒转换为日期时间的函数下方

    IF object_id('dbo.toDbTimeMSC', 'FN') IS NOT NULL DROP FUNCTION dbo.toDbTimeMSC
    GO
    CREATE FUNCTION [dbo].[toDbTimeMSC] (@unixTimeMSC BIGINT) RETURNS DATETIME
    BEGIN
        RETURN DATEADD(MILLISECOND, @unixTimeMSC % 1000, DATEADD(SECOND, @unixTimeMSC / 1000, '19700101'))
    END
    GO
    

    --选择dbo.toDbTimeMSC(1348203320000)

    【讨论】:

      【解决方案3】:

      使用 SQL Server 2008R2 这产生了所需的结果:

      CAST(SWITCHOFFSET(CAST(dateadd(s, convert(bigint, [t_stamp]) / 1000, convert(datetime, '1-1-1970 00:00:00')) AS DATETIMEOFFSET), DATENAME (TZoffset, SYSDATETIMEOFFSET())) AS DATETIME)
      

      【讨论】:

        【解决方案4】:

        DATEADD 需要一个整数作为第二个参数。您的号码1348203320000 对于整数来说非常大,因此它会在运行时产生错误。您应该改用 bigint 类型,并通过将毫秒拆分为秒和毫秒来为 DATEADD 提供正确的 int 值。这是您可以使用的示例。

        DECLARE @total bigint = 1348203320000;
        
        DECLARE @seconds int = @total / 1000
        DECLARE @milliseconds int = @total % 1000;
        
        DECLARE @result datetime = '1970-1-1';
        SET @result = DATEADD(SECOND, @seconds,@result);
        SET @result = DATEADD(MILLISECOND, @milliseconds,@result);
        SELECT @result
        

        【讨论】:

          【解决方案5】:

          我在使用此处给出的答案时遇到了问题(尤其是系统正在计算 0001-01-01 的刻度) - 所以我这样做了:

          CONVERT(DATETIME,[Time]/ 10000.0/1000/86400-693595)
          
          --explanation for [Time_in_Ticks]/ 10000.0/1000/86400-693595
          --Time is in "ticks"
          --10000 = number of ticks in Milisecond
          --1000  = number of milisecons in second
          --86400 = number of seconds in a day (24hours*60minutes*60second)
          --693595= number of days between 0001-01-01 and 1900-01-01 (which is base
          --          date when converting from int to datetime)
          

          【讨论】:

            【解决方案6】:

            现在,您可以使用 dateadd 来除以分钟而不是秒。

            代码会是这样的:

            DATEADD(MILLISECOND, epoch% 60000, DATEADD(MINUTE, epoch/ 60000, '19700101'));

            【讨论】:

              【解决方案7】:
              =dateadd("d",INT((Fields!lastLogon.Value / 864000000000)- 134774),"1970-01-01 00:00:00")
              

              这就是我在 SSRS 中用来解决 INT 错误的方法,使用天而不是秒。错了吗?

              【讨论】:

              • 如果您有新问题,请点击 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。 - From Review
              猜你喜欢
              • 1970-01-01
              • 2022-01-17
              • 1970-01-01
              • 1970-01-01
              • 2019-12-05
              • 1970-01-01
              • 2014-05-06
              • 2015-09-16
              • 1970-01-01
              相关资源
              最近更新 更多