W naszym projekcie C # mamy potrzebę reprezentowania daty bez czasu. Wiem o istnieniu DateTime, jednak zawiera on również porę dnia. Chcę wyraźnie zaznaczyć, że niektóre zmienne i argumenty metod są oparte na datach . Dlatego nie mogę korzystać z DateTime.Date
nieruchomości
Jakie są standardowe podejścia do tego problemu? Z pewnością nie jestem pierwszym, który się z tym spotka? Dlaczego nie ma Date
klasy w C #?
Czy ktoś ma ładną implementację wykorzystującą strukturę i może jakieś metody rozszerzeń w DateTime i może implementując jakieś operatory, takie jak == i <,>?
DateTime
powodują?Odpowiedzi:
Pozwól mi dodać aktualizację do tego klasycznego pytania:
Biblioteka Jona Skeeta Noda Time jest teraz dość dojrzała i zawiera tylko typ daty o nazwie
LocalDate
. (Lokalny w tym przypadku oznacza po prostu lokalny dla kogoś , niekoniecznie lokalny dla komputera, na którym działa kod).Wywołany typ zawierający tylko datę
Date
to proponowany dodatek do platformy .NET Core za pośrednictwem projektu corefxlab . Znajdziesz go wSystem.Time
pakiecie wraz zTimeOfDay
typem i kilkoma metodami rozszerzającymi do istniejących typów.Przestudiowałem ten problem w znacznym stopniu, więc podzielę się również kilkoma powodami konieczności tego typu:
Istnieje logiczna rozbieżność między wartością zawierającą tylko datę a wartością typu „data północy”.
Nie każdy lokalny dzień ma północ w każdej strefie czasowej. Przykład: Brazylijska zmiana czasu wiosennego na czas letni przesuwa zegar z 11:59:59 na 01:00:00.
Data-godzina zawsze odnosi się do określonej godziny w ciągu dnia, podczas gdy tylko data może odnosić się do początku dnia, końca dnia lub całego zakresu dnia.
Dołączanie godziny do daty może prowadzić do zmiany daty, ponieważ wartość jest przekazywana z jednego środowiska do drugiego, jeśli strefy czasowe nie są bardzo uważnie obserwowane. Zwykle ma to miejsce w JavaScript (którego
Date
obiektem jest tak naprawdę data + godzina), ale może się łatwo zdarzyć również w .NET lub w serializacji, gdy dane są przesyłane między JavaScript a .NET.Serializacja
DateTime
z XML lub JSON (i innymi) zawsze będzie zawierać czas, nawet jeśli nie jest to ważne. Jest to bardzo zagmatwane, zwłaszcza biorąc pod uwagę takie rzeczy, jak daty urodzenia i rocznice, gdzie czas nie ma znaczenia.Z architektonicznego
DateTime
punktu widzenia jest obiektem wartości DDD , ale narusza pojedynczą zasadę odpowiedzialnie na kilka sposobów:Został zaprojektowany jako typ daty i godziny, ale często jest używany tylko jako data (ignorowanie godziny) lub tylko jako godzina (ignorowanie daty). (
TimeSpan
jest również często używany do określania pory dnia, ale to inny temat).DateTimeKind
Wartość dołączone do.Kind
majątku dzieli jeden typ do trzech,Unspecified
rodzaj jest naprawdę oryginalne założenia struktury i powinny być używane w ten sposób. TheUtc
kind Wyrównuje wartości specyficznie z czasem UTC, aLocal
kind Wyrównuje wartości z lokalnej strefy czasowej środowiska jest.Problem z posiadaniem oddzielnej flagi dla rodzaju polega na tym, że za każdym razem, gdy konsumujesz
DateTime
, powinieneś sprawdzić,.Kind
aby zdecydować, jakie zachowanie przyjąć. Wszystkie metody ramowe to robią, ale inni często zapominają. Jest to naprawdę naruszenie SRP, ponieważ typ ma teraz dwa różne powody do zmiany (wartość i rodzaj).Oba z nich prowadzą do kompilacji zastosowań API, ale często są bezsensowne lub mają dziwne przypadki skrajne spowodowane efektami ubocznymi. Rozważać:
Podsumowując, chociaż a
DateTime
może być używane tylko do daty, powinno to robić tylko wtedy, gdy każde miejsce, które go używa, jest bardzo ostrożne, aby zignorować czas, a także bardzo ostrożnie, aby nie próbować konwertować do iz UTC lub innego strefy czasowe.źródło
System.Time.Date
skończył we frameworku .NET: /System.Time
tak jak każdy inny pakiet. Po prostu nie jest to jeszcze „oficjalne”.Podejrzewam, że nie ma dedykowanej czystej
Date
klasy, ponieważ już masz,DateTime
która może sobie z tym poradzić. PosiadanieDate
prowadziłoby do powielania i zamieszania.Jeśli chcesz zastosować podejście standardowe, spójrz na
DateTime.Date
właściwość, która podaje tylko część daty aDateTime
z wartością czasu ustawioną na 12:00:00 północ (00:00:00).źródło
Wysłałem e-mail na adres [email protected] i to jest ich odpowiedź
W moim e-mailu spytałem, czy to dlatego, że DateTime używa TimeZoneInfo do uzyskania czasu maszyny - we właściwości Now. Powiedziałbym więc, że to dlatego, że „zasady biznesowe” są „zbyt powiązane”, powiedzieli mi to.
źródło
SpaceTime
klasę! Hej, według Einsteina, przestrzeń i czas są ze sobą ściśle powiązane, więc nie powinniśmy też musieć ich rozróżniać, prawda? (!!!!!!!!!!!) Jestem trochę nowych do C #, ale muszę powiedzieć, że to pole minowe pochodzących z VB.NET, gdzie jest, po prostu,date
,Today()
,now
, itd. NieDateTime
poprzedzając śmieci, nie grzebać. (A te średniki i ta rozróżnianie wielkości liter są z pewnością irytujące! Po prostu zastrzel mnie!)Date
typ, a wynik musi być typuDate
- jeśli był toDate
typ wynik oczekiwany jako ciąg bez czasu. Na przykład Delphi mają również Date jako DateTime, ale typinfo jest inny dla Date i DateTime.Stworzyłem prostą strukturę Date dla czasów, kiedy potrzebujesz prostej daty bez martwienia się o część czasową, strefy czasowe, lokalną i utc itp.
https://github.com/claycephus/csharp-date
źródło
Jeśli chcesz przeprowadzić porównania dat, użyj
Jeśli wyświetlasz na ekranie, użyj
źródło
Pozwólcie, że spekuluję: Może to dlatego, że do SQL Server 2008 nie było w SQL typu danych typu Date, więc byłoby to trudne, więc przechowywać go na serwerze SQL? A to przecież produkt Microsoft?
źródło
Kto wie, dlaczego tak jest. W środowisku .NET jest wiele złych decyzji projektowych. Uważam jednak, że jest to dość drobne. Zawsze możesz zignorować część czasu, więc nawet jeśli jakiś kod zdecyduje, że DateTime odwołuje się do czegoś więcej niż tylko daty, kod, który dba o to, powinien zawsze patrzeć tylko na część daty. Alternatywnie możesz utworzyć nowy typ, który reprezentuje tylko datę i użyć funkcji w DateTime, aby wykonać ciężkie podnoszenie (obliczenia).
źródło
Czemu? Możemy tylko spekulować, a to niewiele pomaga w rozwiązaniu problemów inżynieryjnych. Można przypuszczać, że
DateTime
zawiera wszystkie funkcje, jakie miałaby taka struktura.Jeśli naprawdę ma to dla Ciebie znaczenie, po prostu zawiń
DateTime
swoją własną niezmienną strukturę, która ujawnia tylko datę (lub spójrz naDateTime.Date
właściwość).źródło
Oprócz odpowiedzi Roberta masz również
DateTime.ToShortDateString
metodę. Ponadto, jeśli naprawdę chciałbyś mieć obiekt Date, zawsze możesz użyć wzorca Adapter i zawinąć obiekt DateTime, pokazując tylko to, co chcesz (tj. Miesiąc, dzień, rok).źródło
Zawsze istnieje
DateTime.Date
nieruchomość, która odcina część czasowąDateTime
. Może możesz hermetyzować lub zawijać DateTime we własnym typie Date.A jeśli chodzi o pytanie, cóż, myślę, że będziesz musiał zapytać Andersa Heljsberga.
źródło
Ponieważ aby poznać datę, musisz znać czas systemowy (w tickach), który obejmuje czas - więc po co wyrzucać tę informację?
DateTime
maDate
własność, jeśli w ogóle nie zależy Ci na czasie.źródło
Tak, również System.DateTime jest zapieczętowany. Widziałem, jak niektórzy grają w takie gry, tworząc niestandardową klasę tylko po to, aby uzyskać wartość ciągu czasu, jak wspomniano we wcześniejszych postach, takie jak:
Może to być niepotrzebne, ponieważ można łatwo wyodrębnić GetShortTimeString ze zwykłego starego typu DateTime bez nowej klasy
źródło
Jeśli używasz właściwości Date lub Today, aby uzyskać tylko część daty z obiektu DateTime.
Wtedy otrzymasz składnik daty tylko z elementem czasu ustawionym na północ.
źródło