Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SqlDateTime.MinValue !=DateTime.MinValue, warum?

Ich denke, der Unterschied zwischen Date von SQL und .NET Datentypen ergibt sich aus der Tatsache, dass die datetime von SQL Server Datentyp, seine Minimal- und Maximalwerte und seine Genauigkeit sind viel älter als der DateTime-Datentyp von .NET.

Mit dem Aufkommen von .NET entschied das Team, dass der Datetime-Datentyp natürlicher sein sollte Mindestwert, und 01.01.0001 scheint eine ziemlich logische Wahl zu sein, und sicherlich von einer Programmiersprache , statt Datenbank Perspektivisch ist dieser Wert natürlicher.

Übrigens gibt es bei SQL Server 2008 eine Reihe neuer datumsbasierter Datentypen (Date, Time, DateTime2, DateTimeOffset), die tatsächlich einen größeren Bereich und eine größere Genauigkeit bieten und eng dem DateTime-Datentyp in .NET entsprechen. Beispielsweise hat der Datentyp DateTime2 einen Datumsbereich von 01.01.0001 bis 31.12.9999.

Der Standard-Datentyp "datetime" von SQL Server hatte immer einen Mindestwert von 01.01.1753 (und hat ihn tatsächlich immer noch!). Ich muss zugeben, ich war auch neugierig auf die Bedeutung dieses Werts, also habe ich etwas gegraben. Was ich gefunden habe, war Folgendes:

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 zur Bestimmung, was ein Schaltjahr ist. Im Julianischen Kalender sind alle durch vier teilbaren Jahre Schaltjahre. Im gregorianischen Kalender sind alle durch vier teilbaren Jahre Schaltjahre, außer dass durch 100 teilbare Jahre (aber nicht durch 400 teilbar) keine Schaltjahre sind. Daher sind die Jahre 1700, 1800 und 1900 Schaltjahre im Julianischen Kalender, aber nicht im Gregorianischen Kalender, während die Jahre 1600 und 2000 in beiden Kalendern Schaltjahre sind.

Als Papst Gregor XIII. 1582 seinen Kalender einführte, ordnete er auch an, dass die Tage zwischen dem 4. Oktober 1582 und dem 15. Oktober 1582 übersprungen werden sollten – das heißt, er sagte, dass der Tag nach dem 4. Oktober der 15. Oktober sein sollte. Viele Länder verspätete Umstellung aber. England und seine Kolonien wechselten erst 1752 von der julianischen zur gregorianischen Rechnungslegung, daher lagen die übersprungenen Daten für sie zwischen dem 4. September und dem 14. September 1752. Andere Länder wechselten zu anderen Zeiten, aber 1582 und 1752 sind die relevanten Daten für die DBMSs, die wir diskutieren.

Somit treten bei der Datumsarithmetik zwei Probleme auf, wenn man viele Jahre zurückgeht. Die erste ist, sollten Schaltjahre vor dem Wechsel nach den julianischen oder den gregorianischen Regeln berechnet werden? Das zweite Problem ist, wann und wie sollen die übersprungenen Tage behandelt werden?

So gehen die Big Eight DBMSs mit diesen Fragen um:

  • Stell dir vor, es gäbe keinen Schalter. Dies scheint der SQL-Standard zu verlangen, obwohl das Standarddokument unklar ist:Es besagt lediglich, dass Datumsangaben „durch die natürlichen Regeln für Datumsangaben nach dem gregorianischen Kalender eingeschränkt“ sind – was auch immer „natürliche Regeln“ sind. Dies ist die Option, die DB2 gewählt hat. Wenn vorgetäuscht wird, dass die Regeln eines einzigen Kalenders schon immer galten, sogar zu Zeiten, in denen niemand von dem Kalender gehört hat, ist der Fachbegriff, dass ein "proleptischer" Kalender in Kraft ist. So könnten wir beispielsweise sagen, dass DB2 einem proleptischen gregorianischen Kalender folgt.

  • Vermeiden Sie das Problem vollständig. Microsoft und Sybase legten ihre minimalen Datumswerte auf den 1. Januar 1753 fest, sicher nach der Zeit, als Amerika den Kalender umstellte. Dies ist vertretbar, aber von Zeit zu Zeit tauchen Beschwerden auf, dass diesen beiden DBMSs eine nützliche Funktionalität fehlt, die die anderen DBMSs haben und die der SQL-Standard erfordert.

  • Wählen Sie 1582. Das 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 sich Oracle zusätzliche Mühe gegeben, wenn der SQL-Standard dies anscheinend nicht erfordert? Die Antwort ist, dass Benutzer es möglicherweise benötigen. Historiker und Astronomen verwenden dieses hybride System 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 hybrider Kalender.)

Dieses obige Zitat stammt aus dem folgenden Link:

SQL-Leistungsoptimierung:Daten in SQL