Mam witrynę internetową, która jest hostowana w innej strefie czasowej niż użytkownicy korzystający z aplikacji. Oprócz tego użytkownicy mogą mieć określoną strefę czasową. Zastanawiałem się, jak podchodzą do tego inni użytkownicy SO i aplikacje? Najbardziej oczywistą częścią jest to, że w DB data / czas są przechowywane w UTC. Na serwerze wszystkie daty / godziny powinny być obsługiwane w czasie UTC. Widzę jednak trzy problemy, które próbuję rozwiązać:
Pobieranie aktualnego czasu w UTC (łatwe rozwiązanie za pomocą
DateTime.UtcNow
).Pobieranie daty / godzin z bazy danych i wyświetlanie ich użytkownikowi. Potencjalnie jest wiele wezwań do drukowania dat w różnych widokach. Myślałem o jakiejś warstwie między widokiem a kontrolerami, która mogłaby rozwiązać ten problem. Lub mając włączoną niestandardową metodę rozszerzenia
DateTime
(patrz poniżej). Główną wadą jest to, że w każdym miejscu korzystania z daty i godziny w widoku należy wywołać metodę rozszerzenia!To również utrudniłoby używanie czegoś takiego jak
JsonResult
. Nie można już było łatwo zadzwonićJson(myEnumerable)
, musiałoby byćJson(myEnumerable.Select(transformAllDates))
. Może AutoMapper mógłby pomóc w tej sytuacji?Pobieranie danych od użytkownika (lokalnie do UTC). Na przykład POST przesłanie formularza z datą wymagałoby konwersji daty na UTC wcześniej. Pierwszą rzeczą, która przychodzi na myśl, jest stworzenie niestandardowego
ModelBinder
.
Oto rozszerzenia, których użyłem w widokach:
public static class DateTimeExtensions
{
public static DateTime UtcToLocal(this DateTime source,
TimeZoneInfo localTimeZone)
{
return TimeZoneInfo.ConvertTimeFromUtc(source, localTimeZone);
}
public static DateTime LocalToUtc(this DateTime source,
TimeZoneInfo localTimeZone)
{
source = DateTime.SpecifyKind(source, DateTimeKind.Unspecified);
return TimeZoneInfo.ConvertTimeToUtc(source, localTimeZone);
}
}
Myślę, że zajmowanie się strefami czasowymi byłoby tak powszechne, biorąc pod uwagę, że wiele aplikacji jest teraz opartych na chmurze, gdzie lokalny czas serwera może być znacznie inny niż oczekiwana strefa czasowa.
Czy zostało to wcześniej elegancko rozwiązane? Czy jest coś, czego mi brakuje? Bardzo cenione są pomysły i przemyślenia.
EDYCJA: Aby usunąć zamieszanie, pomyślałem, że dodaj więcej szczegółów. Kwestia teraz nie ma jak do przechowywania UTC razy w db, to więcej o procesie dzieje z UTC-> Lokalne> szczeblu lokalnym i UTC. Jak wskazuje @Max Zerbini, oczywiście mądrze jest umieścić kod UTC-> lokalny w widoku, ale czy DateTimeExtensions
naprawdę używa się odpowiedzi? Czy podczas uzyskiwania danych wejściowych od użytkownika sensowne jest akceptowanie dat jako czasu lokalnego użytkownika (ponieważ tego właśnie używałby JS), a następnie używanie ModelBinder
do przekształcenia na UTC? Strefa czasowa użytkownika jest przechowywana w bazie danych i można ją łatwo odzyskać.
ModelBinder
.