sql >> Base de Datos >  >> RDS >> Sqlserver

Convierta 'datetime' a 'datetimeoffset' en SQL Server (ejemplos de T-SQL)

Este artículo contiene ejemplos de cómo convertir una fecha y hora valor a un datetimeoffset valor en SQL Server.

Cuando convierte una fecha y hora valor a datetimeoffset , el valor resultante dependerá de la precisión de fracciones de segundo que asigne a datetimeoffset , así como cualquier compensación de zona horaria que especifique.

La fechahora tipo de datos tiene un máximo de 3 dígitos para su parte de segundos fraccionarios. Su precisión se redondea a incrementos de 0,000, 0,003 o 0,007 segundos.

El desplazamiento de fecha y hora El tipo de datos, por otro lado, le permite especificar una precisión de segundos fraccionarios de 0 a 7. Si no especifica esto, usará 7 (el valor predeterminado). También tiene una compensación de zona horaria y puede conservar cualquier compensación en el valor original. Sin embargo, datetime no tiene conciencia de zona horaria, por lo que no hay valores existentes para preservar. En este caso, el desplazamiento de la zona horaria por defecto es +00:00.

SQL Server en realidad tiene el TODATETIMEOFFSET() función, que está diseñada específicamente para convertir un valor de fecha/hora a datetimeoffset y agregue un desplazamiento de zona horaria. Sin embargo, hay un detalle sutil a tener en cuenta al usar esta función, y lo explico a continuación (con ejemplos).

Ejemplo 1:conversión implícita

Primero, aquí hay un ejemplo de una conversión implícita entre datetime y desplazamiento de fecha y hora .

DECLARE 
  @thedatetime datetime, 
  @thedatetimeoffset datetimeoffset(7);
SET @thedatetime = '2025-05-21 10:15:30.123';
SET @thedatetimeoffset = @thedatetime;
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset(7)';

Resultado:

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.123 | 2025-05-21 10:15:30.1233333 +00:00 |
+-------------------------+------------------------------------+

Esta es una conversión implícita porque no estamos usando una función de conversión (como las que se muestran a continuación) para convertirla explícitamente. En este caso, SQL Server realiza una conversión implícita entre bastidores cuando intentamos asignar la fecha y hora valor a un datetimeoffset variables.

Podemos ver que el datetimeoffset variable tiene más precisión de segundos fraccionarios, y terminamos con una parte fraccionaria de 1233333 (frente a 123 para la fechahora valor). También terminamos con un desplazamiento de zona horaria de +00:00 .

El uso de una precisión de 7 fracciones de segundo provoca datetimeoffset para usar 10 bytes para el almacenamiento (11 bytes si incluye el byte que almacena su precisión). A modo de comparación, datetime utiliza sólo 8 bytes. Sin embargo, puede reducir la precisión del datetimeoffset valor reemplazando el 7 con un número más bajo. Este es el mismo concepto que cuando se usa datetime2 tipo de datos. Consulte Convertir 'datetime' a 'datetime2' en SQL Server para ver ejemplos de cómo esto puede afectar el resultado final.

Ejemplo 2:redondeo

La fechahora el tipo de datos se redondea a incrementos de .000, .003 o .007 segundos. Incluso si lo establece explícitamente en otro valor, se redondeará. Esto podría causarle mucha confusión si no sabe cómo funciona. No solo puede causar confusión al usar datetime por sí mismo, puede causar confusión adicional al convertir ese valor a otro tipo de datos.

Aquí hay un ejemplo que demuestra lo que quiero decir.

DECLARE 
  @thedatetime datetime, 
  @thedatetimeoffset datetimeoffset;
SET @thedatetime = '2025-05-21 10:15:30.125';
SET @thedatetimeoffset = @thedatetime;
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset(7)';

Resultado:

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1266667 +00:00 |
+-------------------------+------------------------------------+

En este ejemplo, configuré los segundos fraccionarios en 125 pero fechahora redondeado a 127 (porque este tipo de datos solo se puede redondear a incrementos de 0,000, 0,003 o 0,007 segundos).

El desplazamiento de fecha y hora por otro lado, establezca los segundos fraccionarios en 1266667 .

Sin embargo, si simplemente establecemos el valor inicial en datetimeoffset en primer lugar, su parte fraccionaria habría devuelto 1250000 .

Ejemplo 3:conversión explícita mediante CAST()

Este es un ejemplo de una conversión explícita. En este caso, uso el CAST() función directamente dentro del SELECT declaración para convertir explícitamente entre datetime y desplazamiento de fecha y hora .

DECLARE @thedatetime datetime;
SET @thedatetime = '2025-05-21 10:15:30.125';
SELECT 
  @thedatetime AS 'datetime',
  CAST(@thedatetime AS datetimeoffset(7)) AS 'datetimeoffset(7)';

Resultado:

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1266667 +00:00 |
+-------------------------+------------------------------------+

Ejemplo 4:conversión explícita mediante CONVERT()

Aquí hay un ejemplo de una conversión explícita usando CONVERT() función en lugar de CAST() .

DECLARE @thedatetime datetime;
SET @thedatetime = '2025-05-21 10:15:30.125';
SELECT 
  @thedatetime AS 'datetime',
  CONVERT(datetimeoffset(7), @thedatetime) AS 'datetimeoffset(7)';

Resultado:

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1266667 +00:00 |
+-------------------------+------------------------------------+

Ejemplo 5:cambiar la compensación de la zona horaria

Si se está tomando la molestia de convertir su datetime valores a datetimeoffset , probablemente necesite el desplazamiento de la zona horaria. Y existe una gran posibilidad de que desee configurarlo en algo diferente a +00:00.

Afortunadamente, puedes usar el TODATETIMEOFFSET() función para cambiar el desplazamiento.

También puede usar esta función para convertir la fecha y hora original valor a un datetimeoffset valor. Esta función acepta un valor de fecha/hora (que puede resolverse como datetime2 valor) y un valor de compensación.

He aquí un ejemplo:

DECLARE @thedatetime datetime, @thedatetimeoffset datetimeoffset;
SET @thedatetime = '2025-05-21 10:15:30.125';
SET @thedatetimeoffset = TODATETIMEOFFSET(@thedatetime, '+07:00');
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset';

Resultado:

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1270000 +07:00 |
+-------------------------+------------------------------------+

Y aquí hay un ejemplo usando la función dentro de SELECT declaración:

DECLARE @thedatetime datetime = '2025-05-21 10:15:30.125';
SELECT 
  @thedatetime AS 'datetime',
  TODATETIMEOFFSET(@thedatetime, '+07:00') AS 'datetimeoffset';

Resultado:

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1270000 +07:00 |
+-------------------------+------------------------------------+

Un punto importante sobre el TODATETIMEOFFSET() función es que utiliza la misma precisión fraccionaria que el argumento de fecha/hora que se le pasó. En este caso es un datetime argumento, por lo que tiene una escala de 3 (es decir, 3 fracciones de segundo). Esto puede o no ser un problema para usted. Si es así, siempre puede convertirlo en un datetimeoffset primero, luego pase ese valor convertido a TODATETIMEOFFSET() .

Ejemplo:

DECLARE @thedatetime datetime, @thedatetimeoffset datetimeoffset(7);
SET @thedatetime = '2025-05-21 10:15:30.125';
SET @thedatetimeoffset = @thedatetime;
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset',
  TODATETIMEOFFSET(@thedatetimeoffset, '+07:00') AS 'Modified';

Resultado (usando salida vertical):

datetime       | 2025-05-21 10:15:30.127
datetimeoffset | 2025-05-21 10:15:30.1266667 +00:00
Modified       | 2025-05-21 10:15:30.1266667 +07:00