Zastanawiałem się, jakie dokładnie są zasady działania tych dwóch właściwości. Wiem, że drugi jest uniwersalny i zasadniczo nie zajmuje się strefami czasowymi, ale czy ktoś może szczegółowo wyjaśnić, jak działają i który z nich należy zastosować w jakim scenariuszu?
.net
language-features
date
Slavo
źródło
źródło
Odpowiedzi:
DateTime.UtcNow podaje datę i godzinę, tak jak w uniwersalnym czasie koordynowanym, który jest również nazywany strefą czasową średniego czasu Greenwich - w zasadzie tak, jakbyś był w Londynie w Anglii, ale nie latem. DateTime.Now podaje datę i godzinę, tak jak wyglądałoby to dla kogoś w twoim bieżącym języku.
Polecam używać,
DateTime.Now
gdy wyświetlasz randkę człowiekowi - w ten sposób czują się komfortowo z wartością, którą widzą - jest to coś, co mogą łatwo porównać z tym, 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 twojego serwera lub od siebie nawzajem.źródło
To naprawdę dość proste, więc myślę, że zależy to od tego, kim są twoi odbiorcy i gdzie mieszkają.
Jeśli nie używasz Utc, musisz znać strefę czasową osoby, dla której wyświetlasz daty i godziny - w przeciwnym razie powiesz im, że coś się wydarzyło o godzinie 15:00 w czasie systemowym lub na serwerze, a tak naprawdę stało się o godzinie 17:00, gdzie zdarzają się żyć.
Korzystamy z tego,
DateTime.UtcNow
ponieważ mamy globalną publiczność internetową, a ponieważ wolałbym nie nakłaniać każdego użytkownika do wypełnienia formularza wskazującego strefę czasową, w której żyją.Wyświetlamy także czasy względne (2 godziny temu, 1 dzień temu itp.), Dopóki post nie zestarzeje się wystarczająco, aby czas był „taki sam”, bez względu na to, gdzie mieszkasz na Ziemi.
źródło
Zwróć także uwagę na różnicę wydajności;
DateTime.UtcNow
jest gdzieś około 30 razy szybszyDateTime.Now
, ponieważ wewnętrznieDateTime.Now
wykonuje wiele regulacji strefy czasowej (można to łatwo zweryfikować za pomocą Odbłyśnika).Dlatego NIE używaj
DateTime.Now
do pomiaru czasu względnego.źródło
Jedną z głównych koncepcji, które należy zrozumieć 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ą przy pomocy
DateTime.Now
lubDateTime.UtcNow
- przypisanie jest identyczne. * TwójDateTime
obiekt wie, w której strefie czasowej się znajdujesz i bierze to pod uwagę niezależnie od zadania.Przydatność
DateTime.UtcNow
przydaje się przy obliczaniu dat w granicach czasu letniego. Oznacza to, że w miejscach, które uczestniczą w czasie letnim, czasami jest 25 godzin od południa do południa następnego dnia, a czasem są 23 godziny między południem a południem następnego dnia. Jeśli chcesz poprawnie określić liczbę godzin od czasu A i czasu B, musisz najpierw przeliczyć każdy z nich na ich odpowiedniki UTC przed obliczeniemTimeSpan
.Jest to objęte postem na blogu, który napisałem, który wyjaśnia
TimeSpan
i zawiera link do jeszcze obszerniejszego artykułu na ten temat.* Wyjaśnienie: Każde przypisanie zapisze bieżący czas. Jeśli było ładować za pomocą dwóch zmiennych jedną
DateTime.Now()
a drugą za pośrednictwemDateTime.UtcNow()
tejTimeSpan
różnicy między nimi byłaby milisekund, a nie godzin zakładając, że jesteś ze strefy czasowej godziny od GMT. Jak zauważono poniżej, wydrukowanie ichString
wartości spowoduje wyświetlenie różnych ciągów.źródło
To dobre pytanie. Odświeżam go, aby dać trochę więcej szczegółów na temat .Net zachowuje się z różnymi
Kind
wartościami. Jak zauważa @Jan Zich, jest to naprawdę bardzo ważna właściwość i jest różnie ustawiany w zależności od tego, czy używasz, czyNow
teżUtcNow
.Wewnętrznie przechowywana jest data, w
Ticks
której (w przeciwieństwie do odpowiedzi @Carl Camera) różni się w zależności od tego, czy używaszNow
lubUtcNow
.DateTime.UtcNow
zachowuje się jak inne języki. UstawiaTicks
wartość GMT. Ustawia równieżKind
naUtc
.DateTime.Now
zmieniaTicks
wartość na taką, jaka byłaby, gdyby była to Twoja pora dnia w strefie czasowej GMT . Ustawia równieżKind
naLocal
.Jeśli opóźnisz się o 6 godzin (GMT-6), otrzymasz czas GMT sprzed 6 godzin. .Net faktycznie ignoruje
Kind
i traktuje ten czas tak, jakby to było 6 godzin temu, nawet jeśli ma to być „teraz”. To się jeszcze bardziej psuje, jeśli utworzyszDateTime
instancję, a następnie zmień strefę czasową i spróbuj z niej skorzystać.Instancje DateTime z różnymi wartościami rodzaju nie są kompatybilne.
Spójrzmy na kod ...
Jak widać tutaj, porównania i funkcje matematyczne nie są automatycznie konwertowane na zgodne czasy.
Timespan
Powinien być prawie jedna godzina, ale zamiast tego był prawie 6. „UTC <teraz” powinno być prawdziwe (nawet dodaje godzinę, aby mieć pewność), ale nadal była fałszywa.Możesz także zobaczyć „obejście”, które polega na zamianie na czas uniwersalny w dowolnym miejscu, które
Kind
nie jest takie samo.Moja bezpośrednia odpowiedź na pytanie zgadza się z zaleceniem przyjętej odpowiedzi, kiedy należy użyć każdego z nich. Zawsze powinieneś próbować pracować z
DateTime
obiektami, które mająKind=Utc
, z wyjątkiem podczas operacji we / wy (wyświetlanie i parsowanie). 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 odrzucić go od razu.źródło
DateTime nie ma pojęcia, jakie są strefy czasowe. Zawsze zakłada, że jesteś w czasie lokalnym. UtcNow oznacza tylko „Odejmij moją strefę czasową od czasu”.
Jeśli chcesz używać dat uwzględniających strefę czasową, użyj DateTimeOffset , która reprezentuje datę / godzinę w strefie czasowej. Musiałem nauczyć się tego na własnej skórze.
źródło
„Prosta” odpowiedź na pytanie brzmi:
DateTime.Now zwraca wartość DateTime reprezentującą bieżący czas systemowy (w dowolnej strefie czasowej, w której działa system). Właściwością DateTime.Kind będzie DateTimeKind.Local
DateTime.UtcNow zwraca wartość DateTime reprezentującą bieżący uniwersalny czas koordynowany (inaczej UTC), który będzie taki sam bez względu na strefę czasową systemu. Właściwością DateTime.Kind będzie DateTimeKind.Utc
źródło
Mały dodatek do powyższych punktów: struktura DateTime zawiera także mało znane pole o nazwie Kind (przynajmniej nie wiedziałem o tym przez długi czas). Jest to w zasadzie tylko flaga wskazująca, czy czas jest lokalny, czy UTC; nie określa rzeczywistego przesunięcia względem UTC dla czasów lokalnych. Oprócz tego, że wskazuje, z jakimi intencjami zbudowano stuct, ma on również wpływ na sposób działania metod ToUniversalTime () i ToLocalTime () .
źródło
Nieco późno na imprezę, ale te dwa linki (4guysfromrolla) okazały się bardzo przydatne:
Użycie skoordynowanego czasu uniwersalnego (UTC) do przechowywania wartości daty / godziny
Wskazówki dotyczące przechowywania i wyświetlania dat i godzin w różnych strefach czasowych
źródło
DateTime.UtcNow jest ciągłą skalą czasową o pojedynczej wartości, natomiast DateTime.Now nie jest ciągłą ani pojedynczej wartości. Głównym powodem jest czas letni, który nie dotyczy UTC. Tak więc UTC nigdy nie przeskakuje o godzinę do przodu ani do tyłu, podczas gdy czas lokalny (DateTime.Now) tak. A kiedy przeskakuje do tyłu, ta sama wartość czasu występuje dwukrotnie.
źródło
DateTime.UtcNow to uniwersalna skala czasu pomijająca czas letni. Tak więc UTC nigdy się nie zmienia z powodu DST.
Ale DateTime.Now nie jest ciągły ani pojedynczej wartości, ponieważ zmienia się zgodnie z DST. Co oznacza, że DateTime.Now ta sama wartość czasu może wystąpić dwukrotnie, pozostawiając klientów w stanie zagubienia.
źródło
Jeśli potrzebujesz czasu lokalnego na maszynę, na której działa Twoja aplikacja (np. CEST dla Europy), użyj Now. Jeśli chcesz czasu uniwersalnego - UtcNow. To tylko kwestia twoich preferencji - prawdopodobnie stworzenie lokalnej witryny / samodzielnej aplikacji, z której chciałbyś skorzystać, korzystając z czasu użytkownika - więc na to wpływa jego ustawienie strefy czasowej - DateTime.Now.
Pamiętaj tylko, że w przypadku strony internetowej jest to ustawienie strefy czasowej serwera. Więc jeśli wyświetlasz czas dla użytkownika, pobierz jego preferowaną strefę czasową i zmień czas (po prostu zapisz czas Utc w bazie danych i zmodyfikuj go) lub określ UTC. Jeśli zapomnisz to zrobić, użytkownik zobaczy coś w rodzaju: opublikował 3 minusy temu, a potem czas w przyszłości :)
źródło
Duża różnica :) polega na tym, że DateTime.Now nie jest obsługiwany w przepływie pracy SharePoint, musisz użyć DateTime.UtcNow
źródło