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

Convierta 'hora' en 'fecha y hora2' en SQL Server (ejemplos de T-SQL)

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

Cuando conviertes una hora valor a datetime2 , se agrega información adicional al valor. Esto se debe a que datetime2 tipo de datos contiene información de fecha y hora. El tiempo el tipo de datos, por otro lado, solo contiene información de tiempo.

Más específicamente, la fecha se establece en '1900-01-01' (a menos que se redondee a '1900-01-02'), el componente de tiempo se copia y, de acuerdo con la documentación de Microsoft, el desplazamiento de la zona horaria está configurado a las 00:00 (aunque el datetime2 el tipo de datos no tiene en cuenta la zona horaria y no conserva ningún desplazamiento de zona horaria).

Cuando la precisión de fracciones de segundo del datetime2(n) el valor es mayor que el tiempo(n) valor, el valor se redondea hacia arriba.

Ejemplo 1: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 de tiempo a fechahora2 .

DECLARE @thetime time;
SET @thetime = '23:15:59.004007';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2) AS 'datetime2';

Resultado:

+------------------+-----------------------------+
| time             | datetime2                   |
|------------------+-----------------------------|
| 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 |
+------------------+-----------------------------+

Cuando conviertes de tiempo a fechahora2 , se agrega un componente de fecha y se establece en 1900-01-01 .

Sin embargo, hay escenarios en los que la fecha podría redondearse a 1900-01-02 . Esto dependerá de las fracciones de segundo y de la precisión que utilice. Vea a continuación un ejemplo de esto.

Ejemplo 2:precisión de fracciones de segundo

Puede obtener diferentes resultados según la precisión de fracciones de segundo que se asigna a cada tipo de datos. Esto dependerá del valor real de la parte fraccionaria.

En el ejemplo anterior, ambos tipos de datos utilizaron la misma precisión de fracciones de segundo. Esto se debe a que no especifiqué una escala (para definir su precisión) y, por lo tanto, ambos usaron sus valores de escala predeterminados (ambos resultan ser 7).

Para que quede claro, escala es el número de dígitos a la derecha del punto decimal en un número. Precisión es el número total de dígitos en el número.

De todos modos, en ese ejemplo solo asigné 6 decimales al valor inicial, por lo tanto, se agrega un cero al final.

Esto es lo que sucede si especifico una mayor precisión para el tiempo valor comparado con el datetime2 valor:

DECLARE @thetime time(7);
SET @thetime = '23:15:59.1234567';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2(4)) AS 'datetime2(4)';

Resultado:

+------------------+--------------------------+
| time             | datetime2(4)             |
|------------------+--------------------------|
| 23:15:59.1234567 | 1900-01-01 23:15:59.1235 |
+------------------+--------------------------+

Especificando una escala de 4 al datetime2 valor, el resultado se reduce a 4 decimales, y en este caso se redondea hacia arriba.

Como era de esperar, no es solo la parte fraccionaria la que se puede redondear. Aquí hay un ejemplo de donde la parte fraccionaria hace que los minutos y segundos se redondeen:

DECLARE @thetime time(7);
SET @thetime = '23:15:59.7654321';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2(0)) AS 'datetime2(0)';

Resultado:

+------------------+---------------------+
| time             | datetime2(0)        |
|------------------+---------------------|
| 23:15:59.7654321 | 1900-01-01 23:16:00 |
+------------------+---------------------+

Sin embargo, puede obtener diferentes resultados para los mismos datos cambiando la precisión. Si aumentamos la precisión, aunque solo sea por un decimal, obtenemos esto:

DECLARE @thetime time(7);
SET @thetime = '23:15:59.7654321';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2(1)) AS 'datetime2(1)';

Resultado:

+------------------+-----------------------+
| time             | datetime2(1)          |
|------------------+-----------------------|
| 23:15:59.7654321 | 1900-01-01 23:15:59.8 |
+------------------+-----------------------+

Así que en este caso los minutos y segundos no fueron redondeado (pero los milisegundos eran ).

Esto es lo que sucede si configuro la hora value para usar una escala de precisión más baja que datetime2 valor.

DECLARE @thetime time(0);
SET @thetime = '23:15:59.004007';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2) AS 'datetime2';

Resultado:

+----------+-----------------------------+
| time     | datetime2                   |
|----------+-----------------------------|
| 23:15:59 | 1900-01-01 23:15:59.0000000 |
+----------+-----------------------------+

Y mientras estamos en eso, aquí hay un ejemplo de dónde nuestra escala de precisión puede dar como resultado las fracciones de segundo que hacen que la fecha se redondee al día siguiente:

DECLARE @thetime time(7);
SET @thetime = '23:59:59.9999999';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2(0)) AS 'datetime2(0)';

Resultado:

+------------------+---------------------+
| time             | datetime2(0)        |
|------------------+---------------------|
| 23:59:59.9999999 | 1900-01-02 00:00:00 |
+------------------+---------------------+

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

Esto es lo mismo que el primer ejemplo, excepto que esta vez uso el CONVERT() función en lugar de CAST() .

DECLARE @thetime time;
SET @thetime = '23:15:59.004007';
SELECT 
  @thetime AS 'time',
  CONVERT(datetime2, @thetime) AS 'datetime2';

Resultado:

+------------------+-----------------------------+
| time             | datetime2                   |
|------------------+-----------------------------|
| 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 |
+------------------+-----------------------------+

Ejemplo 4:conversión implícita

Aquí hay un ejemplo de hacer lo mismo, pero usando una conversión de tipo implícita.

DECLARE @thetime time, @thedatetime2 datetime2;
SET @thetime = '23:15:59.004007';
SET @thedatetime2 = @thetime;
SELECT 
  @thetime AS 'time',
  @thedatetime2 AS 'datetime2';

Resultado:

+------------------+-----------------------------+
| time             | datetime2                   |
|------------------+-----------------------------|
| 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 |
+------------------+-----------------------------+

Entonces obtenemos el mismo resultado, independientemente de si se trata de una conversión explícita o implícita.

Esta es una conversión implícita porque no estamos usando una función de conversión para convertirla explícitamente. Simplemente estamos asignando el valor de una variable de un tipo de datos a una variable de otro tipo de datos. En este caso, SQL Server realiza una conversión implícita entre bastidores cuando intentamos asignar la hora valor a un datetime2 variables.

Ejemplo 5:cambiar la fecha

Si necesita cambiar la fecha (pero mantener la misma hora), puede usar DATEADD() función.

DECLARE @thetime time, @thedatetime2 datetime2;
SET @thetime = '23:15:59.004007';
SET @thedatetime2 = @thetime;
SET @thedatetime2 = DATEADD(year, 120, @thedatetime2);
SELECT 
  @thetime AS 'time',
  @thedatetime2 AS 'datetime2';

Resultado:

+------------------+-----------------------------+
| time             | datetime2                   |
|------------------+-----------------------------|
| 23:15:59.0040070 | 2020-01-01 23:15:59.0040070 |
+------------------+-----------------------------+

En este caso, agrego 120 al valor del año, lo que lo lleva a 2020.