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

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

Si tiene un datetimeoffset valor, pero no necesita la parte de compensación de fecha y zona horaria, convirtiéndola a hora le ahorrará mucho espacio de almacenamiento (mientras elimina detalles innecesarios del valor). Este artículo contiene ejemplos de cómo convertir un datetimeoffset valor a un tiempo valor en SQL Server.

El desplazamiento de fecha y hora el tipo de datos incluye la fecha y la hora con un desplazamiento de zona horaria. También tiene una parte de segundos fraccionarios entre 0 y 7 (esto depende de cuántos segundos fraccionarios se le asignen). Esto se hace usando datetimeoffset(n) sintaxis. Si no especifica esto, usará 7 (el valor predeterminado). El tamaño de almacenamiento de este tipo de datos es de 8, 9 o 10 bytes, según la precisión que se utilice. Su precisión es de 100 nanosegundos.

El tiempo tipo de datos por otro lado, sólo incluye la hora. No incluye la fecha y no incluye el desplazamiento de la zona horaria. Sin embargo, similar a datetimeoffset también le permite especificar una parte de segundos fraccionarios entre 0 y 7 (usando el time(n) sintaxis). Utiliza 3, 4 o 5 bytes, según su precisión.

Cuando convierte un datetimeoffset valor a un tiempo tipo de datos, pierde la parte de la fecha. También pierde el desplazamiento de la zona horaria. Sin embargo, también reduce el tamaño de almacenamiento de entre 8 y 10 bytes a 3, 4 o 5 bytes. Sin embargo, solo haría esta conversión si no necesita la parte de la fecha o el desplazamiento de la zona horaria.

Tenga en cuenta que las cantidades de almacenamiento enumeradas aquí son las cantidades enumeradas en la documentación de Microsoft. Sin embargo, estos tipos de datos también usan 1 byte para almacenar la precisión. Por lo tanto, deberá agregar 1 byte a las cantidades enumeradas aquí.

Ejemplo 1:conversión implícita

Este es un ejemplo de una conversión implícita entre datetimeoffset y tiempo .

DECLARE 
  @thedatetimeoffset datetimeoffset, 
  @thetime time;
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Resultado:

+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+

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 el datetimeoffset valor a un tiempo variables.

Aquí podemos ver que el tiempo el valor solo incluye la hora (sin el componente de fecha). Los componentes de compensación de fecha y zona horaria se han eliminado del valor.

En este ejemplo, ambos tipos de datos usan la precisión predeterminada (que da como resultado 7 lugares decimales). Esto da como resultado el datetimeoffset valor usando 10 bytes y el tiempo valor usando 5 bytes.

Ejemplo 2:precisión

El resultado exacto dependerá de la configuración de precisión para cada tipo de datos. En el siguiente ejemplo, el tiempo El valor utiliza una precisión menor que el datetimeoffset original valor:

DECLARE 
  @thedatetimeoffset datetimeoffset(7), 
  @thetime time(3);
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Resultado:

+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1230000 |
+------------------------------------+------------------+

Mi sistema muestra ceros al final, pero el punto es que el tiempo el valor ahora tiene una precisión de solo 3 decimales en comparación con los 7 decimales que usa el valor original.

Reducir la precisión también puede resultar en el tiempo valor que se redondea hacia arriba. He aquí un ejemplo:

DECLARE 
  @thedatetimeoffset datetimeoffset(7), 
  @thetime time(3);
SET @thedatetimeoffset = '2025-05-21 10:15:30.1235555 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Resultado:

+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1240000 |
+------------------------------------+------------------+

En este caso, terminamos con una parte fraccionaria de 124 en lugar de 123 , porque el siguiente dígito era 5 o mayor.

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 datetimeoffset y tiempo .

DECLARE @thedatetimeoffset datetimeoffset;
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  CAST(@thedatetimeoffset AS time) AS 'time'; 

Resultado:

+------------------------------------+------------------+
| datetimeoffset                     | date             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+

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 @thedatetimeoffset datetimeoffset;
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  CONVERT(time, @thedatetimeoffset) AS 'time'; 

Resultado:

+------------------------------------+------------------+
| datetimeoffset                     | date             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+