SqlDateTime.MinValue! = DateTime.MinValue, warum?

70

Ich frage mich, warum SqlDateTime.MinValue nicht mit DateTime.MinValue identisch ist.

Dhanapal
quelle

Antworten:

131

Ich denke , der Unterschied zwischen SQL und .NET des Datums - Datentypen aus der Tatsache stammt , dass SQL Server Datetime - Datentyp, ist es Minimal- und Maximalwerte, und es ist Präzision sind viel älter als .NET des Datetime - Datentyp.

Mit dem Aufkommen von .NET entschied das Team, dass der Datetime-Datentyp einen natürlicheren Mindestwert haben sollte, und der 01/01/0001 scheint eine ziemlich logische Wahl zu sein, und dieser Wert ist sicherlich aus Programmiersprache und nicht aus Datenbanksicht natürlicher.

Übrigens gibt es in SQL Server 2008 eine Reihe neuer datumsbasierter Datentypen ( Datum , Uhrzeit , DateTime2 , DateTimeOffset ), die tatsächlich einen größeren Bereich und eine höhere Genauigkeit bieten und dem DateTime-Datentyp in .NET genau zugeordnet sind. Beispielsweise hat der Datentyp DateTime2 einen Datumsbereich von 0001-01-01 bis 9999-12-31.

Der Standarddatentyp "datetime" von SQL Server hatte immer einen Mindestwert von 01/01/1753 (und hat es tatsächlich immer noch!). Ich muss zugeben, auch ich war neugierig auf die Bedeutung dieses Wertes, ebenso wie das Graben. Was ich fand, war wie folgt:

In der Zeit zwischen 1 n. Chr. Und heute hat die westliche Welt tatsächlich zwei Hauptkalender verwendet: den julianischen Kalender von Julius Cäsar und den gregorianischen Kalender von Papst Gregor XIII. Die beiden Kalender unterscheiden sich nur in einer Regel: der Regel für die Entscheidung, was ein Schaltjahr ist. Im julianischen Kalender sind alle durch vier teilbaren Jahre Schaltjahre. Im Gregorianischen Kalender sind alle durch vier teilbaren Jahre Schaltjahre, mit der Ausnahme, dass durch 100 teilbare Jahre (aber nicht durch 400 teilbare Jahre) keine Schaltjahre sind. Somit sind die Jahre 1700, 1800 und 1900 Schaltjahre im julianischen Kalender, jedoch nicht im gregorianischen Kalender, während die Jahre 1600 und 2000 Schaltjahre in beiden Kalendern sind.

Als Papst Gregor XIII. 1582 seinen Kalender vorstellte, wies er auch an, die Tage zwischen dem 4. Oktober 1582 und dem 15. Oktober 1582 zu überspringen - das heißt, der Tag nach dem 4. Oktober sollte der 15. Oktober sein. Viele Länder verzögerte Umstellung jedoch. England und seine Kolonien wechselten erst 1752 von julianischer zu gregorianischer Rechnung, so dass für sie die übersprungenen Daten zwischen dem 4. September und dem 14. September 1752 lagen. Andere Länder wechselten zu anderen Zeiten, aber 1582 und 1752 sind die relevanten Daten für die DBMSs, die wir diskutieren.

Somit treten zwei Probleme mit der Datumsarithmetik auf, wenn man viele Jahre zurückreicht. Die erste ist, sollten Schaltjahre bevor der Wechsel nach den julianischen oder gregorianischen Regeln berechnet wird? Das zweite Problem ist, wann und wie mit den übersprungenen Tagen umgegangen werden soll.

So behandeln die Big Eight DBMS diese Fragen:

  • Stellen Sie sich vor, es gäbe keinen Schalter. Dies scheint der SQL-Standard zu erfordern, obwohl das Standarddokument unklar ist: Es heißt nur, dass Datumsangaben "durch die natürlichen Regeln für Datumsangaben unter Verwendung des Gregorianischen Kalenders eingeschränkt werden" - was auch immer "natürliche Regeln" sind. Dies ist die Option, die DB2 ausgewählt hat. Wenn vorgetäuscht wird, dass die Regeln eines einzelnen Kalenders immer auch dann gelten, wenn niemand von dem Kalender gehört hat, lautet der Fachbegriff, dass ein "proleptischer" Kalender in Kraft ist. So könnte man zum Beispiel sagen, dass DB2 einem proleptischen Gregorianischen Kalender folgt.

  • Vermeiden Sie das Problem vollständig. Microsoft und Sybase legten ihre Mindestdatumswerte auf den 1. Januar 1753 fest, sicher nach der Zeit, als Amerika den Kalender wechselte. Dies ist verteidigungsfähig, aber von Zeit zu Zeit tauchen Beschwerden auf, dass diesen beiden DBMS eine nützliche Funktionalität fehlt, über die die anderen DBMS verfügen und die der SQL-Standard erfordert.

  • Wählen Sie 1582. Dies hat Oracle getan. Ein Oracle-Benutzer würde feststellen, dass der datumsarithmetische Ausdruck 15. Oktober 1582 minus 4. Oktober 1582 einen Wert von 1 Tag ergibt (weil der 5. bis 14. Oktober nicht existiert) und dass das Datum 29. Februar 1300 gültig ist (weil der julianische Sprung- Jahresregel gilt). Warum hat Oracle zusätzliche Probleme, wenn der SQL-Standard dies nicht zu erfordern scheint? Die Antwort ist, dass Benutzer es möglicherweise benötigen. Historiker und Astronomen verwenden dieses Hybridsystem anstelle eines proleptischen Gregorianischen Kalenders. (Dies ist auch die Standardoption, die Sun bei der Implementierung der GregorianCalendar-Klasse für Java ausgewählt hat. Trotz des Namens ist GregorianCalendar ein Hybridkalender.)

Dieses obige Zitat stammt aus dem folgenden Link:

SQL-Leistungsoptimierung: Daten in SQL

CraigTP
quelle
2
Verlassen Sie sich ab i18n nicht darauf, dass alle SQL Server DatTime-Werte immer Gregorianisch sind. Russland und China (und andere osteuropäische Länder) wechselten im 20. Jahrhundert vom julianischen zum gregorianischen Kalender.
Richard
1
@ Richard - Einverstanden. Diese Dinge sollten zuerst ausführlich überprüft werden. Das ganze Geschäft, von Julian zu Gregorian auf der ganzen Welt zu wechseln, war eine trübe Zeit in der Geschichte, und ich bezweifle, dass immer ein einziger Satz endgültiger Regeln in jedem Fall angewendet werden kann.
CraigTP
1
Ich frage mich, welche Apps Daten vor dem 19. Jahrhundert oder vielleicht sogar vor der Archäologie der 1960er Jahre benötigen. Aber das beschränkt Archäologen, die SQL Server verwenden, auf 1753 oder 1582 mit Oracle.
Chris S
5
Apps, die Informationen über Testamente und Taten enthalten, enthalten häufig Informationen, die so alt sind.
MartW
12

Da in SQL Server das Mindestdatum, das in einem Datum / Uhrzeit-Feld (1753/1/1) gespeichert werden kann, nicht dem MinValue des Datentyps DateTime .NET (0001/1/1) entspricht.

Frederik Gheysels
quelle
1
Ja, das ist die richtige Antwort. Wenn Sie versuchen, ein DateTime.MinValue auf einem SqlServer zu speichern, wird eine Fehlermeldung angezeigt.
Stefan Steinegger
9
Ich bin mir nicht ganz sicher, wie dies die Frage des OP überhaupt beantwortet. Er fragte, warum sie nicht gleich seien. Diese Antwort sagt einfach "Ja, sie sind nicht gleich". Craigs Antwort war in Bezug auf das zugrunde liegende Problem viel offener.
NotMe
11

1753 war das Datum des ersten Anwenders des Gregorianischen Kalenders (England). Warum dies gegenüber dem 01.01.10001 gewählt wurde - es ist zweifellos ein Erbe aus der Zeit, als SQL Server in den 1990er Jahren Sybase war. Sie müssen die Entwurfsentscheidung frühzeitig getroffen haben und das Microsoft SQL-Team hat keinen Grund gesehen, sie zu ändern.

Seit der Explosion von .NET und der Integration in SQL Server gibt es jetzt das DateTime2- Objekt für die Kompatibilität. Wenn Sie ein NHibernate-Benutzer sind, können Sie diesen Typ in Ihren Typzuordnungen angeben, um DateTime.MinProbleme zu vermeiden

.NET-Daten berücksichtigen andere Kalender als den gregorianischen:

  • Kalender
    • ChineseLunisolarCalendar
    • EastAsianLunisolarCalendar
    • Gregorianischer Kalender
    • Hebräischer Kalender
    • HijriCalendar
    • Japanischer Kalender
    • JapaneseLunisolarCalendar
    • JulianCalendar
    • Koreanischer Kalender
    • KoreanLunisolarCalendar
    • Persischer Kalender
    • TaiwanKalender
    • TaiwanLunisolarCalendar
    • ThaiBuddhistCalendar
    • UmAlQuraCalendar

Der JulianCalendar enthält aktuelle Daten DateTime.MinValue

Chris S.
quelle
Hmmm, du hast eine andere Frage beantwortet. Die Frage ist "warum", nicht "wie arbeite ich
darum
7

Zwei verschiedene Gruppen entschieden, was "Minimum" für sie in Bezug auf Datum / Uhrzeit bedeutet.

Nikolaus
quelle
1
Ich denke, das ist die genaue Antwort. (keine Ironie)
Nothrow
1
Alter, wenn du herabgestimmt wirst, liegt es daran, dass du eine dumme Antwort gegeben hast ... "Weil ich es gesagt habe" zählt nicht als Antwort, wenn die fragende Person über 10 Jahre alt ist (und ich dort großzügig bin). Aber ich habe dich nicht herabgestimmt :-)
Gabriel Magana
5

SQL verwendet eine andere interne Darstellung für DateTime.

Leppie
quelle
6
Wie ist das hilfreich für die Frage von OP?
ANeves denkt, SE ist böse
1
@ ANeves Es ist sehr hilfreich. Angesichts der Tatsache, dass .NET und MSSQL durch mehr als 10 Jahre Computerentwicklung voneinander getrennt sind, würde dies bedeuten, dass sie wahrscheinlich keine unterschiedlichen Mindestdaten haben.
Contango
1
@Contango Es impliziert nichts dergleichen. Sie können für DateTime unterschiedliche interne Darstellungen haben und dennoch denselben willkürlichen Mindestwert haben (z. B. aus Kompatibilitätsgründen oder zur Implementierung eines bestimmten Standards). Außerdem wäre der Mindestwert in Abhängigkeit von der internen Darstellung eine Implementierung, die in die Spezifikation übergeht, was meiner Meinung nach eine sehr schlechte Sache ist.
ANeves hält SE für böse