Różnica między systemem.DateTime.Teraz i System.DateTime.Dzisiaj
Czy ktoś może wyjaśnić różnicę między System.DateTime.Now
a System.DateTime.Today
w C#.NET? plusy i minusy każdego, jeśli to możliwe.
5 answers
DateTime.Now
Zwraca wartość DateTime
, która składa się z lokalnej daty i czasu komputera, na którym uruchomiony jest kod. Posiada DateTimeKind.Local
przypisane do swojej własności Kind
. Jest równoznaczne z wywołaniem dowolnego z poniższych:
DateTime.UtcNow.ToLocalTime()
DateTimeOffset.UtcNow.LocalDateTime
DateTimeOffset.Now.LocalDateTime
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local)
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local)
DateTime.Today
Zwraca wartość DateTime
, która ma takie same składniki Rok, Miesiąc i dzień, jak każde z powyższych wyrażeń, ale ze składnikami czasu ustawionymi na zero. Informatyka posiada również DateTimeKind.Local
w swojej własności Kind
. Jest to równoważne którejkolwiek z następujących wartości:
DateTime.Now.Date
DateTime.UtcNow.ToLocalTime().Date
DateTimeOffset.UtcNow.LocalDateTime.Date
DateTimeOffset.Now.LocalDateTime.Date
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local).Date
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local).Date
Zauważ, że wewnętrznie, zegar systemowy jest w kategoriach UTC, więc gdy wywołasz {[3] } najpierw dostaje czas UTC (poprzez GetSystemTimeAsFileTime
funkcja w API Win32), a następnie zamienia wartość na lokalną strefę czasową. (Dlatego {[24] } jest droższy niż DateTime.UtcNow
.)
Zauważ również, że DateTimeOffset.Now.DateTime
będzie miał podobne wartości do DateTime.Now
, ale będzie miał DateTimeKind.Unspecified
zamiast DateTimeKind.Local
- co może prowadzić do innych błędów w zależności od tego, co z nim zrobisz.
Więc prosta odpowiedź jest taka, że DateTime.Today
jest równoważna DateTime.Now.Date
.
ale IMHO - nie powinieneś używać ani jednego z tych, ani żadnego z powyższych odpowiedników.
Kiedy pytasz o DateTime.Now
, pytasz o wartość lokalnego zegara kalendarza komputera, że kod jest biegnę dalej. Ale to, co dostajesz, nie ma żadnych informacji o tym zegarze! Najlepsze co dostajesz to to DateTime.Now.Kind == DateTimeKind.Local
. Ale czyja to miejscówka? Informacje te zostają utracone, gdy tylko zrobisz cokolwiek z wartością, na przykład przechowasz je w bazie danych, wyświetlasz na ekranie lub przesyłasz za pomocą usługi internetowej.
Jeśli Twoja lokalna Strefa czasowa przestrzega zasad dotyczących czasu letniego, nie otrzymasz tych informacji z DateTime.Now
. W niejednoznacznych czasach, np. podczas przejścia" jesiennego", nie będzie wiedział, który z dwóch możliwych momentów odpowiada wartości pobranej z DateTime.Now
. Załóżmy na przykład, że strefa czasowa systemu jest ustawiona na Mountain Time (US & Canada)
i poprosisz o DateTime.Now
we wczesnych godzinach 3 listopada 2013 roku. Co oznacza wynik 2013-11-03 01:00:00
? Istnieją dwa momenty czasu chwilowego reprezentowane przez tę samą DateTime kalendarza. Gdybym wysłała tę wartość komuś innemu, nie mieliby pojęcia, o którą mi chodziło. Zwłaszcza, jeśli znajdują się w strefie czasowej, w której zasady są inaczej.
Najlepiej byłoby użyć DateTimeOffset
zamiast:
// This will always be unambiguous.
DateTimeOffset now = DateTimeOffset.Now;
Teraz dla tego samego scenariusza, który opisałem powyżej, otrzymuję wartość 2013-11-03 01:00:00 -0600
przed przejściem, lub 2013-11-03 01:00:00 -0700
po przejściu. Każdy, kto spojrzy na te wartości, może powiedzieć, co miałem na myśli.
Napisałem post na blogu na ten właśnie temat. Proszę przeczytać - sprawę przeciwko DateTime.Teraz .
Są też miejsca na świecie (np. Brazylia), gdzie " wiosna-naprzód" przejście następuje dokładnie o północy. Zegary od 23: 59 do 01: 00. Oznacza to, że wartość DateTime.Today
w tym dniu, nie istnieje! nawet jeśli używasz DateTimeOffset.Now.Date
, otrzymujesz ten sam wynik i nadal masz ten problem. Dzieje się tak dlatego, że tradycyjnie nie było czegoś takiego jak Date
obiekt w .Net. więc niezależnie od tego, jak uzyskasz wartość, po usunięciu czasu - musisz pamiętać, że tak naprawdę nie reprezentuje "północy", mimo że to wartość, z którą pracujesz.
Jeśli naprawdę chcesz w pełni poprawnego rozwiązania tego problemu, najlepszym podejściem jest użycie NodaTime . Klasa LocalDate
poprawnie reprezentuje datę bez czasu. Można uzyskać bieżącą datę dla dowolnej strefy czasowej, w tym lokalnej strefy czasowej systemu:
using NodaTime;
...
Instant now = SystemClock.Instance.Now;
DateTimeZone zone1 = DateTimeZoneProviders.Tzdb.GetSystemDefault();
LocalDate todayInTheSystemZone = now.InZone(zone1).Date;
DateTimeZone zone2 = DateTimeZoneProviders.Tzdb["America/New_York"];
LocalDate todayInTheOtherZone = now.InZone(zone2).Date;
Jeśli nie chcesz używać czasu Noda, jest teraz inna opcja. Dodałem implementację obiektu tylko do daty do projektu . Net CoreFX Lab. Obiekt System.Time
package można znaleźć w ich kanale MyGet. Po dodaniu do projektu przekonasz się, że możesz wykonać jedną z następujących czynności:]}
using System;
...
Date localDate = Date.Today;
Date utcDate = Date.UtcToday;
Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-15 19:43:21
Czas. .Now
zawiera 09:23:12 lub cokolwiek innego; .Today
jest tylko częścią daty (o 00:00:00 tego dnia).
Więc użyj .Now
, jeśli chcesz podać godzinę, i .Today
, jeśli chcesz tylko datę!
.Today
jest zasadniczo tym samym co .Now.Date
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-01 08:08:23
Właściwość DateTime.Now
zwraca bieżącą datę i czas, na przykład 2011-07-01 10:09.45310
.
Właściwość DateTime.Today
zwraca bieżącą datę z parametrami czasu ustawionymi na zero, na przykład 2011-07-01 00:00.00000
.
Właściwość DateTime.Today
jest zaimplementowana do zwracania DateTime.Now.Date
:
public static DateTime Today {
get {
DateTime now = DateTime.Now;
return now.Date;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-31 18:29:38
DateTime.Today przedstawia aktualną datę systemową z częścią czasu ustawioną na 00: 00: 00
I
DateTime.Now przedstawia aktualną datę i godzinę systemową
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-29 05:55:55