Convert .NET Ticks to SQL Server DateTime

后端 未结 7 844
攒了一身酷
攒了一身酷 2020-11-30 10:10

I am saving a TimeSpan (from .NET) value in my db as BIGINT in SQL Server (saving the Ticks property). I want to know how to convert this BIG

相关标签:
7条回答
  • 2020-11-30 10:41

    You should be able to use the CAST function built into SQL Server.

    SELECT(CAST(CAST(CAST ('02/02/10' AS datetime) AS BIGINT) AS datetime)) 
    

    you get 2010-02-02 00:00:00.000

    0 讨论(0)
  • 2020-11-30 10:44

    I don't really know SQL Server, but today a colleague of mine had the same problem and I think I've found a solution like this:

    CAST(([ticks] - 599266080000000000) / 10000000 / 24 / 60 / 60 AS datetime)
    

    where 599266080000000000 is the ticks value for 01/01/1900 00:00:00.

    0 讨论(0)
  • 2020-11-30 10:45

    Get the value of TimeSpan.TicksPerSecond in .NET (just write it down).

    Then, in your SQL, you can divide the tick count by that number, to give the number of seconds.

    You can then divide this by 60 to get minutes, etc.

    0 讨论(0)
  • 2020-11-30 10:54

    I have figured it out on my own:

    288,000,000,000 ticks represents 8 hours, so the following SELECT returns a dummy date with the ammount of hours specified ...

    SELECT DATEADD(millisecond, 288000000000/10000, CAST('1900-01-01' AS DATETIME))
    

    Thanks to everyones efforts.

    0 讨论(0)
  • 2020-11-30 10:56

    I'm not sure how accurate this will be with the seconds, but you could try something like:

    Declare @TickValue bigint
    Declare @Days float
    
    Set @TickValue = 634024345696365272 
    Select @Days = @TickValue * POWER(10.00000000000,-7) / 60 / 60 / 24
    
    Select DATEADD(d, Cast(@Days As int), Cast('0001-01-01' As DATE)) 
        + Cast( (@Days - FLOOR(@Days)) As DateTime)
    

    Actually another way that would work in SQL 2005 is to note that the the number of ticks from 0001-01-01 to 1900-01-01 is 599266080000000000. With that you could do:

    Declare @TickOf19000101 bigint
    Declare @TickValue bigint
    Declare @Minutes float
    
    Set @TickOf19000101  = 599266080000000000
    Set @TickValue = DATEDIFF(mi, 0 ,CURRENT_TIMESTAMP) * Cast(60 As BigInt) 
                       * POWER(10.00000000000,7) + @TickOf19000101
    
    Select @TickValue
    Select @Minutes = (@TickValue - @TickOf19000101) * POWER(10.00000000000,-7) / 60
    
    Select @Minutes
    Select DATEADD(MI, @Minutes, '1900-01-01')
    
    0 讨论(0)
  • 2020-11-30 11:05

    You can use this function taken from Pavel Gatilov's blog to convert a 64-bit integer to a datetime value with millisecond precision in server local time:

    CREATE FUNCTION NetFxUtcTicksToDateTime
    (
       @Ticks bigint
    )
    RETURNS datetime
    AS
    BEGIN
    
    -- First, we will convert the ticks into a datetime value with UTC time
    DECLARE @BaseDate datetime;
    SET @BaseDate = '01/01/1900';
    
    DECLARE @NetFxTicksFromBaseDate bigint;
    SET @NetFxTicksFromBaseDate = @Ticks - 599266080000000000;
    -- The numeric constant is the number of .Net Ticks between the System.DateTime.MinValue (01/01/0001) and the SQL Server datetime base date (01/01/1900)
    
    DECLARE @DaysFromBaseDate int;
    SET @DaysFromBaseDate = @NetFxTicksFromBaseDate / 864000000000;
    -- The numeric constant is the number of .Net Ticks in a single day.
    
    DECLARE @TimeOfDayInTicks bigint;
    SET @TimeOfDayInTicks = @NetFxTicksFromBaseDate - @DaysFromBaseDate * 864000000000;
    
    DECLARE @TimeOfDayInMilliseconds int;
    SET @TimeOfDayInMilliseconds = @TimeOfDayInTicks / 10000;
    -- A Tick equals to 100 nanoseconds which is 0.0001 milliseconds
    
    DECLARE @UtcDate datetime;
    SET @UtcDate = DATEADD(ms, @TimeOfDayInMilliseconds, DATEADD(d, @DaysFromBaseDate, @BaseDate));
    -- The @UtcDate is already useful. If you need the time in UTC, just return this value.
    
    -- Now, some magic to get the local time
    RETURN @UtcDate + GETDATE() - GETUTCDATE();
    END
    GO
    

    Alternative code suitable for inline usage:

    DECLARE @Ticks bigint
    set @Ticks = 634899090000000000
    select DATEADD(ms, ((@Ticks - 599266080000000000) - 
       FLOOR((@Ticks - 599266080000000000) / 864000000000) * 864000000000) / 10000,
       DATEADD(d, (@Ticks - 599266080000000000) / 864000000000, '01/01/1900')) +
       GETDATE() - GETUTCDATE()
    
    0 讨论(0)
提交回复
热议问题