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

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

Questo articolo contiene esempi di conversione di un smalldatetime valore a un datetimeoffset valore in SQL Server.

Quando converti un smalldatetime valore a datetimeoffset , il smalldatetime il valore viene copiato in datetimeoffset valore. I secondi frazionari sono impostati su 0 e l'offset del fuso orario è impostato su +00:0.

Il smalldatetime il tipo di dati non ha secondi frazionari e il relativo componente secondi è sempre impostato su zero (:00). La sua precisione è al minuto più vicino.

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 (l'impostazione predefinita). Ha anche un offset di fuso orario e può conservare qualsiasi offset nel valore originale. Tuttavia, smalldatetime non ha consapevolezza del fuso orario, quindi non ci sono valori esistenti da preservare. In questo caso, l'offset del fuso orario è impostato su +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, vedi sotto per i miei commenti e alcuni esempi relativi a questa opzione.

Esempio 1 – Conversione implicita

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

DECLARE 
  @thesmalldatetime smalldatetime, 
  @thedatetimeoffset datetimeoffset(7);
SET @thesmalldatetime = '2025-05-21 10:15:30';
SET @thedatetimeoffset = @thesmalldatetime;
SELECT 
  @thesmalldatetime AS 'smalldatetime',
  @thedatetimeoffset AS 'datetimeoffset(7)';

Risultato:

+---------------------+------------------------------------+
| smalldatetime       | datetimeoffset(7)                  |
|---------------------+------------------------------------|
| 2025-05-21 10:16:00 | 2025-05-21 10:16:00.0000000 +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 smalldatetime valore a un datetimeoffset variabile.

Possiamo vedere che il datetimeoffset la variabile ha una parte frazionaria ( 0000000 ), mentre il smalldatetime value non ha parte frazionaria e i suoi minuti sono stati arrotondati per eccesso durante l'assegnazione del valore iniziale. Il datatimeoffset il valore include anche un fuso orario di +00:00 .

L'utilizzo di una precisione di 7 secondi frazionari provoca datetimeoffset utilizzare 11 byte per la memorizzazione (10 byte per memorizzare i dati, 1 byte per la precisione). In confronto, smalldatetime utilizza solo 4 byte. Tuttavia, puoi ridurre la precisione di datetimeoffset valore sostituendo il 7 con un numero inferiore. Se vuoi rimuovere del tutto la parte dei secondi frazionari, usa semplicemente datetimeoffset(0) . In questo modo si ridurrà la dimensione della memoria a 9 byte (di cui 1 per la precisione).

Esempio 2 – 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 smalldatetime e datetimeoffset .

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

Risultato:

+---------------------+------------------------------------+
| smalldatetime       | datetimeoffset(7)                  |
|---------------------+------------------------------------|
| 2025-05-21 10:16:00 | 2025-05-21 10:16:00.0000000 +00:00 |
+---------------------+------------------------------------+

Esempio 3 – Conversione esplicita mediante CONVERT()

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

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

Risultato:

+---------------------+------------------------------------+
| smalldatetime       | datetimeoffset(7)                  |
|---------------------+------------------------------------|
| 2025-05-21 10:16:00 | 2025-05-21 10:16:00.0000000 +00:00 |
+---------------------+------------------------------------+

Esempio 4 – Modifica dell'offset del fuso orario

Il fatto che stai convertendo il tuo smalldatetime valori su datetimeoffset significa che probabilmente lo stai facendo per l'offset del fuso orario. Ed è probabile che tu voglia impostarlo su un offset diverso da +00:00 (l'offset predefinito).

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

Puoi anche utilizzare questa funzione per convertire il smalldatetime 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 @thesmalldatetime smalldatetime, @thedatetimeoffset datetimeoffset;
SET @thesmalldatetime = '2025-05-21 10:15:30';
SET @thedatetimeoffset = TODATETIMEOFFSET(@thesmalldatetime, '+07:00');
SELECT 
  @thesmalldatetime AS 'smalldatetime',
  @thedatetimeoffset AS 'datetimeoffset';

Risultato:

+---------------------+------------------------------------+
| smalldatetime       | datetimeoffset                     |
|---------------------+------------------------------------|
| 2025-05-21 10:16:00 | 2025-05-21 10:16:00.0000000 +07:00 |
+---------------------+------------------------------------+

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

DECLARE @thesmalldatetime smalldatetime = '2025-05-21 10:15:30';
SELECT 
  @thesmalldatetime AS 'smalldatetime',
  TODATETIMEOFFSET(@thesmalldatetime, '+07:00') AS 'datetimeoffset';

Risultato:

+---------------------+------------------------------------+
| smalldatetime       | datetimeoffset                     |
|---------------------+------------------------------------|
| 2025-05-21 10:16:00 | 2025-05-21 10:16:00.0000000 +07:00 |
+---------------------+------------------------------------+

Un punto importante su TODATETIMEOFFSET() funzione è che utilizza la stessa precisione frazionaria dell'argomento data/ora passato. In questo caso è un smalldatetime argomento, che non ha secondi frazionari.

Il mio sistema restituisce zeri finali con datetimeoffset parte frazionaria, tuttavia, potresti vedere qualcosa del genere:

+---------------------+----------------------------+
| smalldatetime       | datetimeoffset             |
|---------------------+----------------------------|
| 2025-05-21 10:16:00 | 2025-05-21 10:16:00 +07:00 |
+---------------------+----------------------------+

In ogni caso, puoi comunque sfruttare appieno il datetimeoffset la precisione del tipo di dati se è necessario modificare il valore in un secondo momento.

Ecco un esempio che utilizza DATEADD() funzione per modificare i secondi frazionari dopo che la conversione è già stata eseguita.

DECLARE @thesmalldatetime smalldatetime, @thedatetimeoffset datetimeoffset(7);
SET @thesmalldatetime = '2025-05-21 10:15:30';
SET @thedatetimeoffset = TODATETIMEOFFSET(@thesmalldatetime, '+07:00');
SELECT 
  @thesmalldatetime AS 'smalldatetime',
  @thedatetimeoffset AS 'datetimeoffset',
  DATEADD(nanosecond, 123456700, @thedatetimeoffset) AS 'Modified';

Risultato (usando l'output verticale):

smalldatetime  | 2025-05-21 10:16:00
datetimeoffset | 2025-05-21 10:16:00.0000000 +07:00
Modified       | 2025-05-21 10:16:00.1234567 +07:00