SqlDateTime.MinValue! = DateTime.MinValue, почему? - PullRequest
69 голосов
/ 30 апреля 2009

Интересно, почему SqlDateTime.MinValue отличается от DateTime.MinValue?

Ответы [ 5 ]

129 голосов
/ 30 апреля 2009

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

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

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

Стандартный тип данных «Дата / время» в SQL Server всегда имел минимальное значение 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 годы являются соответствующими датами для СУБД, которые мы обсуждаем.

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

Вот как СУБД Big Eight решают следующие вопросы:

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

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

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

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

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

12 голосов
/ 30 апреля 2009

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

11 голосов
/ 12 января 2010

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

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

.NET Даты обслуживают другие календари, кроме григорианского:

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

Предварительные даты факта JulianCalendar DateTime.MinValue

7 голосов
/ 30 апреля 2009

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

5 голосов
/ 30 апреля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...