69 votes

SqlDateTime.MinValue != DateTime.MinValue, pourquoi ?

Je me demande pourquoi SqlDateTime.MinValue n'est pas la même chose que DateTime.MinValue ?

130voto

CraigTP Points 18514

Je pense que la différence entre SQL et .NET Date types de données provient du fait que le serveur SQL Server datetime ses valeurs minimale et maximale et sa précision sont bien plus anciennes que le type de données DateTime de .NET.

Avec l'avènement de .NET, l'équipe a décidé que le type de données Datetime devait avoir un aspect plus "moderne". naturel valeur minimale, et 01/01/0001 semble être un choix assez logique, et certainement d'une langage de programmation plutôt que base de données cette valeur est plus naturelle.

D'ailleurs, avec SQL Server 2008, il existe un certain nombre de nouveaux types de données basés sur la date ( Date , Temps , DateTime2 , DateTimeOffset ) qui offrent effectivement une plage et une précision accrues et correspondent étroitement au type de données DateTime de .NET. Par exemple, le type de données DateTime2 a une plage de dates allant de 0001-01-01 à 9999-12-31.

Le type de données standard "datetime" de SQL Server a toujours eu une valeur minimale de 01/01/1753 (et l'a toujours !). Je dois admettre que j'étais moi aussi curieux de connaître la signification de cette valeur, et j'ai donc fait quelques recherches Ce que j'ai trouvé est le suivant :

Entre l'an 1 de notre ère et aujourd'hui, le monde occidental a en fait utilisé deux calendriers principaux : le calendrier julien de Jules César et le calendrier grégorien du pape Grégoire XIII. Les deux calendriers ne diffèrent que par une seule règle : celle qui permet de déterminer ce qu'est une année bissextile. Dans le calendrier julien, toutes les années divisibles par quatre sont des années bissextiles. Dans le calendrier grégorien, toutes les années divisibles par quatre sont des années bissextiles, sauf les années divisibles par 100 (mais non divisibles par 400). Ainsi, les années 1700, 1800 et 1900 sont des années bissextiles dans le calendrier julien mais pas dans le calendrier grégorien, tandis que les années 1600 et 2000 sont des années bissextiles dans les deux calendriers.

Lorsque le pape Grégoire XIII a introduit son calendrier en 1582, il a également ordonné de sauter les jours compris entre le 4 octobre 1582 et le 15 octobre 1582, c'est-à-dire que le jour suivant le 4 octobre devait être le 15 octobre. De nombreux pays ont cependant retardé le changement. L'Angleterre et ses colonies ne sont passées du système julien au système grégorien qu'en 1752. Pour eux, les dates sautées se situaient donc entre le 4 et le 14 septembre 1752. D'autres pays ont basculé à d'autres moments, mais 1582 et 1752 sont les dates pertinentes pour les SGBD dont nous parlons.

Ainsi, deux problèmes se posent avec l'arithmétique des dates lorsque l'on remonte de nombreuses années en arrière. Le premier est de savoir si les années bissextiles avant le changement doivent être calculées selon les règles juliennes ou grégoriennes. Le second problème est de savoir quand et comment traiter les jours sautés.

Voici comment les huit grands SGBD traitent ces questions :

  • Faites comme s'il n'y avait pas d'interrupteur. C'est ce que la norme SQL semble exiger, bien que le document de la norme ne soit pas clair : il dit simplement que les dates sont "contraintes par les règles naturelles pour les dates utilisant le calendrier grégorien" - quelles que soient les "règles naturelles". C'est l'option que DB2 a choisie. Lorsque l'on prétend que les règles d'un calendrier unique se sont toujours appliquées, même à des époques où personne n'a entendu parler de ce calendrier, le terme technique est qu'un calendrier "proleptique" est en vigueur. Ainsi, par exemple, nous pourrions dire que DB2 suit un calendrier grégorien proleptique.

  • Évitez complètement le problème. Microsoft et Sybase fixent leurs valeurs minimales de date au 1er janvier 1753, soit bien après le moment où l'Amérique a changé de calendrier. C'est défendable, mais de temps en temps, des plaintes apparaissent pour dénoncer le fait que ces deux SGBD manquent d'une fonctionnalité utile que les autres SGBD possèdent et que la norme SQL exige.

  • Pick 1582. C'est ce qu'a fait Oracle. Un utilisateur d'Oracle constaterait que l'expression arithmétique de la date 15 octobre 1582 moins 4 octobre 1582 donne une valeur de 1 jour (car les 5-14 octobre n'existent pas) et que la date 29 février 1300 est valide (car la règle de l'année bissextile julienne s'applique). Pourquoi Oracle s'est-il donné tant de mal alors que la norme SQL ne semble pas l'exiger ? La réponse est que les utilisateurs pourraient l'exiger. Les historiens et les astronomes utilisent ce système hybride au lieu d'un calendrier grégorien proleptique. (C'est également l'option par défaut que Sun a choisie lors de l'implémentation de la classe GregorianCalendar pour Java - malgré son nom, GregorianCalendar est un calendrier hybride).

Cette citation ci-dessus est tirée du lien suivant :

Optimisation des performances SQL : Dates en SQL

12voto

Frederik Gheysels Points 36354

En effet, dans SQL Server, la date minimale qui peut être stockée dans un champ datetime (1753/1/1) n'est pas égale à la valeur minimale du type de données DateTime .NET (0001/1/1).

11voto

Chris S Points 32376

1753 est la date de la première adoption du calendrier grégorien (Angleterre). Quant à savoir pourquoi cette date a été choisie plutôt que le 01/01/0001, il s'agit sans doute d'un héritage de l'époque où SQL Server était Sybase, dans les années 1990. Ils ont dû prendre la décision de conception très tôt et l'équipe Microsoft SQL n'a pas vu de raison de la changer.

Depuis l'explosion de .NET et son intégration dans Sql Server, il y a maintenant le DateTime2 pour des raisons de compatibilité. Si vous êtes un utilisateur de NHibernate, vous pouvez fournir ce type dans vos mappages de types pour éviter DateTime.Min problèmes

.NET Dates prend en charge d'autres calendriers que le calendrier grégorien :

  • Calendrier
    • Calendrier lunaire chinois
    • Calendrier solaire de l'Asie de l'Est
    • Calendrier grégorien
    • Calendrier hébraïque
    • HijriCalendar
    • JaponaisCalendrier
    • Calendrier japonaisLunisolaire
    • Calendrier julien
    • Calendrier coréen
    • Calendrier lunaire coréen
    • Calendrier persan
    • TaiwanCalendrier
    • TaiwanCalendrier lunaire
    • Calendrier bouddhiste thaïlandais
    • UmAlQuraCalendrier

Le calendrier julien précède en fait DateTime.MinValue

7voto

Nicholas Points 2532

Deux groupes différents ont décidé de ce que "minimum" signifie pour eux en ce qui concerne la date et l'heure.

5voto

leppie Points 67289

SQL utilise une représentation interne différente pour DateTime.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X