2012-09-21 39 views
17

Quiero convertir milisegundos UTC a DateTime en el servidor SQL.Convertir milisegundos UTC a DATETIME en el servidor SQL

Esto se puede hacer fácilmente en C# por el siguiente código:

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

tengo que hacer esto en el servidor SQL. Encontré una secuencia de comandos here, pero esto estaba tomando marcas iniciales de 1900-01-01.

he utilizado la función DATEADD como abajo, pero esto se da una excepción de desbordamiento aritmético por supping milisegundos como la diferencia:

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

¿Cómo puedo hacer la conversión correctamente?

Respuesta

33
DECLARE @UTC BIGINT 
SET @UTC = 1348203320997 

SELECT DATEADD(MILLISECOND, @UTC % 1000, DATEADD(SECOND, @UTC/1000, '19700101')) 
3

El DATEADD requiere un número entero como segundo argumento. Su número 1348203320000 es muy grande para enteros, por lo tanto, produce un error en el tiempo de ejecución. En su lugar, debería utilizar el tipo bigint y proporcionarle a DATEADD los valores int correctos dividiendo sus milisegundos en segundos y milisegundos. Esa es una muestra que podrías usar.

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 
1

he tenido problemas con el uso de las respuestas dadas aquí (especialmente que el sistema contaba forma garrapatas 0001-01-01) - así que hice esto:

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

Por debajo de la función que convierte milisegundos para datetime

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 

- seleccionar dbo.toDbTimeMSC (1348203320000)

-1

El uso de SQL Server 2008R2 produjo el resultado requerido:

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) 
Cuestiones relacionadas