Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Converti "datetimeoffset" in "time" in SQL Server (esempi T-SQL)

Se hai un datetimeoffset valore, ma non è necessaria la parte di offset di data e fuso orario, convertendola in ora ti farà risparmiare molto spazio di archiviazione (rimuovendo i dettagli non necessari dal valore). Questo articolo contiene esempi di conversione di un datetimeoffset valore a un tempo valore in SQL Server.

Il datatimeoffset il tipo di dati include la data e l'ora con una differenza di fuso orario. Ha anche una parte di secondi frazionari compresa tra 0 e 7 (questo dipende da quanti secondi frazionari gli vengono assegnati). Questo viene fatto usando datetimeoffset(n) sintassi. Se non lo specifichi, utilizzerà 7 (l'impostazione predefinita). La dimensione di archiviazione di questo tipo di dati è 8, 9 o 10 byte, a seconda della precisione utilizzata. La sua precisione è di 100 nanosecondi.

Il tempo tipo di dati d'altra parte, include solo l'ora. Non include la data e non include l'offset del fuso orario. Tuttavia, simile a datetimeoffset ti permette anche di specificare una parte di secondi frazionari compresa tra 0 e 7 (usando il time(n) sintassi). Utilizza 3, 4 o 5 byte, a seconda della sua precisione.

Quando converti un datetimeoffset valore a un tempo tipo di dati, si perde la parte della data. Perdi anche l'offset del fuso orario. Tuttavia, si riduce anche la dimensione di archiviazione da 8 a 10 byte fino a 3, 4 o 5 byte. Tuttavia, faresti questa conversione solo se non hai bisogno della parte della data o dell'offset del fuso orario.

Si noti che gli importi di archiviazione elencati qui sono gli importi elencati nella documentazione Microsoft. Tuttavia, questi tipi di dati utilizzano anche 1 byte per memorizzare la precisione. Pertanto, dovrai aggiungere 1 byte agli importi elencati qui.

Esempio 1 – Conversione implicita

Ecco un esempio di conversione implicita tra datetimeoffset e tempo .

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';

Risultato:

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

Questa è una conversione implicita perché non stiamo usando una funzione di conversione (come quelle sotto) per convertirla in modo esplicito. In questo caso, SQL Server esegue una conversione implicita dietro le quinte quando proviamo ad assegnare il datetimeoffset valore a un tempo variabile.

Qui possiamo vedere che il tempo il valore include solo l'ora (senza il componente data). I componenti dell'offset di data e fuso orario sono stati rimossi dal valore.

In questo esempio, entrambi i tipi di dati utilizzano la precisione predefinita (che risulta in 7 cifre decimali). Ciò si traduce in datetimeoffset valore utilizzando 10 byte e il tempo valore utilizzando 5 byte.

Esempio 2 – Precisione

Il risultato esatto dipenderà dalle impostazioni di precisione per ciascun tipo di dati. Nel prossimo esempio il tempo value utilizza una precisione inferiore rispetto all'originale datetimeoffset valore:

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';

Risultato:

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

Il mio sistema mostra zeri finali, ma il punto è che il tempo value ora ha una precisione di sole 3 cifre decimali rispetto alle 7 cifre decimali utilizzate dal valore originale.

Ridurre la precisione può anche comportare il tempo valore arrotondato per eccesso. Ecco un esempio:

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';

Risultato:

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

In questo caso ci ritroviamo con una parte frazionaria di 124 invece di 123 , perché la cifra successiva era 5 o maggiore.

Esempio 3 – Conversione esplicita mediante CAST()

Ecco un esempio di conversione esplicita. In questo caso, utilizzo il CAST() funzione direttamente all'interno di SELECT istruzione da convertire in modo esplicito tra datetimeoffset e tempo .

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

Risultato:

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

Esempio 4 – Conversione esplicita mediante CONVERT()

Ecco un esempio di una conversione esplicita utilizzando CONVERT() funzione invece di CAST() .

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

Risultato:

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