Questo articolo contiene esempi di conversione di un tempo valore a un datetime2 valore in SQL Server.
Quando converti un tempo valore a datetime2 , al valore vengono aggiunte informazioni aggiuntive. Questo perché datetime2 il tipo di dati contiene informazioni sulla data e sull'ora. Il tempo il tipo di dati, d'altra parte, contiene solo informazioni sull'ora.
In particolare, la data è impostata su '1900-01-01' (a meno che non venga arrotondato per eccesso a '1900-01-02'), la componente temporale viene copiata e, secondo la documentazione Microsoft, l'offset del fuso orario è impostato su 00:00 (anche se datetime2 il tipo di dati non è a conoscenza del fuso orario e non conserva alcun offset del fuso orario).
Quando la precisione frazionaria dei secondi di datetime2(n) il valore è maggiore di time(n) value, il valore viene arrotondato per eccesso.
Esempio 1 – Conversione esplicita mediante CAST()
Ecco un esempio di conversione esplicita. In questo caso, utilizzo il CAST()
funzione direttamente all'interno di SELECT
dichiarazione da convertire esplicitamente da tempo a dataora2 .
DECLARE @thetime time; SET @thetime = '23:15:59.004007'; SELECT @thetime AS 'time', CAST(@thetime AS datetime2) AS 'datetime2';
Risultato:
+------------------+-----------------------------+ | time | datetime2 | |------------------+-----------------------------| | 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 | +------------------+-----------------------------+
Quando effettui una conversione da tempo a dataora2 , viene aggiunto un componente data e impostato su 1900-01-01
.
Tuttavia, ci sono scenari in cui la data potrebbe essere arrotondata a 1900-01-02
. Questo dipenderà dai secondi frazionari e dalla precisione che usi. Vedi sotto per un esempio di questo.
Esempio 2 – Precisione frazionaria dei secondi
È possibile ottenere risultati diversi a seconda della precisione frazionaria di secondi assegnata a ciascun tipo di dati. Ciò dipenderà dal valore effettivo della parte frazionaria.
Nell'esempio precedente, entrambi i tipi di dati utilizzavano la stessa precisione di secondi frazionari. Questo perché non ho specificato una scala (per definire la loro precisione) e quindi entrambi hanno usato i loro valori di scala predefiniti (entrambi sono 7).
Giusto per essere chiari, scala è il numero di cifre a destra della virgola decimale in un numero. Precisione è il numero totale di cifre nel numero.
Ad ogni modo, in quell'esempio ho assegnato solo 6 decimali al valore iniziale, quindi alla fine viene aggiunto uno zero.
Ecco cosa succede se specifico una precisione maggiore per il tempo valore rispetto a datetime2 valore:
DECLARE @thetime time(7); SET @thetime = '23:15:59.1234567'; SELECT @thetime AS 'time', CAST(@thetime AS datetime2(4)) AS 'datetime2(4)';
Risultato:
+------------------+--------------------------+ | time | datetime2(4) | |------------------+--------------------------| | 23:15:59.1234567 | 1900-01-01 23:15:59.1235 | +------------------+--------------------------+
Specificando una scala da 4 a datetime2 value, il risultato viene ridotto a 4 cifre decimali e in questo caso viene arrotondato per eccesso.
Come ci si potrebbe aspettare, non è solo la parte frazionaria che può essere arrotondata. Ecco un esempio di dove la parte frazionaria determina l'arrotondamento per eccesso di minuti e secondi:
DECLARE @thetime time(7); SET @thetime = '23:15:59.7654321'; SELECT @thetime AS 'time', CAST(@thetime AS datetime2(0)) AS 'datetime2(0)';
Risultato:
+------------------+---------------------+ | time | datetime2(0) | |------------------+---------------------| | 23:15:59.7654321 | 1900-01-01 23:16:00 | +------------------+---------------------+
Tuttavia, è possibile ottenere risultati diversi per gli stessi dati modificando la precisione. Se aumentiamo la precisione, anche solo di un decimale, otteniamo questo:
DECLARE @thetime time(7); SET @thetime = '23:15:59.7654321'; SELECT @thetime AS 'time', CAST(@thetime AS datetime2(1)) AS 'datetime2(1)';
Risultato:
+------------------+-----------------------+ | time | datetime2(1) | |------------------+-----------------------| | 23:15:59.7654321 | 1900-01-01 23:15:59.8 | +------------------+-----------------------+
Quindi in questo caso i minuti e i secondi non erano arrotondato per eccesso (ma i millisecondi erano ).
Ecco cosa succede se imposto il ora valore per utilizzare una scala di precisione inferiore a datetime2 valore.
DECLARE @thetime time(0); SET @thetime = '23:15:59.004007'; SELECT @thetime AS 'time', CAST(@thetime AS datetime2) AS 'datetime2';
Risultato:
+----------+-----------------------------+ | time | datetime2 | |----------+-----------------------------| | 23:15:59 | 1900-01-01 23:15:59.0000000 | +----------+-----------------------------+
E già che ci siamo, ecco un esempio di dove la nostra scala di precisione può comportare l'arrotondamento della data al giorno successivo:
DECLARE @thetime time(7); SET @thetime = '23:59:59.9999999'; SELECT @thetime AS 'time', CAST(@thetime AS datetime2(0)) AS 'datetime2(0)';
Risultato:
+------------------+---------------------+ | time | datetime2(0) | |------------------+---------------------| | 23:59:59.9999999 | 1900-01-02 00:00:00 | +------------------+---------------------+
Esempio 3 – Conversione esplicita mediante CONVERT()
Questo è lo stesso del primo esempio, tranne che questa volta uso il CONVERT()
funzione invece di CAST()
.
DECLARE @thetime time; SET @thetime = '23:15:59.004007'; SELECT @thetime AS 'time', CONVERT(datetime2, @thetime) AS 'datetime2';
Risultato:
+------------------+-----------------------------+ | time | datetime2 | |------------------+-----------------------------| | 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 | +------------------+-----------------------------+
Esempio 4 – Conversione implicita
Ecco un esempio di come fare la stessa cosa, ma usando una conversione di tipo implicita.
DECLARE @thetime time, @thedatetime2 datetime2; SET @thetime = '23:15:59.004007'; SET @thedatetime2 = @thetime; SELECT @thetime AS 'time', @thedatetime2 AS 'datetime2';
Risultato:
+------------------+-----------------------------+ | time | datetime2 | |------------------+-----------------------------| | 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 | +------------------+-----------------------------+
Quindi otteniamo lo stesso risultato, indipendentemente dal fatto che si tratti di una conversione esplicita o implicita.
Questa è una conversione implicita perché non stiamo usando una funzione di conversione per convertirla in modo esplicito. Stiamo semplicemente assegnando il valore da una variabile di un tipo di dati a una variabile di un altro tipo di dati. In questo caso, SQL Server esegue una conversione implicita dietro le quinte quando proviamo ad assegnare il tempo valore a un datetime2 variabile.
Esempio 5:modifica della data
Se devi cambiare la data (ma mantenere la stessa ora), puoi usare il DATEADD()
funzione.
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';
Risultato:
+------------------+-----------------------------+ | time | datetime2 | |------------------+-----------------------------| | 23:15:59.0040070 | 2020-01-01 23:15:59.0040070 | +------------------+-----------------------------+
In questo caso aggiungo 120 al valore dell'anno, che lo porta al 2020.