web-dev-qa-db-fra.com

Convertir des millisecondes UTC en DATETIME dans un serveur SQL

Je veux convertir des millisecondes UTC en DateTime sur un serveur SQL.

Cela peut facilement être fait en C # en utilisant le code suivant:

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

J'ai besoin de faire cela sur un serveur SQL. J'ai trouvé un script ici , mais cela prenait les ticks initiaux du 1900-01-01. 

J'ai utilisé la fonction DATEADD comme ci-dessous, mais cela donnait une exception de dépassement arithmétique en supposant que millisecondes soit la différence:

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

Comment puis-je faire la conversion correctement?

21
Mohan
DECLARE @UTC BIGINT
SET @UTC = 1348203320997 

SELECT DATEADD(MILLISECOND, @UTC % 1000, DATEADD(SECOND, @UTC / 1000, '19700101'))
42
Mikael Eriksson

La DATEADD nécessite un entier comme second argument. Votre nombre 1348203320000 est très grand pour l'entier, il génère donc une erreur lors de l'exécution. Utilisez plutôt bigint et donnez à DATEADD les valeurs int correctes en fractionnant vos millisecondes en secondes et en millisecondes. C'est un exemple que vous pourriez utiliser.

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
3
tsionyx

J'ai eu du mal à utiliser les réponses données ici (surtout que le système comptait les ticks du formulaire 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)
2
Tariq2k

Ci-dessous la fonction qui convertit les millisecondes en date/heure

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

- sélectionnez dbo.toDbTimeMSC (1348203320000)

2
GLeb

L'utilisation de SQL Server 2008R2 a donné le résultat requis:

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)
1
stinkyjak

À l'heure actuelle, vous pouvez utiliser dateadd avec division en minutes et non en secondes.

Le code sera comme ça:

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

0
Ygalbel