2010-01-05 11 views
20

Tengo una tabla anterior con algunas filas que tienen una columna de fecha y hora. Quiero cambiar esto a datetimeoffset pero quiero poder transferir los datos que ya existen. Por lo que estoy haciendo algo como:Migrar la columna de fecha y hora de SQL Server a DateTimeOffset

SET IDENTITY_INSERT Table_Temp ON 

INSERT INTO Table_Temp 
    (Col0, ... ColN,) 
SELECT 
    COl0,.... ColN, from 
Table_Original; 

SET IDENTITY_INSERT Table_Temp OFF 

Esto funciona, pero el conjunto de desplazamiento es 0 cuando hago la dattime a datetimeoffset asignación. Afortunadamente, el desplazamiento que quiero establecer es el desplazamiento del sistema actual. No soy un gurú de tsql, pero parece que no puedo encontrar una forma fácil de hacerlo.

Quiero ser capaz de establecer el desplazamiento dentro de la conversión. Iba a recurrir a la utilidad C# (o PowerShell), pero prefiero mantenerlo simple.

+0

--- Gracias chicos, que debería haber sido claro en que yo simplemente quería añadir el desplazamiento sin cambiar el tiempo mismo. ¡Pero ustedes me consiguieron allí! ;) – hdz

Respuesta

4

Si está utilizando una versión de SQL Server que sabe del tipo datetimeoffset, esta sintaxis va a trabajar para conseguir que el desplazamiento del servidor local de tz:

select datepart(tz,sysdatetimeoffset())

El resultado es en minutos.

+0

Gracias por eso, exactamente lo que necesitaba. Están usando muchos términos superpuestos ahora que es difícil incluso buscar en los documentos ... –

2

Puede averiguar cuál es el desplazamiento del servidor SQL actual utilizando lo siguiente.

select datediff(MI,getdate(), getutcdate()) 

que necesita para obtener el desplazamiento en minutos y no en horas, ya que hay una serie de media hora e incluso una zona horaria cuarto de hora.

Usando el valor de los minutos, puede alterar sus valores van en (suponiendo que estaban históricamente todas registra en hora local) mediante el uso de algo así como

select dateadd(mi,datediff(MI,getdate(), getutcdate()), yourDateField) 

Para la eficiencia Me calcularlo una vez en una variable y el uso eso, ya que la diferencia no va a cambiar.

+2

esto no funciona en fechas históricas si necesita contabilizar el horario de verano. ¿Derecha? Está encontrando su desplazamiento UTC actual basado en getdate y luego agregando esto a un campo histórico de fecha. Pero, el desplazamiento cambia si desea contabilizar el horario de verano. La hora estándar del Este es UTC-5, pero el horario de verano del Este es UTC-4. Si desea convertir fechas históricas, debe tener en cuenta las transiciones de horario de verano. (Me da un dolor de cabeza solo de pensarlo). –

+0

Corregir y, a continuación, cambiar los datos históricos en lotes, y luego tener en cuenta un año cada uno con un punto diferente en el tiempo que cambió. – Andrew

+0

¿Cómo harías para encontrar el desplazamiento de la fecha histórica? – Jeremy

22

Véase más abajo para doc, es probable que desee algo como:

-- up here set the @time_zone variable. 

INSERT INTO Table_Temp 
    (Col0, ... ColN,) 
SELECT 
    COl0, TODATETIMEOFFSET(COLDATE, @time_zone),.... ColN, from 
Table_Original; 

De MSDN

La función SWITCHOFFSET ajusta un valor DateTimeOffset de entrada a una zona horaria especificada , preservando al mismo tiempo la Valor UTC. La sintaxis es SWITCHOFFSET (datetimeoffset_value, time_zone). Por ejemplo, el siguiente código ajusta el valor actual del sistema datetimeoffset a la zona horaria GMT 05: 00:

SELECT SWITCHOFFSET (SYSDATETIMEOFFSET(), '-05: 00');

lo tanto, si el valor actual del sistema datetimeoffset es el 12 de febrero de 2009 10: 00: 00,0000000 -08: 00, este código devuelve el valor 12 de febrero de 2009 13: 00: 00,0000000 -05: 00.

La función TODATETIMEOFFSET establece offset de zona horaria de una fecha de entrada y valor de tiempo. Su sintaxis es TODATETIMEOFFSET (date_and_time_value, time_zone).

Esta función es diferente de SWITCHOFFSET de varias maneras. En primer lugar, no está restringido a un valor datetimeoffset como entrada; más bien acepta cualquier dato de fecha y hora tipo .En segundo lugar, no trata de ajustar el tiempo en función de la diferencia de huso horario entre el valor de la fuente y la zona horaria especificada pero su lugar simplemente devuelve la fecha de entrada como el valor temporal con la zona horaria especificado como un valor datetimeoffset .

El propósito principal de la función TODATETIMEOFFSET es convertir los tipos que no son conscientes de zona horaria a DateTimeOffset por la zona momento dado offset. Si la fecha y la hora valor dado es un DateTimeOffset, la función TODATETIMEOFFSET cambia el valor DateTimeOffset basado en la misma fecha local original y valor de tiempo además de la nueva zona horaria determinada offset.

Por ejemplo, el valor actual del sistema datetimeoffset es 12 de febrero de 2009 10: 00: 00,0000000 -08: 00, y que ejecute el siguiente código:

SELECT TODATETIMEOFFSET (SYSDATETIMEOFFSET(), '-05: 00');

Se devuelve el valor 12 de febrero de 2009 10: 00: 00.0000000 -05: 00. Recuerde que la función SWITCHOFFSET obtenido 12 de febrero de, 2009 13: 00: 00,0000000 -05: 00 porque ajustar el tiempo en función de las diferencias de zona horaria entre la entrada (-08: 00) y la zona de tiempo especificado (-05: 00).

Como se mencionó anteriormente, puede utilizar la función TODATETIMEOFFSET con cualquier tipo de datos de fecha y hora como entrada. Para ejemplo, el siguiente código toma la fecha actual sistema y el valor de tiempo y lo devuelve como un valor datetimeoffset con una zona de tiempo -00: 05:

SELECT TODATETIMEOFFSET (SYSDATETIME(), '-05: 00 ');

+1

Un comentario sobre esta publicación anterior. La zona horaria y el desplazamiento del tiempo de la fecha son diferentes. La zona horaria tiene en cuenta el horario de verano, mientras que el desplazamiento está solo compensado. –

4

Estas funciones de conversión no funcionarán correctamente si el guardado de DST está activo en la zona horaria de destino, ya que el desplazamiento de la zona horaria cambia dentro del mismo año.

+2

¿Cómo lo harías correctamente para tener en cuenta el horario de verano? – Jeremy

0

Esta es una ligera variación de una respuesta ya proporcionada, y no tiene en cuenta los cambios de DST.Sin embargo, podría ser lo suficientemente bueno para muchos propósitos:

dateadd(minute, -datepart(tz, sysdatetimeoffset()), @legacyDatetime) 
Cuestiones relacionadas