2016-07-26 28 views
1

Ich habe bigInt: 635307578922100000 die ich in DateTime konvertieren muss.Konvertieren von bestimmten BigInt in DateTime in T-SQL

Ich habe einige Möglichkeiten versucht, dies zu tun:

SELECT 
    DATEADD(S, CONVERT(bigint,635307578922100000)/1000, CONVERT(DATETIME, '1-1-1970 00:00:00')) 

und: 1283174502729, mit meinem BigInt ich folgendes:

SELECT 
    DATEADD(ms, 635307578922100000/86400000, (635307578922100000/86400000) +25567) 

Während ich die Codes über die Arbeit mit bigInts wie gefunden Fehler:

Msg 8115 ... Arithmetic overflow error converting expression to data type datetime.

jemand eine Idee Hat, wie es zu lösen?

+1

Was wäre Ihr erwartetes Ergebnis für den gegebenen Eingang '635307578922100000' – StackUser

+0

Es sieht so aus, als wären dies Ticks. Mögliches Duplikat von [.NET-Ticks in SQL Server DateTime konvertieren] (http://stackoverflow.com/questions/2313236/convert-net-ticks-to-sql-server-datetime) - mit der Antwort hier wird '2016-07 ausgegeben -26 09: 12: 00.000' – Bridge

+0

Sie müssen diesen Wert in die Anzahl der Stunden seit dem 01.01.1900 00:00:00 umrechnen, es ist die maximale Datumsgenauigkeit, die für 'int' passt. Fügen Sie dann ms links hinzu. – Serg

Antwort

1

Hier sind 2 Berechnungen, die Bigint zu einem Datetime berechnen können.

select 
tick.value, 

-- 10000000 * 24 * 60 * 60 = 864000000000 
CAST((tick.value - 599266080000000000)/864000000000 AS datetime) as DateTimeCalc1, 

DATEADD(MINUTE, ((tick.value - 599266080000000000)/600000000), '1900-01-01') as DateTimeCalc2, 

from (values 
(convert(bigint,635307578922100000)), 
(convert(bigint,599266080000000000)) 
) tick(value); 

Ergebnis:

value    DateTimeCalc1   DateTimeCalc2 
635307578922100000 2014-03-18 16:44:52.210 2014-03-18 16:44:00.000 
599266080000000000 1900-01-01 00:00:00.000 1900-01-01 00:00:00.000 

Beachten Sie, dass die erste auf die Sekunde genau ist.
Die Millisekunden variieren jedoch mit jedem Lauf.

Während der zweite ist nur auf die Minute genau.

Mit ein bisschen Manipulation können diese Datumsangaben auf die zweite gerundet werden.

select 
tick.value, 
CAST((tick.value - 599266080000000000)/864000000000 AS datetime) as DateTimeCalc1, 

-- truncated 
CAST(CONVERT(varchar, CAST((tick.value - 599266080000000000)/864000000000 AS datetime),20) AS datetime) as DateTimeCalc1B, 

-- rounded 
CAST(CAST(CAST((tick.value - 599266080000000000)/864000000000 AS datetime) as datetime2(0)) AS datetime) as DateTimeCalc1C, 

-- only for dates between 1981-12-14 and 2118-01-19 
DATEADD(SECOND, ((tick.value - 646602048000000000)/10000000), '2050-01-01') as DateTimeCalc2B 
from (values 
(630823257457000000), 
(635307578922100000), 
(646602048000000000), 
(662380857456770000) 
) tick(value); 
+0

Perfekte Lösung. Vielen Dank. –

3

Ich denke, es ist in Ticks (ergibt 2014-03-18 16: 44: 52.210). Hier Lösung:

SELECT DATEADD(
    MILLISECOND, 
    FLOOR(((635307578922100000-599266080000000000)%(10000000*60))/10000), 
    DATEADD(
     MINUTE, 
     FLOOR((635307578922100000-599266080000000000)/(10000000*60)), 
     '01-01-1900')) 

Dieser magische Wert 599266080000000000 ist Anzahl der Ticks zwischen 0001-01-01 und 1900-01-01 in Powershell wie folgt berechnet:

([DateTime]::Parse('1900-01-01')-[DateTime]::MinValue).Ticks 

Konvertierungen erforderlich sind, weil DATEADD funktioniert nicht mit bigint (erfordert int). SQL Server DateTime ist ebenfalls auf den 1. Januar 1753 beschränkt.