sql >> Databáze >  >> RDS >> Sqlserver

SqlDateTime.MinValue !=DateTime.MinValue, proč?

Myslím, že je rozdíl mezi Datem SQL a .NET datové typy pramení ze skutečnosti, že datetime SQL Serveru datový typ, jeho minimální a maximální hodnoty a jeho přesnost jsou mnohem starší než datový typ DateTime .NET.

S příchodem .NET se tým rozhodl, že datový typ Datetime by měl mít přirozenější minimální hodnota a 01/01/0001 se jeví jako docela logická volba a určitě z programovacího jazyka , spíše než databáze perspektivě, je tato hodnota přirozenější.

Mimochodem, s SQL Server 2008 existuje řada nových datových typů založených na datu (Date, Time, DateTime2, DateTimeOffset), které ve skutečnosti nabízejí větší rozsah a přesnost a úzce se připojují k datovému typu DateTime v .NET. Například datový typ DateTime2 má rozsah dat od 0001-01-01 do 9999-12-31.

Standardní datový typ "datetime" SQL Server měl vždy minimální hodnotu 01/01/1753 (a skutečně stále má!). Musím se přiznat, že i já jsem byl zvědavý na význam této hodnoty, takže jsem se trochu pohrabal. Co jsem našel, bylo následující:

V období mezi rokem 1 n. l. a dnes západní svět ve skutečnosti používal dva hlavní kalendáře:juliánský kalendář Julia Caesara a gregoriánský kalendář papeže Řehoře XIII. Tyto dva kalendáře se liší pouze jedním pravidlem:pravidlem pro rozhodování o tom, co je přestupný rok. V juliánském kalendáři jsou všechny roky dělitelné čtyřmi roky přestupnými. V gregoriánském kalendáři jsou všechny roky dělitelné čtyřmi roky přestupnými, kromě toho, že roky dělitelné 100 (ale ne dělitelné 400) nejsou přestupnými roky. Roky 1700, 1800 a 1900 jsou tedy přestupnými roky v juliánském kalendáři, ale nikoli v gregoriánském kalendáři, zatímco roky 1600 a 2000 jsou přestupnými roky v obou kalendářích.

Když papež Řehoř XIII zavedl svůj kalendář v roce 1582, také nařídil, že dny mezi 4. říjnem 1582 a 15. říjnem 1582 by měly být vynechány – to znamená, že den po 4. říjnu by měl být 15. říjen. změna se však zpozdila. Anglie a její kolonie přešly z juliánského na gregoriánské počítání až v roce 1752, takže pro ně byla přeskočená data mezi 4. zářím a 14. zářím 1752. Jiné země přešly v jiných časech, ale 1582 a 1752 jsou relevantní data pro DBMS, o kterých diskutujeme.

Když se tedy vrátíme o mnoho let zpět, vyvstávají u aritmetiky data dva problémy. První zní, měly by se přestupné roky před přechodem počítat podle juliánských nebo gregoriánských pravidel? Druhý problém je, kdy a jak by se měly vynechané dny nakládat?

Takto se s těmito otázkami vypořádává DBMS Big Eight:

  • Předstírejte, že žádný vypínač nebyl. Zdá se, že to vyžaduje standard SQL, ačkoli standardní dokument je nejasný:Pouze říká, že data jsou „omezována přirozenými pravidly pro data používající gregoriánský kalendář“ – ať už jsou „přirozená pravidla“ jakákoli. Toto je možnost, kterou zvolil DB2. Když se předstírá, že pravidla jednoho kalendáře vždy platila i v době, kdy o kalendáři nikdo neslyšel, technický termín zní, že je v platnosti „proleptický“ kalendář. Takže bychom například mohli říci, že DB2 se řídí proleptickým gregoriánským kalendářem.

  • Vyhněte se problému zcela. Microsoft a Sybase nastavily své minimální hodnoty data na 1. leden 1753, tedy bezpečně po době, kdy Amerika přepínala kalendáře. To je obhajitelné, ale čas od času se objeví stížnosti, že tyto dva DBMS postrádají užitečnou funkcionalitu, kterou mají ostatní DBMS a kterou vyžaduje standard SQL.

  • Vyberte si 1582. Tohle udělal Oracle. Uživatel Oracle by zjistil, že aritmetický výraz 15. října 1582 mínus 4. října 1582 dává hodnotu 1 dne (protože 5.–14. říjen neexistuje) a že datum 29. února 1300 je platné (protože juliánský skok- platí roční pravidlo). Proč se Oracle dostal do dalších problémů, když to standard SQL zřejmě nevyžaduje? Odpověď je, že uživatelé to mohou vyžadovat. Historici a astronomové používají tento hybridní systém namísto proleptického gregoriánského kalendáře. (Toto je také výchozí možnost, kterou Sun zvolil při implementaci třídy GregorianCalendar pro Java – navzdory názvu je GregorianCalendar hybridní kalendář.)

Tato výše uvedená citace je převzata z následujícího odkazu:

Ladění výkonu SQL:Data v SQL



  1. Jak získám místní data do databáze pouze pro čtení pomocí dplyr?

  2. MariaDB JSON_QUOTE() Vysvětleno

  3. Jak odstranit hodnotu typu enum v postgresu?

  4. Matematické funkce serveru SQL (úplný seznam)