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

SqlDateTime.MinValue !=DateTime.MinValue, perché?

Penso che la differenza tra la Data di SQL e .NET i tipi di dati derivano dal fatto che datetime di SQL Server tipo di dati, i suoi valori minimo e massimo e la sua precisione sono molto più vecchi del tipo di dati DateTime di .NET.

Con l'avvento di .NET, il team ha deciso che il tipo di dati Datetime dovrebbe avere un aspetto più naturale valore minimo e 01/01/0001 sembra una scelta abbastanza logica, e sicuramente da un linguaggio di programmazione , anziché database prospettiva, questo valore è più naturale.

Per inciso, con SQL Server 2008, sono disponibili numerosi nuovi tipi di dati basati sulla data (Date, Time, DateTime2, DateTimeOffset) che offrono effettivamente un intervallo e una precisione maggiori e si associano strettamente al tipo di dati DateTime in .NET. Ad esempio, il tipo di dati DateTime2 ha un intervallo di date compreso tra 0001-01-01 e 9999-12-31.

Il tipo di dati standard "datetime" di SQL Server ha sempre avuto un valore minimo di 01/01/1753 (e in effetti lo ha ancora!). Devo ammettere che anch'io ero curioso del significato di questo valore, quindi ho scavato un po'.. Quello che ho trovato è stato il seguente:

Nel periodo compreso tra l'1 d.C. e oggi, il mondo occidentale ha utilizzato in realtà due calendari principali:il calendario giuliano di Giulio Cesare e il calendario gregoriano di papa Gregorio XIII. I due calendari differiscono rispetto ad una sola regola:la regola per decidere cos'è un anno bisestile. Nel calendario giuliano, tutti gli anni divisibili per quattro sono bisestili. Nel calendario gregoriano, tutti gli anni divisibili per quattro sono bisestili, tranne che gli anni divisibili per 100 (ma non divisibili per 400) non sono bisestili. Pertanto, gli anni 1700, 1800 e 1900 sono anni bisestili nel calendario giuliano ma non nel calendario gregoriano, mentre gli anni 1600 e 2000 sono anni bisestili in entrambi i calendari.

Quando papa Gregorio XIII introdusse il suo calendario nel 1582, ordinò anche che i giorni tra il 4 ottobre 1582 e il 15 ottobre 1582 fossero saltati, cioè disse che il giorno dopo il 4 ottobre doveva essere il 15 ottobre. Molti paesi ritardato il cambio, però. L'Inghilterra e le sue colonie non passarono dal calcolo giuliano a quello gregoriano fino al 1752, quindi per loro le date saltate erano comprese tra il 4 settembre e il 14 settembre 1752. Altri paesi cambiarono altre volte, ma il 1582 e il 1752 sono le date rilevanti per il DBMS di cui stiamo parlando.

Pertanto, sorgono due problemi con l'aritmetica delle date quando si torna indietro di molti anni. Il primo è:dovrebbero essere anni bisestili prima che il cambio sia calcolato secondo le regole giuliane o gregoriche? Il secondo problema è, quando e come devono essere gestiti i giorni saltati?

Ecco come i Big Eight DBMS gestiscono queste domande:

  • Fai finta che non ci fosse alcun interruttore. Questo è ciò che lo standard SQL sembra richiedere, sebbene il documento standard non sia chiaro:dice solo che le date sono "vincolate dalle regole naturali per le date che utilizzano il calendario gregoriano", qualunque siano le "regole naturali". Questa è l'opzione scelta da DB2. Quando si pretende che le regole di un unico calendario siano sempre state applicate anche a tempi in cui nessuno aveva sentito parlare del calendario, il termine tecnico è che è in vigore un calendario "prolettico". Quindi, ad esempio, potremmo dire che DB2 segue un prolettico calendario gregoriano.

  • Evita del tutto il problema. Microsoft e Sybase hanno impostato i loro valori minimi di data al 1 gennaio 1753, dopo il tempo in cui l'America ha cambiato calendario. Questo è giustificabile, ma di tanto in tanto emergono lamentele sul fatto che questi due DBMS non dispongono di una funzionalità utile che gli altri DBMS hanno e che lo standard SQL richiede.

  • Scegli 1582. Questo è ciò che ha fatto Oracle. Un utente Oracle scoprirebbe che l'espressione data-aritmetica 15 1582 ottobre meno 4 1582 ottobre produce un valore di 1 giorno (perché il 5-14 ottobre non esiste) e che la data 29 1300 febbraio è valida (perché il salto giuliano- si applica la regola dell'anno). Perché Oracle ha avuto ulteriori problemi quando lo standard SQL non sembra richiederlo? La risposta è che gli utenti potrebbero richiederlo. Storici e astronomi usano questo sistema ibrido invece di un prolettico calendario gregoriano. (Questa è anche l'opzione predefinita scelta da Sun durante l'implementazione della classe GregorianCalendar per Java, nonostante il nome, GregorianCalendar è un calendario ibrido.)

Questa citazione sopra è tratta dal seguente link:

Ottimizzazione delle prestazioni SQL:date in SQL