DateTime.Teraz kontra DateTime.UtcNow

Zastanawiałem się, jakie dokładnie są zasady działania tych dwóch właściwości. Wiem, że druga jest uniwersalna i w zasadzie nie zajmuje się strefami czasowymi, ale czy ktoś może szczegółowo wyjaśnić, jak one działają i która z nich powinna być użyta w jakim scenariuszu?

Author: Jedi Master Spooky, 2008-09-15

12 answers

DateTime.UtcNow mówi ci datę i godzinę tak, jak byłoby to w skoordynowanym czasie uniwersalnym, który jest również nazywany strefą czasową Greenwich Mean Time-w zasadzie tak, jakbyś był w Londynie w Anglii, ale nie w lecie. DateTime.Now podaje datę i godzinę tak, jak wydaje się to komuś w Twoim bieżącym języku.

Polecam używać DateTime.Now, gdy wyświetlasz datę człowiekowi - w ten sposób są one wygodne z wartością, którą widzą - jest to coś, co mogą łatwo porównać do tego, co widzą na zegarku lub zegarze. Użyj DateTime.UtcNow, gdy chcesz zapisać daty lub użyć ich do późniejszych obliczeń w ten sposób (w modelu klient-serwer) twoje obliczenia nie będą mylone przez klientów w różnych strefach czasowych od serwera lub od siebie.

 277
Author: Blair Conrad,
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-04-18 20:44:48

To naprawdę dość proste, więc myślę, że to zależy, jaka jest twoja publiczność i gdzie mieszkają.

Jeśli nie używasz Utc, musisz znać strefę czasową osoby, której wyświetlasz daty i godziny-w przeciwnym razie powiesz im, że coś wydarzyło się o 3 po południu w czasie systemowym lub serwerowym, kiedy naprawdę stało się o 5 po południu, gdzie zdarzy się żyć.

Używamy DateTime.UtcNow, ponieważ mamy globalną grupę odbiorców internetowych i dlatego, że wolałbym nie zrzędzić każdemu użytkownikowi, aby wypełnił formularz wskazując, w jakiej strefie czasowej żyją.

Wyświetlamy również względne czasy (2 godziny temu, 1 dzień temu itp.), aż post starzeje się na tyle, że czas jest "taki sam" bez względu na to, gdzie na Ziemi mieszkasz.

 73
Author: Jeff Atwood,
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
2008-09-15 11:03:36

Jedną z głównych koncepcji do zrozumienia w. NET jest to, że teraz jest teraz na całej ziemi, bez względu na strefę czasową, w której się znajdujesz. Więc jeśli załadujesz zmienną z DateTime.Teraz albo DateTime.UtcNow -- przypisanie jest identyczne.* Twój obiekt DateTime wie, w jakiej strefie czasowej się znajdujesz i bierze to pod uwagę niezależnie od przydziału.

Użyteczność DateTime.UtcNow jest przydatny przy obliczaniu dat w granicach czasu letniego. Czyli w miejscach, które weź udział w czasie letnim, czasami jest 25 godzin od południa do południa następnego dnia, a czasami są 23 godziny między południem a południem następnego dnia. Jeśli chcesz poprawnie określić liczbę godzin z czasu A i czasu B, musisz najpierw przetłumaczyć każdą z nich na ich odpowiedniki UTC przed obliczeniem czasu.

Jest to omówione w blogu, który napisałem, który dodatkowo wyjaśnia czas i zawiera link do jeszcze bardziej obszernego artykułu MS w temacie.

*Wyjaśnienie: każde przypisanie będzie przechowywać bieżący czas. Jeśli miałbyś załadować dwie zmienne po jednej przez DateTime.Now() i inne poprzez DateTime.UtcNow() różnica między nimi wynosi milisekundy, a nie Godziny, zakładając, że znajdujesz się w strefie czasowej godziny od GMT. Jak wspomniano poniżej, drukowanie ich wartości ciągów wyświetla różne ciągi.

 25
Author: Carl Camera,
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
2017-05-16 18:23:21

Zwróć również uwagę na różnicę wydajności; DateTime.UtcNow jest gdzieś około 30 razy szybszy niż DateTime.Teraz, ponieważ wewnętrznie DateTime.Teraz robi wiele korekt stref czasowych (można łatwo zweryfikować to za pomocą reflektora).

Więc nie używaj DateTime.Teraz względne pomiary czasu.

 24
Author: Magnus Krisell,
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
2009-02-21 13:16:17

To dobre pytanie. Odświeżam go, aby dać trochę więcej szczegółów na temat tego, jak. Net zachowuje się z różnymi "rodzajowymi" wartościami. Jak wskazuje @ Jan Zich, jest to w rzeczywistości krytycznie ważna właściwość i jest różnie ustawiana w zależności od tego, czy używasz teraz, czy UtcNow.

Wewnętrznie Data jest zapisywana jako "kleszcze", które (w przeciwieństwie do odpowiedzi @Carl Camera) różnią się w zależności od tego, czy używasz Now czy UtcNow.

DateTime.UtcNow zachowuje się jak inne języki. Ustawia kleszcze na GMT wartość oparta. Ustawia również "Kind" Na "Utc".

DateTime.Teraz zmienia wartość kleszczy na jaka byłaby twoja pora dnia w strefie czasowej GMT . Ustawia również "Kind" na "Local".

Jeśli jesteś 6 godzin do tyłu (GMT-6), otrzymasz Czas GMT sprzed 6 godzin. . Net faktycznie ignoruje "miły" i traktuje tym razem tak, jakby to było 6 godzin temu, mimo że miało być "teraz". To łamie się jeszcze bardziej, jeśli utworzysz instancję DateTime, a następnie zmienisz strefę czasową i spróbuj go użyć.

Instancje DateTime z różnymi wartościami "Kind" nie są kompatybilne.

Spójrzmy na jakiś kod...
    DateTime utc = DateTime.UtcNow;
    DateTime now = DateTime.Now;
    Debug.Log (utc + " " + utc.Kind);  // 05/20/2015 17:19:27 Utc
    Debug.Log (now + " " + now.Kind);  // 05/20/2015 10:19:27 Local

    Debug.Log (utc.Ticks);  // 635677391678617830
    Debug.Log (now.Ticks);  // 635677139678617840

    now = now.AddHours(1);
    TimeSpan diff = utc - now;
    Debug.Log (diff);  // 05:59:59.9999990

    Debug.Log (utc <  now);  // false
    Debug.Log (utc == now);  // false
    Debug.Log (utc >  now);  // true

    Debug.Log (utc.ToUniversalTime() <  now.ToUniversalTime());  // true
    Debug.Log (utc.ToUniversalTime() == now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() >  now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() -  now.ToUniversalTime());  // -01:00:00.0000010

Jak widać tutaj, porównania i funkcje matematyczne nie są automatycznie konwertowane na zgodne czasy. Czas powinien wynosić prawie godzinę, ale zamiast tego był prawie 6. "utc

Możesz również zobaczyć "obejście", które polega na prostym przekonwertowaniu do uniwersalnego czasu wszędzie tam, gdzie "Rodzaj" nie jest taki sam.

Moja bezpośrednia odpowiedź na pytanie zgadza się z przyjętą odpowiedzią na zalecenie, kiedy używać każdego z nich. Należy zawsze spróbować pracować z obiektami DateTime, które mają Kind = Utc, z wyjątkiem czasu wejścia / wyjścia (wyświetlania i parsowania). Oznacza to, że prawie zawsze powinieneś używać DateTime.UtcNow, z wyjątkiem przypadków, w których tworzysz obiekt tylko po to, aby go wyświetlić i natychmiast go odrzucić.

 13
Author: Ted Bigham,
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
2015-05-20 17:49:06

DateTime nie ma pojęcia, jakie są strefy czasowe. Zawsze zakłada, że jesteś w swoim czasie lokalnym. UtcNow oznacza tylko "odjąć moją strefę czasową od czasu".

Jeśli chcesz użyć dat świadomych strefy czasowej, użyj DateTimeOffset , który reprezentuje datę/czas ze strefą czasową. Musiałem się tego nauczyć na własnej skórze.

 6
Author: Omer van Kloeten,
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
2008-09-15 11:05:41

Tylko mały dodatek do powyższych punktów: struktura DateTime zawiera również mało znane pole o nazwie Kind (przynajmniej długo o tym nie wiedziałem). Jest to w zasadzie tylko flaga wskazująca, czy czas jest lokalny, czy UTC; nie określa rzeczywistego przesunięcia od UTC dla czasu lokalnego. Poza tym, że wskazuje, z jakimi intencjami został zbudowany, wpływa również na sposób, w jaki metody ToUniversalTime () i ToLocalTime () praca.

 4
Author: Jan Zich,
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
2009-04-18 00:12:29

"prosta" odpowiedź na pytanie brzmi:

DateTime.Now Zwraca wartość DateTime reprezentującą bieżący czas systemowy(w dowolnej strefie czasowej, w której system działa). DateTime.Rodzaj właściwość będzie DateTimeKind.Local

DateTime.UtcNow Zwraca wartość DateTime reprezentującą bieżący Uniwersalny czas koordynowany (znany również jako UTC), który będzie taki sam niezależnie od strefy czasowej systemu. Na DateTime.Rodzaj właściwość będzie DateTimeKind.Utc

 4
Author: PapillonUK,
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-09-14 15:43:17
 2
Author: Sorin Comanescu,
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-09-15 13:11:06

DateTime.UtcNow jest ciągłą, jednowartościową skalą czasową, natomiast DateTime.Teraz nie jest ciągła ani jednowartościowa. Głównym powodem jest czas letni, który nie ma zastosowania do czasu UTC. Tak więc UTC nigdy nie skacze do przodu ani do tyłu o godzinę, podczas gdy czas lokalny (DateTime.Teraz). A gdy przeskakuje do tyłu, ta sama wartość czasu występuje dwa razy.

 1
Author: user1315023,
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-09-08 13:49:53

DateTime.UtcNow jest uniwersalną skalą czasu pomijającą czas letni. Więc UTC nigdy nie zmienia się z powodu czasu DST.

Ale, DateTime.Teraz nie jest ciągła ani jednostajna, ponieważ zmienia się zgodnie z DST. Co oznacza DateTime.Teraz ta sama wartość czasu może wystąpić dwukrotnie, pozostawiając klientów w stanie dezorientacji.

 1
Author: ChaiVan,
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
2018-10-03 10:31:28

Jeśli potrzebujesz czasu lokalnego dla maszyny, na której działa Twoja aplikacja (jak CEST w Europie), użyj teraz. Jeśli chcesz uniwersalnego czasu-UtcNow. To tylko kwestia Twoich preferencji - prawdopodobnie tworzenie lokalnej strony internetowej / samodzielnej aplikacji, którą chcesz użyć w czasie, który Użytkownik ma-więc wpływ na jego ustawienie strefy czasowej-DateTime.Teraz.

Pamiętaj, że dla strony internetowej jest to ustawienie strefy czasowej serwera. Więc jeśli wyświetlasz czas dla użytkownika, albo uzyskaj jego preferowaną strefę czasową i przesuń czas (po prostu zapisz czas Utc do bazy danych i zmodyfikuj go) lub określ, że jest to UTC. Jeśli zapomnisz tego zrobić, user może zobaczyć coś w stylu: posted 3 minuses ago and then a time in the future near it:)

 0
Author: kender,
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
2008-09-15 11:04:40