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

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

Questo articolo contiene esempi di conversione di una data/ora valore a un datetimeoffset valore in SQL Server.

Quando converti un data/ora valore a datetimeoffset , il valore risultante dipenderà dalla precisione frazionaria di secondi che assegni a datetimeoffset , nonché qualsiasi differenza di fuso orario specificata.

La data e ora il tipo di dati ha un massimo di 3 cifre per la sua parte di secondi frazionari. La sua precisione è arrotondata a incrementi di .000, .003 o .007 secondi.

Il datatimeoffset il tipo di dati, d'altra parte, ti consente di specificare una precisione frazionaria di secondi da 0 a 7. Se non lo specifichi, utilizzerà 7 (il valore predefinito). Ha anche un offset di fuso orario e può conservare qualsiasi offset nel valore originale. Tuttavia, data e ora non ha consapevolezza del fuso orario, quindi non ci sono valori esistenti da preservare. In questo caso, l'offset di fuso orario predefinito è +00:00.

SQL Server ha effettivamente il TODATETIMEOFFSET() funzione, progettata specificamente per convertire un valore di data/ora in datetimeoffset e aggiungi un offset di fuso orario. Tuttavia, c'è un dettaglio sottile da tenere presente quando si utilizza questa funzione e lo spiego di seguito (con esempi).

Esempio 1 – Conversione implicita

Innanzitutto, ecco un esempio di conversione implicita tra datetime e datetimeoffset .

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

Risultato:

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

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 datetime valore a un datetimeoffset variabile.

Possiamo vedere che il datetimeoffset variabile ha una precisione di secondi frazionari maggiore e finiamo con una parte frazionaria di 1233333 (rispetto a 123 per la data e ora valore). Ci ritroviamo anche con uno scostamento del fuso orario di +00:00 .

L'utilizzo di una precisione di 7 secondi frazionari provoca datetimeoffset per utilizzare 10 byte per l'archiviazione (11 byte se si include il byte che ne memorizza la precisione). A titolo di confronto, datetime utilizza solo 8 byte. Tuttavia, puoi ridurre la precisione di datetimeoffset valore sostituendo il 7 con un numero inferiore. Questo è lo stesso concetto di quando si utilizza datetime2 tipo di dati. Vedere Converti "datetime" in "datetime2" in SQL Server per esempi di come ciò può influire sul risultato finale.

Esempio 2 – Arrotondamento

La data e ora il tipo di dati viene arrotondato per incrementi di .000, .003 o .007 secondi. Anche se lo imposti in modo esplicito su un altro valore, verrà arrotondato. Questo potrebbe causare molta confusione se non sei a conoscenza di come funziona. Non solo può creare confusione quando si utilizza datetime di per sé, può causare ulteriore confusione durante la conversione di quel valore in un altro tipo di dati.

Ecco un esempio che dimostra cosa intendo.

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

Risultato:

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

In questo esempio, ho impostato i secondi frazionari su 125 ma data e ora arrotondato per eccesso a 127 (perché questo tipo di dati può essere arrotondato solo a incrementi di .000, .003 o .007 secondi).

Il datatimeoffset valore d'altra parte, imposta i secondi frazionari su 1266667 .

Tuttavia, se dovessimo semplicemente impostare il valore iniziale su datetimeoffset in primo luogo, la sua parte frazionaria avrebbe restituito 1250000 .

Esempio 3 – 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 in modo esplicito tra datetime e datetimeoffset .

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

Risultato:

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

Esempio 4 – Conversione esplicita mediante CONVERT()

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

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

Risultato:

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

Esempio 5 – Modifica dell'offset del fuso orario

Se hai tutti i problemi di convertire il tuo datetime valori su datetimeoffset , probabilmente hai bisogno dell'offset del fuso orario. E c'è una forte possibilità che tu voglia che sia impostato su qualcosa di diverso da +00:00.

Fortunatamente, puoi usare TODATETIMEOFFSET() funzione per modificare l'offset.

Puoi anche utilizzare questa funzione per convertire la data/ora originale valore a un datetimeoffset valore. Questa funzione accetta un valore di data/ora (che può essere risolto in un datetime2 value) e un valore di offset.

Ecco un esempio:

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

Risultato:

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

Ed ecco un esempio che utilizza la funzione all'interno di SELECT dichiarazione:

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

Risultato:

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

Un punto importante su TODATETIMEOFFSET() funzione è che utilizza la stessa precisione frazionaria dell'argomento data/ora passato. In questo caso è un data/ora argomento, quindi ha una scala di 3 (cioè 3 secondi frazionari). Questo potrebbe essere o meno un problema per te. Se lo è, puoi sempre convertirlo in un datetimeoffset prima, passa quel valore convertito a TODATETIMEOFFSET() .

Esempio:

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

Risultato (usando l'output verticale):

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