Tsql 如何在T-SQL中将DATETIME转换为FILETIME值?

Tsql 如何在T-SQL中将DATETIME转换为FILETIME值?,tsql,datetime,filetime,Tsql,Datetime,Filetime,我需要在T-SQLSELECT语句(在SQL Server 2000上)中将SQL ServerDATETIME值转换为FILETIME。是否有内置的功能来执行此操作?如果没有,有人能帮我弄清楚如何将此转换例程实现为UDF(或纯Transact-SQL)?以下是我所知道的: FILETIME是64位值,表示自 1601年1月1日(UTC)(per) SQL Server基准时间从1900-01-01 00:00:00开始(每次选择转换(0作为日期时间)) 我找到了几个示例,展示了如何将FILET

我需要在T-SQLSELECT语句(在SQL Server 2000上)中将SQL ServerDATETIME转换为FILETIME。是否有内置的功能来执行此操作?如果没有,有人能帮我弄清楚如何将此转换例程实现为UDF(或纯Transact-SQL)?以下是我所知道的:

  • FILETIME是64位值,表示自 1601年1月1日(UTC)(per)
  • SQL Server基准时间从1900-01-01 00:00:00开始(每次选择转换(0作为日期时间))
  • 我找到了几个示例,展示了如何将FILETIME值转换为T-SQLDateTime(尽管我不能100%确定它们是否准确),但找不到任何有关反向转换的内容。即使是一般的想法(或算法)也会有所帮助

    2 SQL Server时代开始于 1900-01-01 00:00:00 如日期时间)

    不,那是基准日期,日期时间从1753年开始

    运行这个

    select cast('17800122' as datetime) 
    
    输出

    1780-01-22 00:00:00.000


    但是这仍然比文件时间短,所以您需要添加这一点……但是请记住格里高利历和儒略历(也是日期时间从1753年开始的原因)

    好的,我想我自己能够实现这一点。下面是函数:

    IF EXISTS 
    (
        SELECT 1
        FROM   sysobjects 
        WHERE  id   = OBJECT_ID('[dbo].[fnDateTimeToFileTime]')
          AND  type = 'FN'
    )
    BEGIN
        DROP FUNCTION [dbo].[fnDateTimeToFileTime]
    END
    GO
    
    -- Create function.
    CREATE FUNCTION [dbo].[fnDateTimeToFileTime]
    (
        @DateTime AS DATETIME
    )
    RETURNS
        BIGINT
    BEGIN
    
    IF @DateTime IS NULL
        RETURN NULL
    
    DECLARE @MsecBetween1601And1970 BIGINT
    DECLARE @MsecBetween1970AndDate BIGINT
    
    SET @MsecBetween1601And1970 = 11644473600000
    
    SET @MsecBetween1970AndDate = 
        DATEDIFF(ss, CAST('1970-01-01 00:00:00' as DATETIME), @DateTime) * 
            CAST(1000 AS BIGINT)
    
    RETURN (@MsecBetween1601And1970 + @MsecBetween1970AndDate) * CAST(10000 AS BIGINT)  
    END
    GO
    
    IF @@ERROR = 0
        GRANT EXECUTE ON [dbo].[fnDateTimeToFileTime] TO Public 
    GO
    
    它似乎精确到1秒,这对我来说还行(由于数据溢出,我无法使它更精确)。我使用计算日期之间的持续时间


    你认为呢?

    接受的答案很有效,但会在2038年1月19日之后崩溃。使用 如果您使用的是SQL Server 2016或更高版本,请使用DATEDIFF_BIG而不是DATEDIFF,或者使用以下更正

    CREATE FUNCTION [dbo].[fnDateTimeToFileTime]
    (
        @DateTime AS DATETIME
    )
    RETURNS
        BIGINT
    BEGIN
    
    IF @DateTime IS NULL
        RETURN NULL
    
    DECLARE @MsecBetween1601And1970 BIGINT
    DECLARE @MsecBetween1970AndDate BIGINT
    
    DECLARE @MaxNumberDayBeforeOverflowDateDiff int;
    SET @MaxNumberDayBeforeOverflowDateDiff  = 24855; --SELECT DATEDIFF(day, CAST('1970-01-01 00:00:00' as DATETIME), CAST('2038-01-19 00:00:00' as DATETIME))
    
    DECLARE @nbMaxDaysBetween1970AndDate int;
    SET @nbMaxDaysBetween1970AndDate = DATEDIFF(day, CAST('1970-01-01 00:00:00' as DATETIME), @DateTime) / @MaxNumberDayBeforeOverflowDateDiff;
    
    DECLARE @moduloResteDay int
    SET @moduloResteDay = DATEDIFF(day, CAST('1970-01-01 00:00:00' as DATETIME), @DateTime) % @MaxNumberDayBeforeOverflowDateDiff;
    
    DECLARE @nbSecondBefore19700101And20380119 bigint = 2147472000;
    SET @MsecBetween1601And1970 = 11644473600000;
    
    DECLARE @DateTimeModulo datetime;
    SET @DateTimeModulo = DATEADD(day, -@nbMaxDaysBetween1970AndDate * @MaxNumberDayBeforeOverflowDateDiff, @DateTime)
    
    
    SET @MsecBetween1970AndDate = CAST(CAST(@nbMaxDaysBetween1970AndDate as bigint) * @nbSecondBefore19700101And20380119 + 
        DATEDIFF(ss, CAST('1970-01-01 00:00:00' as DATETIME), @DateTimeModulo) as bigint)* 
            CAST(1000 AS BIGINT)
    
    RETURN (@MsecBetween1601And1970 + @MsecBetween1970AndDate) * CAST(10000 AS BIGINT) 
    END
    

    哦,太好了,现在我更困惑了。:-)至少在SQLServer2008DateTime2到了第一年