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

Formato data SQL:come gestirlo in modo intelligente

Grazie alla diversità delle culture sulla Terra, abbiamo una varietà di formati di data. Per le date numeriche, abbiamo mese-giorno-anno, giorno-mese-anno e anno-mese-giorno. Abbiamo anche formati brevi e lunghi. Le date possono essere mescolate con il tempo, che è un'altra storia. Questa realtà ci segue al lavoro. Ecco perché il formato della data SQL non è qualcosa che possiamo prendere facilmente.

Nelle Filippine utilizziamo 2 formati:mese-giorno-anno e giorno-mese-anno. Mese-giorno-anno è il formato generale per le date numeriche. Ma con formati di data più lunghi, utilizziamo in modo intercambiabile giorno-mese-anno e mese-giorno-anno.

Al lavoro, non ho mai riscontrato un'impostazione del formato della data di SQL Server diversa da mese-giorno-anno. Tuttavia, varia nei rapporti e nei file per gli scambi di dati e il progetto Extract-Transform-Load (ETL). Per non parlare degli utenti che lo cambiano nelle loro stazioni per preferenze personali! Con tutti questi scenari, non affrontarli in modo appropriato è una ricetta da rompere.

Le tue app hanno a che fare con culture diverse? Questo è un altro livello di complessità e un problema quando si ha a che fare con questi vari formati di data SQL. In questo articolo, esploreremo lo standard per affrontare tutte queste varietà ed esempi. Continua a leggere fino alla fine! Ma prima di procedere, facciamo una breve deviazione su come SQL Server archivia le date.

Modalità di archiviazione delle date in SQL Server

Prova a indovinare. SQL Server archivia il 29/03/2021 alle 21:35 come nel database? Che ne dici del 29-03-2021? Sono memorizzati come stringhe formattate? Sulla base di questa documentazione di Microsoft, non è così.

Prendiamo ad esempio il tipo di dati DATE. Viene memorizzato come numero intero a 3 byte.

Come lo sappiamo?

Bene, Microsoft dice che è così ma non fornisce ulteriori informazioni. Non significa che non possiamo saperlo con certezza. Innanzitutto, il valore minimo del tipo di dati DATE è 01/01/0001 o 1 gennaio, 1 d.C. o Common Era. Per convertirlo in un numero intero, convertiamo prima quella data in VARBINARY, in questo modo:

SELECT CAST(CAST('01/01/0001' AS DATE) AS VARBINARY(3))

Il risultato è 0x000000 in formato esadecimale. Da questo valore, possiamo vedere che il valore intero di gennaio 1, 1 CE è 0. È logico perché è il valore DATE minimo.

Ora avanziamo di 1 giorno.

SELECT CAST(CAST('01/02/0001' AS DATE) AS VARBINARY(3))  -- January 2, 1 CE

Il risultato è 0x010000 . Questo è un po 'complicato, ma questo post ci ha dato un'idea. Non possiamo trattarlo come lo vediamo. I byte vengono invertiti e il valore esadecimale effettivo è 0x000001 . Se conosci un po' di numeri esadecimali, sai che questo è uguale a 1:è 1 giorno dal punto di partenza, 1 gennaio 1 d.C.

Ora, proviamo una data recente:29/03/2021.

SELECT CAST(CAST('03/29/2021' AS DATE) AS VARBINARY(3))

Il risultato è 0x55420B . Quando lo invertiamo, diventa 0x0B4255 . Questa volta, non possiamo conoscere il valore guardandolo. Quindi, lo moltiplichiamo per 1 come numero intero.

SELECT 0x0B4255 * CAST(1 AS INT)

Il risultato è 737.877 . Questo è il numero di giorni dal 1 gennaio 1 d.C. Verifichiamolo con DATEDIFF.

SELECT DATEDIFF(DAY,CAST('01/01/0001' AS DATE),CAST('03/29/2021' AS DATE))

Il risultato è lo stesso:737.877 giorni. Molto bello!

Riga in basso:la data formattata è solo a scopo di presentazione

Ecco come SQL Server archivia i tipi di dati DATE. È diverso per DATETIME, SMALLDATETIME e DATETIME2, ma viene comunque memorizzato come numeri interi. SQL Server calcola la durata del tempo dal punto di partenza e visualizza la data che tutti possiamo capire.

Che tu lo stia guardando in SQL Server Management Studio, dbForge Studio per SQL Server o nella tua app, 29/03/2021 è solo una presentazione. Se modifichi la regione o la lingua, il valore memorizzato 0x55420B rimarrà lo stesso.

Ora sappiamo che le date non vengono memorizzate come stringhe. Possiamo dimenticare di memorizzare le date in un formato specifico . Non è così che funziona comunque. Invece, esaminiamo diversi modi in SQL per formattare le date di cui le tue app hanno bisogno.

I 4 semplici modi per formattare le date

Esaminiamo le seguenti funzioni di data SQL:

  • Funzione CONVERTI
  • IMPOSTA LINGUA
  • IMPOSTA FORMATO DATA
  • Funzione FORMATTA

Puoi anche utilizzare un formattatore di query SQL.

1. CONVERTI Funzione

CONVERT è una delle funzioni di conversione dei dati che può servire anche per la formattazione della data. La figura 1 mostra un esempio.

I primi due argomenti di CONVERT sono il tipo di dati di destinazione e il valore della data. Il terzo è facoltativo ma vale anche per le date. I valori numerici sono gli stili di formato della data SQL da utilizzare durante la conversione da data a stringa.

Nella Figura 1, il Giappone utilizza un formato anno-mese-giorno con una barra come separatore. La Germania utilizza giorno-mese-anno con punti come separatori. Gran Bretagna e Francia usano la stessa sequenza della Germania, ma con una barra come separatore. Solo gli Stati Uniti utilizzano mese-giorno-anno con un trattino come separatore.

In SQL, puoi anche convertire l'espressione DATETIME in DATE.

Per un elenco completo degli stili di formato della data CONVERT in SQL, controlla questo riferimento di Microsoft.

2. IMPOSTA LINGUA

Questa impostazione specifica la lingua applicata alla sessione. Influisce sui formati della data e sui messaggi di sistema. Quando imposti una lingua, applichi implicitamente anche le impostazioni SET DATEFORMAT (lo risolveremo in seguito).

Per ora, controlliamo gli esempi nella Figura 2. Sto cambiando le impostazioni della lingua in lituano e poi di nuovo in inglese.

Guarda la Figura 2. Il formato della data lituana è anno-mese-giorno. Ogni volta che provo date diverse, la data lunga include sempre 'm.' prima del mese e 'd.' dopo il giorno. Anche la prima lettera del mese e il nome del giorno della settimana non sono in maiuscolo. È diverso per le altre impostazioni della lingua, ma hai capito.

Per ulteriori informazioni su SET LANGUAGE, consulta questo riferimento di Microsoft.

3. IMPOSTA FORMATO DATA

Questa impostazione inserisce l'ordine del mese, del giorno e dell'anno per l'interpretazione delle stringhe di caratteri della data. Sovrascriverà le impostazioni del formato della data implicita eseguite da SET LANGUAGE. Ecco un esempio nella Figura 3.

Nella Figura 3, il codice utilizza il formato GMA o giorno-mese-anno. In queste impostazioni, qualsiasi valore di data impostato su una variabile di data dovrebbe seguire questo schema. Il 30/03/2021 corrisponde a questo formato, ma il 31/03/2021 genera un errore perché 31 non è un mese valido.

Pertanto, le modifiche al formato della data potrebbero interrompere l'app se la logica opera sulla base di un altro formato.

Per ulteriori informazioni su SET DATEFORMAT, consulta questo riferimento di Microsoft.

4. FORMATO Funzione

Di tutte le opzioni di formattazione disponibili, questa è la più flessibile. È simile per la formattazione della data in .Net, poiché FORMAT si basa sulla presenza di .Net Framework sul server in cui è installato SQL Server. Questo è lo svantaggio di questa opzione, tuttavia.

Proprio come in C#, FORMAT accetta un valore di data e una stringa di formato. Facciamo alcuni esempi nella Figura 4.

Come in .Net, in SQL Server puoi formattare le date utilizzando diversi separatori. Inoltre, puoi posizionare il mese, il giorno e l'anno ovunque. Quindi, puoi ottenere le informazioni culturali e utilizzare il formato della data.

Per ulteriori informazioni ed esempi su FORMAT, consulta questo riferimento di Microsoft.

Ora, abbiamo identificato 4 modi per formattare le date e la varietà di formati di data. Esiste un formato standard che funzioni sempre durante la conversione di stringhe in date?

ISO 8601:il formato di data SQL più portatile e privo di errori che puoi utilizzare per la conversione

La ISO 8601 esiste dal 1988. È lo standard internazionale negli scambi di dati relativi a date e orari .

È anche disponibile nella funzione CONVERT come uno degli stili di formato della data:gli stili 126 e 127 sono conformi a ISO 8601.

Cosa lo rende portatile e privo di errori?

Il problema con i formati non ISO 8601

Dimostriamo il problema per la non ISO 8601 con un esempio:

DECLARE @d VARCHAR(10) = '03/09/2021';

SET LANGUAGE Italian;
SELECT FORMAT(CONVERT(DATETIME, @d),'D')
SET LANGUAGE English
SELECT FORMAT(CONVERT(DATETIME, @d),'D')

SET DATEFORMAT DMY
SELECT FORMAT(CONVERT(DATETIME, @d),'D')
SET DATEFORMAT MDY
SELECT FORMAT(CONVERT(DATETIME, @d),'D')

A seconda della località della tua data, puoi interpretare @d come 9 marzo 2021 o 3 settembre 2021. Non puoi essere sicuro di quale. Ecco dove sta il problema.

Controlla il risultato nella Figura 5 di seguito:

Nemmeno SQL Server lo sa per certo!

Peggio ancora, questo tipo di scenario può interrompere la tua app proprio come è successo nella Figura 3 in precedenza. Questa situazione è problematica per le app che si occupano di utenti multiculturali.

La ISO 8601 può aiutare in questo?

Utilizzo di ISO 8601 per risolvere i problemi di formattazione

Nota quando il formato ISO 8601 aaaaMMgg viene utilizzato al posto di MM/gg/aaaa e controlla il risultato in Figura 6:

Sarà sempre il 9 marzo, indipendentemente dalla lingua e dalle impostazioni del formato della data utilizzate. Questo è ottimo per lo scambio di dati e le integrazioni di sistema. Se il tuo utente ha un altro formato di data nella stazione, non importa neanche.

Se devi trasformare le tue date in stringhe e viceversa, usa ISO 8601.

ISO 8601 in SQL Server è disponibile in 2 versioni:

  • AAAAMMGG è solo per le date.
  • AAAA-MM-GGTHH:MM:SS per un mix di data e ora, dove T è il delimitatore tra data e ora.

Altri modi per gestire i formati di data dalle app a SQL Server

1. Usa i controlli di riconoscimento della data nell'app

Quando chiedi a un utente di inserire le date in un modulo, non consentire loro di utilizzare testo libero. Utilizza i controlli della data che consentono di scegliere solo tra valori validi.

2. Converti in un formato diverso solo quando necessario

Non continuare a trasformare le date in stringhe e viceversa. Usa i tipi di dati Data o DateTime nativi dell'app chiamante. Se hai bisogno di trasformarli per qualsiasi motivo, usa ISO 8601.

3. Imposta la data/ora, il fuso orario e la cultura nell'avvio dell'app, se applicabile

Se la tua app utilizza un formato di data fisso e ai tuoi utenti piace modificare i formati di data, puoi correggere entrambi all'avvio dell'applicazione. Imposta in modo esplicito ciò di cui la tua app ha bisogno. Sarà molto meglio se il tuo amministratore di rete può bloccare queste impostazioni.

Da asporto

Quindi, la gestione di varietà di formati di data SQL è schiacciante? Non posso biasimarti se la trovi ancora così, ma abbiamo scoperto che non è impossibile.

Ecco cosa abbiamo trattato:

  • Le date SQL vengono memorizzate come numeri interi . Quello che vediamo con i nostri occhi è già formattato in base alle impostazioni di SQL Server. Non importa quante volte cambiamo lingua e formato della data, il valore memorizzato rimarrà lo stesso. È inutile pensare di memorizzare le date in un formato specifico.
  • Ci sono 4 modi per formattare le date:CONVERTI , IMPOSTA LINGUA , IMPOSTA FORMATO DATA e FORMATO .
  • Se devi trasformare le date in stringhe e viceversa, usa il formato ISO 8601 .
  • Ci sono altri 3 modi per gestire i formati di data:
    • utilizzando i controlli sensibili alla data nella tua app;
    • trasformare le date in stringhe solo quando necessario;
    • impostazione del fuso orario, della cultura, della data/ora del server all'avvio, se applicabile .

Pensi che questo sarà utile a te e agli altri? Quindi, condividi questo articolo sulle tue piattaforme di social media preferite.