2012-06-16 27 views
5

Tengo unas pocas columnas en una base de datos de SQL Server 2008 R2 que necesito convertir de hora local (la zona horaria en que se encuentra el servidor sql) a UTC.Servidor SQL: Convierta entre hora UTC y hora local de manera precisa

He visto bastantes preguntas similares en StackOverflow, pero todas las respuestas no funcionan correctamente con el horario de verano, solo tienen en cuenta la diferencia actual y compensan la fecha.

+0

¿Tiene que lidiar con los tiempos durante las transiciones DST (donde dos valores UTC pueden ser un resultado válido para una sola hora local)? –

Respuesta

7

No he podido encontrar ninguna manera de hacerlo usando T-SQL solo. Lo resuelto mediante SQL CLR:

public static class DateTimeFunctions 
{ 
    [SqlFunction(IsDeterministic = true, IsPrecise = true)] 
    public static DateTime? ToLocalTime(DateTime? dateTime) 
    { 
     if (dateTime == null) return null; 
     return dateTime.Value.ToLocalTime(); 
    } 

    [SqlFunction(IsDeterministic = true, IsPrecise = true)] 
    public static DateTime? ToUniversalTime(DateTime? dateTime) 
    { 
     if (dateTime == null) return null; 
     return dateTime.Value.ToUniversalTime(); 
    } 
} 

Y la siguiente secuencia de comandos de registro:

CREATE FUNCTION ToLocalTime(@dateTime DATETIME2) RETURNS DATETIME2 AS EXTERNAL NAME AssemblyName.[AssemblyName.DateTimeFunctions].ToLocalTime; 
GO 
CREATE FUNCTION ToUniversalTime(@dateTime DATETIME2) RETURNS DATETIME2 AS EXTERNAL NAME AssemblyName.[AssemblyName.DateTimeFunctions].ToUniversalTime; 

Es una lástima que ser forzado a ir a tal esfuerzo para convertir ay desde la hora UTC.

Tenga en cuenta que estas funciones interpretan hora local como lo que sea local para el servidor. Se recomienda tener clientes y servidores configurados en el mismo huso horario para evitar confusiones.

+1

Gracias por su contribución. En mi caso, no era algo que tuviera que hacer más de una vez, era parte de una actualización a la base de datos donde se usaba la hora local y terminé simplemente creando una aplicación independiente para hacer la actualización. Pero he elegido aceptar esto como una respuesta porque se lo merece. – user1450824

1
DECLARE @convertedUTC datetime, @convertedLocal datetime 
    SELECT DATEADD(
        HOUR,         -- Add a number of hours equal to 
        DateDiff(HOUR, GETDATE(), GETUTCDATE()), -- the difference of UTC-MyTime 
        GetDate()        -- to MyTime 
        ) 

    SELECT @convertedUTC = DATEADD(HOUR,DateDiff(HOUR, GETDATE(), GETUTCDATE()),GetDate()) --Assign the above to a var 

    SELECT DATEADD(
        HOUR,         -- Add a number of hours equal to 
        DateDiff(HOUR, GETUTCDATE(),GETDATE()), -- the difference of MyTime-UTC 
        @convertedUTC       -- to MyTime 
        ) 

    SELECT @convertedLocal = DATEADD(HOUR,DateDiff(HOUR, GETUTCDATE(),GETDATE()),GetDate()) --Assign the above to a var 


    /* Do our converted dates match the real dates? */ 
    DECLARE @realUTC datetime = (SELECT GETUTCDATE()) 
    DECLARE @realLocal datetime = (SELECT GetDate()) 

    SELECT 'REAL:', @realUTC AS 'UTC', @realLocal AS 'Local' 
    UNION 
    SELECT 'CONVERTED:', @convertedUTC AS 'UTC', @convertedLocal AS 'Local' 
+1

No cuenta para DST :( –

Cuestiones relacionadas