Dans notre projet C #, nous avons besoin de représenter une date sans heure. Je connais l'existence du DateTime, cependant, il intègre également une heure de la journée. Je veux préciser que certaines variables et certains arguments de méthode sont basés sur la date . Par conséquent, je ne peux pas utiliser la DateTime.Date
propriété
Quelles sont les approches standard de ce problème? Je ne suis sûrement pas le premier à rencontrer cela? Pourquoi n'y a-t-il pas de Date
classe en C #?
Quelqu'un a-t-il une belle implémentation en utilisant une structure et peut-être des méthodes d'extension sur DateTime et peut-être implémentant certains opérateurs tels que == et <,>?
DateTime
crée-t-il?Réponses:
Permettez-moi d'ajouter une mise à jour à cette question classique:
La bibliothèque Noda Time de Jon Skeet est maintenant assez mature et a un type de date uniquement appelé
LocalDate
. (Local dans ce cas signifie simplement local pour quelqu'un , pas nécessairement local pour l'ordinateur sur lequel le code est exécuté.)Un type de date uniquement appelé
Date
est un ajout proposé au .NET Core, via le projet corefxlab . Vous le trouverez dans leSystem.Time
package, avec unTimeOfDay
type et plusieurs méthodes d'extension aux types existants.J'ai étudié ce problème de manière significative, je vais donc également partager plusieurs raisons de la nécessité de ces types:
Il existe un écart logique entre une valeur de date uniquement et une valeur de date à minuit.
Pas tous les jours locale a un minuit dans chaque fuseau horaire. Exemple: la transition de l'heure d'été vers l'avant du Brésil fait passer l'horloge de 11:59:59 à 01:00:00.
Une date-heure fait toujours référence à une heure spécifique dans la journée, tandis qu'une date uniquement peut faire référence au début de la journée, à la fin de la journée ou à toute la plage de la journée.
Le fait d'attacher une heure à une date peut entraîner un changement de date lorsque la valeur est transmise d'un environnement à un autre, si les fuseaux horaires ne sont pas surveillés très attentivement. Cela se produit généralement en JavaScript (dont l'
Date
objet est en réalité une date + heure), mais peut également se produire facilement dans .NET, ou dans la sérialisation lorsque les données sont transmises entre JavaScript et .NET.La sérialisation d'un
DateTime
avec XML ou JSON (et autres) inclura toujours l'heure, même si ce n'est pas important. C'est très déroutant, surtout si l'on considère des choses comme les dates de naissance et les anniversaires, où l'heure n'a pas d'importance.Sur le plan architectural, il
DateTime
s'agit d'un objet de valeur DDD , mais il enfreint le principe de responsabilité unique de plusieurs manières:Il est conçu comme un type date + heure, mais est souvent utilisé comme date uniquement (en ignorant l'heure), ou en heure uniquement (en ignorant la date). (
TimeSpan
est également souvent utilisé pour l'heure de la journée, mais c'est un autre sujet.)La
DateTimeKind
valeur attachée à la.Kind
propriété divise le type unique en trois. LeUnspecified
genre est vraiment l'intention d'origine de la structure et doit être utilisé de cette façon. LeUtc
kind aligne la valeur spécifiquement avec UTC et leLocal
kind aligne la valeur sur le fuseau horaire local de l'environnement.Le problème d'avoir un indicateur distinct pour kind est que chaque fois que vous consommez un
DateTime
, vous êtes censé vérifier.Kind
pour décider du comportement à adopter. Les méthodes de cadre font toutes cela, mais d'autres oublient souvent. Il s'agit vraiment d'une violation SRP, car le type a maintenant deux raisons différentes de changer (la valeur et le genre).Les deux conduisent à des utilisations d'API qui se compilent, mais qui sont souvent absurdes, ou ont des cas extrêmes causés par des effets secondaires. Considérer:
En résumé, alors que a
DateTime
peut être utilisé pour une date uniquement, il ne devrait le faire que lorsque chaque lieu qui l'utilise fait très attention d'ignorer l'heure, et est également très prudent de ne pas essayer de convertir vers et depuis UTC ou autre fuseaux horaires.la source
System.Time.Date
finirait dans le framework .NET: /System.Time
accéder comme n'importe quel autre package. Ce n'est tout simplement pas encore "officiel".Je soupçonne qu'il n'y a pas de
Date
classe pure dédiée car vous avez déjàDateTime
qui peut le gérer. CelaDate
entraînerait des doubles emplois et de la confusion.Si vous voulez l'approche standard, regardez la
DateTime.Date
propriété qui donne uniquement la partie date de aDateTime
avec la valeur de l'heure définie sur 12:00:00 minuit (00:00:00).la source
J'ai envoyé un e-mail à [email protected] et c'est leur réponse
Dans mon e-mail, je me suis demandé si c'était parce que DateTime utilise TimeZoneInfo pour obtenir l'heure de la machine - dans Now propriété. Donc je dirais que c'est parce que "les règles métier" sont "trop couplées", ils me l'ont confirmé.
la source
SpaceTime
classe! Hé, selon Einstein, l'espace et le temps sont étroitement liés, nous ne devrions donc pas avoir besoin de les différencier non plus, non? (!!!!!!!!!!!) Je suis un peu nouveau pour C #, mais je dois dire, c'est un champ de mines en provenance de VB.NET où est, tout simplement,date
,Today()
,now
, etc. Pas deDateTime
déchets préfixant, pas dégoûtant. (Et ces points-virgules et cette sensibilité à la casse sont vraiment ennuyeux! Il suffit de me tirer dessus maintenant!)Date
type et le résultat doit être de typeDate
- s'il était deDate
type résultat attendu sous forme de chaîne sans temps. Par exemple, Delphi a également Date comme DateTime, mais typeinfo différent pour Date et DateTime.J'ai créé une structure de date simple pour les moments où vous avez besoin d'une date simple sans vous soucier de la partie horaire, des fuseaux horaires, du local ou de l'utc, etc.
https://github.com/claycephus/csharp-date
la source
Si vous devez exécuter des comparaisons de dates, utilisez
Si vous affichez à l'écran, utilisez
la source
Permettez-moi de spéculer: c'est peut-être parce que jusqu'à SQL Server 2008, il n'y avait pas de type de données Date dans SQL, donc il serait difficile de le stocker dans SQL Server ?? Et c'est après tout un produit Microsoft?
la source
Qui sait pourquoi c'est ainsi. Il y a beaucoup de mauvaises décisions de conception dans le framework .NET. Cependant, je pense que c'est une question assez mineure. Vous pouvez toujours ignorer la partie heure, donc même si un code décide de faire référence à une date / heure plus que juste la date, le code qui se soucie ne devrait jamais regarder que la partie date. Vous pouvez également créer un nouveau type qui ne représente qu'une date et utiliser des fonctions dans DateTime pour effectuer le gros du travail (calculs).
la source
Pourquoi? Nous ne pouvons que spéculer et cela ne fait pas grand-chose pour résoudre les problèmes d'ingénierie. Une bonne supposition est que
DateTime
contient toutes les fonctionnalités qu'une telle structure aurait.Si cela compte vraiment pour vous, enveloppez simplement
DateTime
votre propre structure immuable qui expose uniquement la date (ou regardez laDateTime.Date
propriété).la source
En plus de la réponse de Robert, vous avez également la
DateTime.ToShortDateString
méthode. De plus, si vous vouliez vraiment un objet Date, vous pouvez toujours utiliser le modèle Adapter et envelopper l'objet DateTime en exposant uniquement ce que vous voulez (c'est-à-dire le mois, le jour, l'année).la source
Il y a toujours la
DateTime.Date
propriété qui coupe la partie temporelle duDateTime
. Vous pouvez peut-être encapsuler ou encapsuler DateTime dans votre propre type de date.Et pour savoir pourquoi, eh bien, je suppose que vous devrez demander à Anders Heljsberg.
la source
Parce que pour connaître la date, vous devez connaître l'heure du système (en ticks), qui comprend l'heure - alors pourquoi jeter ces informations?
DateTime
a uneDate
propriété si vous ne vous souciez pas du tout de l'heure.la source
Ouais, System.DateTime est également scellé. J'ai vu des gens jouer à des jeux avec cela en créant une classe personnalisée juste pour obtenir la valeur de chaîne de l'heure comme mentionné dans les articles précédents, des trucs comme:
Ceci est peut-être inutile, car vous pouvez facilement extraire GetShortTimeString d'un ancien type DateTime sans nouvelle classe
la source
Si vous utilisez les propriétés Date ou Today pour obtenir uniquement la partie date de l'objet DateTime.
Ensuite, vous obtiendrez le composant de date uniquement avec le composant d'heure défini sur minuit.
la source