2016-07-26 1 views
1

J'ai bigInt: 635307578922100000 que j'ai besoin de convertir en DateTime.Convertir BigInt spécifique à DateTime en T-SQL

J'ai essayé quelques façons de le faire:

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

et:

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

Bien que je trouve les codes ci-dessus travail avec bigInts comme: 1283174502729, avec mon BigInt je reçois le texte suivant erreur:

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

Quelqu'un at-il une idée de la façon de le résoudre?

+1

Quel serait votre résultat attendu pour l'entrée '635307578922100000' – StackUser

+0

Il semble que ce soient des coches. Copie possible de [Convertir .NET Ticks à SQL Server DateTime] (http://stackoverflow.com/questions/2313236/convert-net-ticks-to-sql-server-datetime) - en utilisant la réponse ici donne '2016-07 -26 09: 12: 00.000' – Bridge

+0

Vous devez convertir cette valeur en nombre d'heures depuis 01.01.1900 00:00:00, c'est la précision maximale de la partie date qui correspond à 'int'. Puis ajoutez ms à gauche. – Serg

Répondre

1

Voici 2 calculs qui peuvent calculer le bigint à une date/heure.

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); 

Résultat:

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 

Notez que la première est à la seconde près.
Les millisecondes varient toutefois à chaque passage.

Alors que le second est seulement précis à la minute.

Avec un peu de falsification, ces dates peuvent être arrondies à la seconde.

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

Solution parfaite. Merci. –

3

Je pense que c'est en ticks (rendements 2014-03-18 16: 44: 52.210). Voici la solution:

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

Cette valeur magique 599266080000000000 est le nombre de tiques entre 0001-01-01 et 1900-01-01 calculée PowerShell comme suit:

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

Les conversions sont nécessaires, parce que DATEADD ne fonctionnera pas avec bigint (nécessite int). SQL Server DateTime est également limitée au 1er janvier 1753.