SqlDateTime.MinValue!= DateTime.MinValue, почему?

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

Ответ 1

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

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

Кстати, с SQL Server 2008 существует ряд новых типов данных по дате (Date, Время, DateTime2, DateTimeOffset), которые действительно предлагают расширенный диапазон и точность и тесно сопоставляются с типом данных DateTime в .NET. Например, тип данных DateTime2 имеет диапазон дат от 0001-01-01 до 9999-12-31.

Стандартный тип данных "datetime" SQL Server всегда имел минимальное значение 01/01/1753 (и действительно имеет значение!). Должен признаться, мне тоже было любопытно, насколько важна эта ценность, так же как и копание. То, что я нашел, было следующим:

В течение периода между 1 A.D. и сегодня западный мир фактически использовал два основных календаря: юлианский календарь Юлий Цезарь и григорианский календарь Папы Григория 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 Standard, похоже, не требует этого? Ответ заключается в том, что пользователи могут потребовать его. Историки и астрономы используют эту гибридную систему вместо прорептического григорианского календаря. (Это также параметр по умолчанию, который выбрал Sun при реализации класса GregorianCalendar для Java - несмотря на имя, GregorianCalendar - это гибридный календарь.)

Эта цитата из приведенной ниже ссылки:

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

Ответ 2

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

Ответ 3

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

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

.NET Даты предназначены для других календарей, кроме григорианского:

  • Calendar
    • ChineseLunisolarCalendar
    • EastAsianLunisolarCalendar
    • GregorianCalendar
    • еврейский календарь
    • HijriCalendar
    • японский календарь
    • JapaneseLunisolarCalendar
    • JulianCalendar
    • KoreanCalendar
    • KoreanLunisolarCalendar
    • PersianCalendar
    • TaiwanCalendar
    • TaiwanLunisolarCalendar
    • ThaiBuddhistCalendar
    • UmAlQuraCalendar

Предсказания инфантильности JulianCalendar DateTime.MinValue

Ответ 4

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

Ответ 5

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