Вопрос

Интересно, почему SqlDateTime.MinValue не совпадает с DateTime.MinValue?

Это было полезно?

Решение

Я думаю, что разница между SQL и .NET Дата типы данных обусловлены тем фактом, что SQL Server дата и время тип данных, его минимальное и максимальное значения, а также его точность намного старше, чем тип данных DateTime в .NET.

С появлением .NET команда решила, что тип данных Datetime должен иметь более естественный минимальное значение, а 01.01.0001 кажется вполне логичным выбором, и, конечно, с язык программирования, скорее, чем база данных В перспективе это значение более естественно.

Кстати, в SQL Server 2008 появилось несколько новых типов данных на основе даты (Дата, Время, ДатаВремя2, ДатаВремяСмещение), которые на самом деле предлагают увеличенный диапазон и точность и точно соответствуют типу данных DateTime в .NET.Например, тип данных DateTime2 имеет диапазон дат от 01.001.01 до 31.12.9999.

Стандартный тип данных SQL Server «datetime» всегда имел минимальное значение 01.01.1753 (и действительно имеет до сих пор!).Должен признаться, мне тоже было любопытно значение этого значения, поэтому я немного покопался.Я обнаружил следующее:

В период с 1 н.э.и сегодня западный мир фактически использует два основных календаря:Юлианский календарь Юлия Цезаря и григорианский календарь Папы Григория XIII.Два календаря различаются только одним правилом:правило определения високосного года.В юлианском календаре все годы, кратные четырем, являются високосными.В григорианском календаре все годы, кратные четырем, являются високосными, за исключением годов, кратных 100 (но не кратных 400), не високосными.Таким образом, 1700, 1800 и 1900 годы являются високосными в юлианском календаре, но не в григорианском, а 1600 и 2000 — високосными в обоих календарях.

Когда папа Григорий XIII представил свой календарь в 1582 году, он также приказал пропустить дни между 4 октября 1582 года и 15 октября 1582 года, то есть он сказал, что день после 4 октября должен быть 15 октября.Однако многие страны отложили переход.Англия и ее колонии не перешли с юлианского на григорианское исчисление до 1752 года, поэтому для них пропущенными датами были период с 4 по 14 сентября 1752 года.Другие страны перешли в другое время, но 1582 и 1752 годы — соответствующие даты для СУБД, которые мы обсуждаем.

Таким образом, если вернуться на много лет назад, при арифметике дат возникают две проблемы.Во-первых, следует ли рассчитывать високосные годы до перехода по юлианским или григорианским правилам?Вторая проблема: когда и как обрабатывать пропущенные дни?

Вот как СУБД «Большой восьмерки» решают эти вопросы:

  • Представьте, что переключателя не было.Кажется, именно этого требует стандарт SQL, хотя стандартный документ неясен:Там просто говорится, что даты «ограничены естественными правилами для дат, использующими григорианский календарь» — какими бы «естественными правилами» ни были.Это вариант, который выбрала DB2.Когда создается впечатление, что правила единого календаря всегда применялись даже в те времена, когда о календаре никто не слышал, техническим термином является то, что действует «предварительный» календарь.Так, например, мы могли бы сказать, что DB2 следует опережающему григорианскому календарю.

  • Полностью избегайте проблемы. Microsoft и Sybase установили минимальные значения дат на 1 января 1753 года, то есть благополучно прошло время, когда Америка сменила календари.Это можно оправдать, но время от времени возникают жалобы на то, что этим двум СУБД не хватает полезной функциональности, которая есть у других СУБД и которая требуется стандартом SQL.

  • Выберите 1582.Это то, что сделал Oracle.Пользователь Oracle обнаружит, что арифметическое выражение даты 15 октября 1582 года минус 4 октября 1582 года дает значение 1 день (поскольку 5–14 октября не существует) и что дата 29 февраля 1300 года действительна (поскольку юлианский скачок применяется правило года).Почему Oracle приложила дополнительные усилия, хотя стандарт SQL, похоже, этого не требует?Ответ в том, что пользователям это может потребоваться.Историки и астрономы используют эту гибридную систему вместо опережающего григорианского календаря.(Это также вариант по умолчанию, который компания Sun выбрала при реализации класса GregorianCalendar для Java — несмотря на название, GregorianCalendar представляет собой гибридный календарь.)

Приведенная выше цитата взята из следующей ссылки:

Настройка производительности SQL:Даты в SQL

Другие советы

Поскольку в SQL Server минимальная дата, которая может храниться в поле даты и времени (1753/1/1), не равна MinValue типа данных DateTime .NET (0001/1/1).

1753 год стал датой первого принятия григорианского календаря (Англия).Что касается того, почему это было выбрано вместо 01.01.0001, то это, без сомнения, наследие тех времен, когда SQL Server был Sybase еще в 1990-х годах.Должно быть, они приняли проектное решение заранее, и команда Microsoft SQL не видела причин его менять.

После бурного развития .NET и его интеграции в Sql Server, теперь существует ДатаВремя2 объект для совместимости.Если вы пользователь NHibernate, вы можете предоставить этот тип в сопоставлениях типов, чтобы избежать DateTime.Min проблемы

.NET Dates поддерживает другие календари, помимо григорианского:

  • Календарь
    • КитайскийЛунно-солнечныйКалендарь
    • ВостокАзиатскаяЛунная СолнечнаяКалендарь
    • Григорианский календарь
    • ИвритКалендарь
    • ХиджраКалендарь
    • ЯпонскийКалендарь
    • ЯпонскийЛунно-солнечныйКалендарь
    • ЮлианКалендарь
    • КорейскийКалендарь
    • КорейскийЛунно-солнечныйКалендарь
    • ПерсидскийКалендарь
    • ТайваньКалендарь
    • ТайваньЛунно-солнечная погодаКалендарь
    • ТайскийБуддийскийКалендарь
    • УмАлКураКалендарь

JulianCalendar на самом деле предшествует дате DateTime.MinValue

Две разные группы решили, что для них означает «минимум» в отношении даты/времени.

SQL использует другое внутреннее представление для DateTime.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top