Dank der Vielfalt der Kulturen auf der Erde haben wir eine Vielzahl von Datumsformaten. Für numerische Daten haben wir Monat-Tag-Jahr, Tag-Monat-Jahr und Jahr-Monat-Tag. Wir haben auch kurze und lange Formate. Daten können mit der Zeit vermischt werden, was eine andere Geschichte ist. Diese Realität folgt uns bei der Arbeit. Deshalb können wir das SQL-Datumsformat nicht einfach hinnehmen.
Auf den Philippinen verwenden wir 2 Formate:Monat-Tag-Jahr und Tag-Monat-Jahr. Monat-Tag-Jahr ist das allgemeine Format für numerische Daten. Bei längeren Datumsformaten verwenden wir jedoch abwechselnd Tag-Monat-Jahr und Monat-Tag-Jahr.
Bei der Arbeit bin ich nie auf eine andere SQL Server-Datumsformateinstellung als Monat-Tag-Jahr gestoßen. Es variiert jedoch in Berichten und Dateien für Datenaustausch und ETL-Projekt (Extract-Transform-Load). Ganz zu schweigen von Benutzern, die es in ihren Stationen für persönliche Vorlieben ändern! Bei all diesen Szenarien ist ein unangemessener Umgang mit ihnen ein Rezept zum Durchbrechen.
Befassen sich Ihre Apps mit unterschiedlichen Kulturen? Das ist eine weitere Ebene der Komplexität und ein Problem beim Umgang mit diesen verschiedenen SQL-Datumsformaten. In diesem Artikel werden wir den Standard untersuchen, um mit all diesen Varianten und Beispielen umzugehen. Lesen Sie weiter bis zum Ende! Aber bevor wir fortfahren, machen wir einen kurzen Abstecher darüber, wie SQL Server Daten speichert.
Wie SQL Server Daten speichert
Raten Sie mal. Speichert SQL Server den 29.03.2021 21:35 unverändert in der Datenbank? Wie wäre es mit 2021-03-29? Werden sie als formatierte Zeichenfolgen gespeichert? Basierend auf dieser Dokumentation von Microsoft ist es nicht so.
Nehmen wir zum Beispiel den Datentyp DATE. Es wird als 3-Byte-Integer gespeichert.
Woher wissen wir das?
Nun, Microsoft sagt, dass es so ist, liefert aber keine weiteren Informationen. Das bedeutet nicht, dass wir es nicht sicher wissen können. Erstens ist der Mindestwert des DATE-Datentyps 01.01.0001 oder 1. Januar 1 CE oder Common Era. Um dies in eine Ganzzahl umzuwandeln, konvertieren wir dieses Datum zuerst in VARBINARY, wie folgt:
SELECT CAST(CAST('01/01/0001' AS DATE) AS VARBINARY(3))
Das Ergebnis ist 0x000000 im Hexadezimalformat. Aus diesem Wert können wir ersehen, dass der ganzzahlige Wert vom 1. Januar 1 CE 0 ist. Es ist logisch, weil dies der minimale DATE-Wert ist.
Jetzt rücken wir 1 Tag vor.
SELECT CAST(CAST('01/02/0001' AS DATE) AS VARBINARY(3)) -- January 2, 1 CE
Das Ergebnis ist 0x010000 . Das ist ein wenig knifflig, aber dieser Beitrag hat uns eine Idee gegeben. Wir können es nicht so behandeln, wie wir es sehen. Die Bytes sind vertauscht und der tatsächliche Hex-Wert ist 0x000001 . Wenn Sie sich ein wenig mit Hex-Zahlen auskennen, wissen Sie, dass dies gleich 1 ist – es ist 1 Tag vom Startpunkt, dem 1. Januar, 1 CE.
Versuchen wir es jetzt mit einem aktuellen Datum:29.03.2021.
SELECT CAST(CAST('03/29/2021' AS DATE) AS VARBINARY(3))
Das Ergebnis ist 0x55420B . Wenn wir es umkehren, wird es zu 0x0B4255 . Diesmal können wir den Wert nicht erkennen, indem wir ihn uns ansehen. Also multiplizieren wir es mit 1 als ganze Zahl.
SELECT 0x0B4255 * CAST(1 AS INT)
Das Ergebnis ist 737.877 . Dies ist die Anzahl der Tage ab dem 1. Januar 1 CE. Lassen Sie es uns mit DATEDIFF überprüfen.
SELECT DATEDIFF(DAY,CAST('01/01/0001' AS DATE),CAST('03/29/2021' AS DATE))
Das Ergebnis ist dasselbe:737.877 Tage. Sehr cool!
Fazit:Das formatierte Datum dient nur zu Präsentationszwecken
So speichert SQL Server DATE-Datentypen. Es ist anders für DATETIME, SMALLDATETIME und DATETIME2, aber immer noch als ganze Zahlen gespeichert. SQL Server berechnet die Zeitdauer ab dem Startpunkt und zeigt das für uns alle verständliche Datum an.
Ob Sie es in SQL Server Management Studio, dbForge Studio für SQL Server oder Ihrer App betrachten, der 29.03.2021 ist nur eine Präsentation. Wenn Sie die Region oder Sprache ändern, wird der gespeicherte Wert 0x55420B bleibt gleich.
Jetzt wissen wir, dass Datumsangaben nicht als Zeichenketten gespeichert werden. Wir können das Speichern von Daten in einem bestimmten Format vergessen . So funktioniert es jedenfalls nicht. Schauen wir uns stattdessen verschiedene Möglichkeiten in SQL an, um Daten zu formatieren, die Ihre Apps benötigen.
Die 4 einfachen Möglichkeiten, Datumsangaben zu formatieren
Sehen wir uns die folgenden SQL-Datumsfunktionen an:
- CONVERT-Funktion
- SPRACHE EINSTELLEN
- DATUMSFORMAT EINSTELLEN
- FORMAT-Funktion
Sie können auch einen SQL-Abfrageformatierer verwenden.
1. CONVERT-Funktion
CONVERT ist eine der Datenkonvertierungsfunktionen, die auch zur Datumsformatierung dienen kann. Abbildung 1 zeigt ein Beispiel.
Die ersten beiden Argumente von CONVERT sind der Zieldatentyp und der Datumswert. Der dritte ist optional, gilt aber auch für Datteln. Die numerischen Werte sind die SQL-Datumsformatstile, die während der Konvertierung von Datum in Zeichenfolge verwendet werden.
In Abbildung 1 verwendet Japan ein Jahr-Monat-Tag-Format mit einem Schrägstrich als Trennzeichen. Deutschland verwendet Tag-Monat-Jahr mit Punkten als Trennzeichen. Großbritannien und Frankreich verwenden die gleiche Reihenfolge wie Deutschland, jedoch mit einem Schrägstrich als Trennzeichen. Nur die Vereinigten Staaten verwenden Monat-Tag-Jahr mit einem Bindestrich als Trennzeichen.
In SQL können Sie den DATETIME-Ausdruck auch in DATE.
umwandelnEine vollständige Liste der CONVERT-Datumsformatstile in SQL finden Sie in dieser Referenz von Microsoft.
2. SPRACHE EINSTELLEN
Diese Einstellung gibt die Sprache an, die auf die Sitzung angewendet wird. Es wirkt sich auf die Datumsformate und Systemmeldungen aus. Wenn Sie eine Sprache festlegen, wenden Sie implizit auch die SET DATEFORMAT-Einstellungen an (wir werden das später ausarbeiten).
Schauen wir uns zunächst die Beispiele in Abbildung 2 an. Ich ändere die Spracheinstellungen auf Litauisch und dann wieder auf Englisch.
Schauen Sie sich Abbildung 2 an. Das litauische Datumsformat ist Jahr-Monat-Tag. Immer wenn ich verschiedene Daten ausprobiere, enthält das lange Datum immer „m.“ vor dem Monat und „d.“ nach dem Tag. Auch der erste Buchstabe des Monats und der Name des Wochentags werden nicht groß geschrieben. Bei anderen Spracheinstellungen ist es anders, aber Sie verstehen, worauf es ankommt.
Weitere Informationen zu SET LANGUAGE finden Sie in dieser Referenz von Microsoft.
3. DATUMFORMAT EINSTELLEN
Diese Einstellung legt die Reihenfolge von Monat, Tag und Jahr für die Interpretation von Datumszeichenfolgen fest. Es überschreibt die impliziten Datumsformateinstellungen, die von SET LANGUAGE vorgenommen wurden. Hier ist ein Beispiel in Abbildung 3.
In Abbildung 3 verwendet der Code das DMY- oder Tag-Monat-Jahr-Format. Unter diesen Einstellungen sollte jeder auf eine Datumsvariable festgelegte Datumswert diesem Muster folgen. 30.03.2021 entspricht diesem Format, aber 31.03.2021 löst einen Fehler aus, da 31 kein gültiger Monat ist.
Daher können Änderungen am Datumsformat Ihre App beschädigen, wenn die Logik auf der Prämisse eines anderen Formats basiert.
Weitere Informationen zu SET DATEFORMAT finden Sie in dieser Referenz von Microsoft.
4. FORMAT-Funktion
Von allen verfügbaren Formatierungsoptionen ist diese die flexibelste. Ähnlich verhält es sich mit der Datumsformatierung in .Net, da FORMAT auf das Vorhandensein von .Net Framework auf dem Server angewiesen ist, auf dem SQL Server installiert ist. Das ist jedoch der Nachteil dieser Option.
Genau wie in C# nimmt FORMAT einen Datumswert und eine Formatzeichenfolge. Sehen wir uns einige Beispiele in Abbildung 4 an.
Wie in .Net können Sie in SQL Server Datumsangaben mit verschiedenen Trennzeichen formatieren. Außerdem können Sie Monat, Tag und Jahr beliebig positionieren. Dann können Sie die kulturellen Informationen abrufen und ihr Datumsformat verwenden.
Weitere Informationen und Beispiele zu FORMAT finden Sie in dieser Referenz von Microsoft.
Jetzt haben wir 4 Möglichkeiten zum Formatieren von Datumsangaben und die Vielfalt der Datumsformate identifiziert. Gibt es ein Standardformat, das beim Konvertieren von Zeichenfolgen in Datumsangaben immer funktioniert?
ISO 8601 – Das portabelste, fehlerfreiste SQL-Datumsformat, das Sie für die Konvertierung verwenden können
ISO 8601 gibt es seit 1988. Es ist der internationale Standard im Austausch von Daten zu Datum und Uhrzeit .
Es ist auch in der CONVERT-Funktion als einer der Datumsformatstile verfügbar:Stile 126 und 127 sind ISO 8601-kompatibel.
Was macht es portabel und fehlerfrei?
Das Problem mit Nicht-ISO 8601-Formaten
Lassen Sie uns das Problem für Nicht-ISO 8601 anhand eines Beispiels demonstrieren:
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')
Abhängig von Ihrem Datumsgebietsschema können Sie @d als 9. März 2021 oder 3. September 2021 interpretieren. Sie können nicht sicher sein, welches was ist. Darin liegt das Problem.
Überprüfen Sie das Ergebnis in Abbildung 5 unten:
Selbst SQL Server weiß es nicht genau!
Im schlimmsten Fall kann diese Art von Szenario Ihre App beschädigen, genau wie in Abbildung 3 zuvor. Diese Situation ist problematisch für Apps, die sich mit multikulturellen Benutzern befassen.
Kann ISO 8601 dabei helfen?
Verwendung von ISO 8601 zur Behandlung von Formatierungsproblemen
Beachten Sie, wenn das ISO 8601-Format yyyyMMdd wird anstelle von MM/tt/jjjj verwendet und überprüfen Sie das Ergebnis in Abbildung 6:
Es wird immer der 9. März sein, egal welche Sprach- und Datumsformateinstellungen verwendet werden. Dies ist großartig für Datenaustausch und Systemintegrationen. Wenn Ihr Benutzer ein anderes Datumsformat in der Station hat, spielt es auch keine Rolle.
Wenn Sie Ihre Daten in Zeichenfolgen und zurück umwandeln müssen, verwenden Sie ISO 8601.
ISO 8601 in SQL Server gibt es in zwei Varianten:
- JJJJMMTT ist nur für Daten.
- JJJJ-MM-TTTHH:MM:SS für eine Mischung aus Datum und Uhrzeit, wobei T das Trennzeichen zwischen Datum und Uhrzeit ist.
Andere Möglichkeiten zur Handhabung von Datumsformaten von Apps zu SQL Server
1. Verwenden Sie datumsbezogene Steuerelemente in der App
Wenn Sie einen Benutzer bitten, Daten in ein Formular einzugeben, lassen Sie ihn keinen freien Text verwenden. Verwenden Sie Datumssteuerelemente, die nur die Auswahl aus gültigen Werten zulassen.
2. Nur bei Bedarf in ein anderes Format konvertieren
Wandeln Sie Datumsangaben nicht ständig in Zeichenfolgen um und umgekehrt. Verwenden Sie die nativen Date- oder DateTime-Datentypen der aufrufenden App. Wenn Sie sie aus irgendeinem Grund umwandeln müssen, verwenden Sie ISO 8601.
3. Legen Sie Datum/Uhrzeit, Zeitzone und Kultur bei Ihrem App-Start fest, falls zutreffend
Wenn Ihre App ein festes Datumsformat verwendet und Ihre Benutzer die Datumsformate gerne optimieren, können Sie beides beim Start der Anwendung korrigieren. Legen Sie explizit fest, was Ihre App benötigt. Es ist viel besser, wenn Ihr Netzwerkadministrator diese Einstellungen sperren kann.
Imbiss
Ist der Umgang mit verschiedenen SQL-Datumsformaten also überwältigend? Ich kann es dir nicht verübeln, wenn du es immer noch so findest, aber wir haben herausgefunden, dass es nicht unmöglich ist.
Folgendes haben wir behandelt:
- SQL-Daten werden als Ganzzahlen gespeichert . Was wir mit unseren Augen sehen, ist bereits basierend auf den SQL Server-Einstellungen formatiert. Egal wie oft wir die Sprache und das Datumsformat ändern, der gespeicherte Wert bleibt gleich. Es ist sinnlos, daran zu denken, Datumsangaben in einem bestimmten Format zu speichern.
- Es gibt 4 Möglichkeiten, Datumsangaben zu formatieren:KONVERTIEREN , SPRACHE EINSTELLEN , DATUMSFORMAT EINSTELLEN und FORMAT .
- Wenn Sie Datumsangaben in Zeichenfolgen und umgekehrt umwandeln müssen, verwenden Sie das ISO 8601-Format .
- Es gibt 3 weitere Möglichkeiten, mit Datumsformaten umzugehen:
- Datum berücksichtigende Steuerelemente verwenden in Ihrer App;
- Datum nur bei Bedarf in Zeichenketten umwandeln;
- Festlegen der erforderlichen Zeitzone, Kultur, Datum/Uhrzeit des Servers beim Start, falls zutreffend .
Denken Sie, dass dies für Sie und andere nützlich sein wird? Dann teilen Sie diesen Artikel bitte auf Ihren bevorzugten Social-Media-Plattformen.