In unserem C # -Projekt müssen wir ein Datum ohne Uhrzeit darstellen. Ich weiß von der Existenz der DateTime, sie enthält jedoch auch eine Tageszeit. Ich möchte deutlich machen, dass bestimmte Variablen und Methodenargumente datumsbasiert sind . Daher kann ich die DateTime.Date
Eigenschaft nicht verwenden
Was sind die Standardansätze für dieses Problem? Sicher bin ich nicht der erste, der darauf stößt? Warum gibt es Date
in C # keine Klasse?
Hat jemand eine nette Implementierung mit einer Struktur und vielleicht einigen Erweiterungsmethoden in DateTime und vielleicht einige Operatoren wie == und <,>?
DateTime
?Antworten:
Gestatten Sie mir, dieser klassischen Frage ein Update hinzuzufügen:
Die Noda Time- Bibliothek von Jon Skeet ist jetzt ziemlich ausgereift und hat einen Nur-Datum-Typ namens
LocalDate
. (Lokal bedeutet in diesem Fall nur lokal für jemanden , nicht unbedingt lokal für den Computer, auf dem der Code ausgeführt wird.)Ein Nur-Datum-Typ namens
Date
ist eine vorgeschlagene Ergänzung zum .NET Core über das corefxlab- Projekt. Sie finden es imSystem.Time
Paket zusammen mit einemTimeOfDay
Typ und mehreren Erweiterungsmethoden für die vorhandenen Typen.Ich habe dieses Problem eingehend untersucht, daher werde ich auch einige Gründe für die Notwendigkeit dieser Typen nennen:
Es gibt eine logische Diskrepanz zwischen einem Nur-Datum- und einem Mitternachtsdatum-Wert.
Nicht jeder lokale Tag hat in jeder Zeitzone Mitternacht. Beispiel: Brasiliens Sommerzeitübergang im Frühjahr bewegt die Uhr von 11:59:59 auf 01:00:00 Uhr.
Eine Datums- und Uhrzeitangabe bezieht sich immer auf eine bestimmte Uhrzeit innerhalb eines Tages, während sich eine Datums- und Uhrzeitangabe auf den Tagesanfang, das Tagesende oder den gesamten Tagesbereich beziehen kann .
Das Anhängen einer Uhrzeit an ein Datum kann dazu führen, dass sich das Datum ändert, wenn der Wert von einer Umgebung in eine andere übergeben wird, wenn die Zeitzonen nicht sehr genau überwacht werden. Dies tritt häufig in JavaScript auf (dessen
Date
Objekt tatsächlich ein Datum + eine Uhrzeit ist), kann jedoch auch in .NET oder bei der Serialisierung leicht auftreten, wenn Daten zwischen JavaScript und .NET übertragen werden.Das Serialisieren von a
DateTime
mit XML oder JSON (und anderen) enthält immer die Zeit, auch wenn dies nicht wichtig ist. Dies ist sehr verwirrend, insbesondere wenn man Dinge wie Geburtsdaten und Jahrestage berücksichtigt, bei denen die Zeit keine Rolle spielt.Architektonisch
DateTime
handelt es sich um ein DDD- Wertobjekt , das jedoch in mehrfacher Hinsicht gegen das Prinzip der Einzelverantwortung verstößt :Es ist als Datums- und Uhrzeittyp konzipiert, wird jedoch häufig nur als Datum (ohne Berücksichtigung der Uhrzeit) oder nur als Uhrzeit (ohne Berücksichtigung des Datums) verwendet. (
TimeSpan
wird auch oft für die Tageszeit verwendet, aber das ist ein anderes Thema.)Der
DateTimeKind
an die.Kind
Eigenschaft angehängte Wert teilt den einzelnen Typ in drei Teile. DieUnspecified
Art ist wirklich die ursprüngliche Absicht der Struktur und sollte auf diese Weise verwendet werden. DieUtc
Art richtet den Wert speziell auf UTC aus und dieLocal
Art richtet den Wert an der lokalen Zeitzone der Umgebung aus.Das Problem mit einem separaten Flag für Art ist, dass Sie jedes Mal, wenn Sie ein konsumieren
DateTime
, überprüfen müssen , welches Verhalten Sie anwenden sollen.Kind
. Die Framework-Methoden tun dies alle, aber andere vergessen es oft. Dies ist wirklich eine SRP-Verletzung, da der Typ jetzt zwei verschiedene Gründe hat, sich zu ändern (den Wert und die Art).Die beiden führen zu API-Verwendungen, die kompiliert werden, aber oft unsinnig sind oder seltsame Randfälle aufweisen, die durch Nebenwirkungen verursacht werden. Erwägen:
Zusammenfassend
DateTime
lässt sich sagen, dass a zwar nur für ein Datum verwendet werden kann , dies jedoch nur dann der Fall sein sollte, wenn an jedem Ort, an dem es verwendet wird, die Zeit sehr sorgfältig ignoriert wird und auch sehr darauf geachtet wird, nicht zu versuchen, von und nach UTC oder einem anderen Wert zu konvertieren Zeitzonen.quelle
System.Time.Date
im .NET FrameworkSystem.Time
wie jedes andere Paket einbinden . Es ist nur noch nicht "offiziell".Ich vermute, es gibt keine dedizierte reine
Date
Klasse, weil Sie bereits eine haben,DateTime
die damit umgehen kann. DiesDate
würde zu Doppelarbeit und Verwirrung führen.Wenn Sie den Standardansatz wünschen, schauen Sie sich die
DateTime.Date
Eigenschaft an, die nur den Datumsteil von aDateTime
mit dem auf 12:00:00 Mitternacht (00:00:00) festgelegten Zeitwert angibt.quelle
Ich habe eine E-Mail an [email protected] gesendet und das ist ihre Antwort
In meiner E-Mail hatte ich gefragt, ob DateTime TimeZoneInfo verwendet, um die Uhrzeit der Maschine abzurufen - in Now-Anstand. Ich würde also sagen, es liegt daran, dass "die Geschäftsregeln" "zu gekoppelt" sind, das haben sie mir bestätigt.
quelle
SpaceTime
Klasse implementieren ! Hey, laut Einstein sind Raum und Zeit eng miteinander verbunden, also sollten wir auch nicht zwischen ihnen unterscheiden müssen, oder? (!!!!!!!!!!!) Ich bin ein bisschen neu in C #, aber ich muss sagen, es ist ein Minenfeld von VB.NET kommen , wo ist, einfach,date
,Today()
,now
etc. KeinDateTime
Müll prefixing, nein herumalbern. (Und diese Semikolons und diese Groß- und Kleinschreibung sind sicher lästig! Erschießen Sie mich jetzt!)Date
Typ und das Ergebnis müssen vom Typ seinDate
- wenn es sich um einDate
Typergebnis handelt, das als Zeichenfolge ohne Zeit erwartet wird. Zum Beispiel hat Delphi auch Datum als DateTime, aber typeinfo unterscheidet sich für Date und DateTime.Ich habe eine einfache Datumsstruktur für Zeiten erstellt, in denen Sie ein einfaches Datum benötigen, ohne sich um Zeitanteil, Zeitzonen, lokale oder utc usw. kümmern zu müssen.
https://github.com/claycephus/csharp-date
quelle
Wenn Sie Datumsvergleiche durchführen müssen, verwenden Sie
Wenn Sie auf dem Bildschirm anzeigen, verwenden Sie
quelle
Lassen Sie mich spekulieren: Vielleicht liegt es daran, dass es bis SQL Server 2008 keinen Datentyp "Datum" in SQL gab, sodass es schwierig wäre, ihn in SQL Server zu speichern? Und es ist doch ein Microsoft-Produkt?
quelle
Wer weiß, warum es so ist. Im .NET Framework gibt es viele schlechte Entwurfsentscheidungen. Ich denke jedoch, dass dies ein ziemlich kleiner ist. Sie können den Zeitteil jederzeit ignorieren. Selbst wenn sich ein Code dafür entscheidet, dass sich eine DateTime auf mehr als nur das Datum bezieht, sollte der betreffende Code immer nur den Datumsteil anzeigen. Alternativ können Sie einen neuen Typ erstellen, der nur ein Datum darstellt, und Funktionen in DateTime verwenden, um das schwere Heben (Berechnungen) durchzuführen.
quelle
Warum? Wir können nur spekulieren und es hilft nicht viel bei der Lösung technischer Probleme. Eine gute Vermutung ist, dass sie
DateTime
alle Funktionen enthält, die eine solche Struktur haben würde.Wenn es Ihnen wirklich wichtig ist, schließen Sie einfach
DateTime
Ihre eigene unveränderliche Struktur ein, die nur das Datum verfügbar macht (oder sehen Sie sich dieDateTime.Date
Eigenschaft an).quelle
Neben Roberts Antwort haben Sie auch die
DateTime.ToShortDateString
Methode. Wenn Sie wirklich ein Date-Objekt möchten, können Sie jederzeit das Adaptermuster verwenden und das DateTime-Objekt umbrechen, um nur das anzuzeigen, was Sie möchten (z. B. Monat, Tag, Jahr).quelle
Es gibt immer die
DateTime.Date
Eigenschaft, die den Zeitteil der abschneidetDateTime
. Möglicherweise können Sie DateTime in Ihren eigenen Datumstyp kapseln oder einschließen.Und für die Frage, warum, denke ich, müssen Sie Anders Heljsberg fragen.
quelle
Denn um das Datum zu kennen, müssen Sie die Systemzeit (in Ticks) kennen, einschließlich der Uhrzeit - warum also diese Informationen wegwerfen?
DateTime
hat eineDate
Eigenschaft, wenn Sie sich überhaupt nicht um die Zeit kümmern.quelle
Ja, auch System.DateTime ist versiegelt. Ich habe einige Leute gesehen, die damit Spiele gespielt haben, indem sie eine benutzerdefinierte Klasse erstellt haben, um den String-Wert der Zeit zu erhalten, wie in früheren Beiträgen erwähnt, wie zum Beispiel:
Dies ist möglicherweise nicht erforderlich, da Sie GetShortTimeString einfach aus einem einfachen alten DateTime-Typ ohne eine neue Klasse extrahieren können
quelle
Wenn Sie die Eigenschaften Datum oder Heute verwenden, um nur den Datumsteil vom DateTime-Objekt abzurufen.
Dann erhalten Sie die Datumskomponente nur, wenn die Zeitkomponente auf Mitternacht eingestellt ist.
quelle