Pregunta

Me pregunto, ¿por qué SqlDateTime.MinValue no es lo mismo que DateTime.MinValue?

¿Fue útil?

Solución

Creo que la diferencia entre los tipos de datos Fecha de SQL y .NET se debe al hecho de que el tipo de datos datetime de SQL Server, sus valores mínimos y máximos, y su precisión son mucho más antiguo que el tipo de datos DateTime de .NET.

Con el advenimiento de .NET, el equipo decidió que el tipo de datos Fecha y hora debería tener un valor mínimo más natural , y 01/01/0001 parece una opción bastante lógica, y ciertamente desde un < em> lenguaje de programación , en lugar de la perspectiva de base de datos , este valor es más natural.

Por cierto, con SQL Server 2008, hay varios tipos de datos basados ??en Fecha ( Fecha , Time , DateTime2 , DateTimeOffset ) que realmente ofrece un mayor rango y precisión, y se asigna estrechamente al tipo de datos DateTime en .NET. Por ejemplo, el tipo de datos DateTime2 tiene un rango de fechas desde 0001-01-01 hasta 9999-12-31.

El estándar " datetime " El tipo de datos de SQL Server siempre ha tenido un valor mínimo de 01/01/1753 (¡y de hecho todavía tiene!). Debo admitir que yo también sentí curiosidad por la importancia de este valor, así que hice algunas excavaciones ... Lo que encontré fue el siguiente:

  

Durante el período entre 1 A.D. y hoy, el mundo occidental ha utilizado dos calendarios principales: el calendario juliano de Julio César y el calendario gregoriano del Papa Gregorio XIII. Los dos calendarios difieren con respecto a una sola regla: la regla para decidir qué es un año bisiesto. En el calendario juliano, todos los años divisibles por cuatro son años bisiestos. En el calendario gregoriano, todos los años divisibles por cuatro son años bisiestos, excepto que los años divisibles por 100 (pero no divisibles por 400) no son años bisiestos. Por lo tanto, los años 1700, 1800 y 1900 son años bisiestos en el calendario juliano pero no en el calendario gregoriano, mientras que los años 1600 y 2000 son años bisiestos en ambos calendarios.

     

Cuando el papa Gregorio XIII presentó su calendario en 1582, también ordenó que los días entre el 4 de octubre de 1582 y el 15 de octubre de 1582 se omitieran & # 8212; es decir, que el día posterior al 4 de octubre 15 de octubre. Muchos países retrasaron el cambio, sin embargo. Inglaterra y sus colonias no cambiaron de cuentas julianas a gregorianas hasta 1752, por lo que para ellos, las fechas omitidas fueron entre el 4 de septiembre y el 14 de septiembre de 1752. Otros países cambiaron en otras ocasiones, pero 1582 y 1752 son las fechas relevantes para la DBMS que estamos discutiendo.

     

Por lo tanto, surgen dos problemas con la aritmética de fechas cuando uno se remonta a muchos años. La primera es, ¿deberían saltarse años antes de que se calcule el cambio de acuerdo con las reglas de Julian o Gregorian? El segundo problema es, ¿cuándo y cómo deben manejarse los días omitidos?

     

Así es como los DBMS de Big Eight manejan estas preguntas:

     
      
  • Imagina que no hubo ningún interruptor. Esto es lo que parece requerir el estándar SQL, aunque el documento estándar no está claro: simplemente dice que las fechas están restringidas por las reglas naturales para las fechas que usan el calendario gregoriano " & # 8212; cualquiera que sea " las reglas naturales " son. Esta es la opción que DB2 eligió. Cuando hay una pretensión de que las reglas de un solo calendario siempre se han aplicado incluso en los momentos en que nadie ha oído hablar del calendario, el término técnico es que un " proleptic " El calendario está en vigor. Entonces, por ejemplo, podríamos decir que DB2 sigue un calendario gregoriano proleptico.

  •   
  • Evita el problema por completo. Microsoft y Sybase establecen sus valores de fecha mínima el 1 de enero de 1753, después de la fecha en que América cambió los calendarios. Esto es defendible, pero de vez en cuando surgen quejas de que estos dos DBMS carecen de una funcionalidad útil que tienen los otros DBMS y que requiere el estándar SQL.

  •   
  • Selecciona 1582. Esto es lo que hizo Oracle. Un usuario de Oracle encontraría que la expresión aritmética de fecha 15 de octubre de 1582 menos 4 de octubre de 1582 arroja un valor de 1 día (porque el 5 de octubre & # 8211; 14 no existe) y que la fecha del 29 de febrero de 1300 es válida (debido a que Julian se aplica la regla del año bisiesto). ¿Por qué Oracle tuvo problemas adicionales cuando el estándar de SQL no parece requerirlo? La respuesta es que los usuarios pueden necesitarlo. Los historiadores y los astrónomos usan este sistema híbrido en lugar de un calendario gregoriano proleptico. (Esta es también la opción predeterminada que Sun eligió al implementar la clase GregorianCalendar para Java & # 8212; a pesar del nombre, GregorianCalendar es un calendario híbrido).

  •   

Esta cita anterior se tomó del siguiente enlace:

Ajuste de rendimiento de SQL: Fechas en SQL

Otros consejos

Dado que, en SQL Server, la fecha mínima que se puede almacenar en un campo datetime (1753/1/1), no es igual al valor mínimo del tipo de datos DateTime .NET (0001/1/1).

1753 fue la fecha del primer adoptante del calendario gregoriano (Inglaterra). En cuanto a por qué se eligió esto a partir del 01/01/0001, es sin duda un legado de cuando SQL Server era Sybase en la década de 1990. Deben haber tomado la decisión de diseño desde el principio y el equipo de Microsoft SQL no ha visto ninguna razón para cambiarla.

Desde la explosión de .NET y su integración en el servidor Sql, ahora hay DateTime2 objeto para compatibilidad. Si es un usuario de NHibernate, puede proporcionar este tipo en sus asignaciones de tipo para evitar los DateTime.Min problemas

.NET Las fechas satisfacen otros calendarios además del gregoriano:

  • Calendario
    • ChineseLunisolarCalendar
    • EastAsianLunisolarCalendar
    • GregorianCalendar
    • Calendario hebreo
    • HijriCalendar
    • calendario japonés
    • JapaneseLunisolarCalendar
    • JulianCalendar
    • calendario coreano
    • KoreanLunisolarCalendar
    • PersianCalendar
    • TaiwanCalendar
    • TaiwanLunisolarCalendar
    • ThaiBuddhistCalendar
    • UmAlQuraCalendar

El calendario JulianCalendar es anterior a DateTime.MinValue

Dos grupos diferentes decidieron qué " mínimo " significa para ellos con respecto a la fecha / hora.

SQL usa una representación interna diferente para DateTime.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top