Staram się wykorzystać DateTimeOffset
do przekazania określonego momentu w dowolnej strefie czasowej. Nie wiem, jak TimeZoneInfo
radzić sobie z czasem letnim.
var dt = DateTime.UtcNow;
Console.WriteLine(dt.ToLocalTime());
var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
Console.WriteLine(utcOffset.ToOffset(tz.BaseUtcOffset));
To drukuje:
02.06.2010 16:37:19 6/2/2010 15:37:19 PM -06: 00
Jestem w centralnej strefie czasowej, a obecnie obowiązuje czas letni. Próbuję odczytać drugą linijkę:
02.06.2010 16:37:19 -05: 00
BaseUtcOffset
najwyraźniej nie zmienia się na podstawie czasu letniego.
Jak uzyskać właściwy czas z odpowiednią wartością przesunięcia?
c#
datetimeoffset
timezone
jaminto
źródło
źródło
dt.Kind
jest ustawiony poprawnie.Odpowiedzi:
Musisz pobrać UtcOffset z TimeZoneInfo, a następnie przekazać to do metody ToOffset ():
var dt = DateTime.UtcNow; Console.WriteLine(dt.ToLocalTime()); var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"); var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero); Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset)));
źródło
DateTimeOffset
.Możesz również użyć TimeZoneInfo.ConvertTimeFromUtc, co pozwoli na czas letni:
DateTime utc = DateTime.UtcNow; TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"); DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utc, zone);
źródło
Lub lepiej, jeśli nie chcesz na stałe zakodować identyfikatora strefy czasowej :
źródło
TimeZoneInfo.Local
bezpośrednio? Dlaczego potrzebujesz telefonuFindSystemTimeZoneById
?DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(networkDateTime, TimeZoneInfo.Local);
Jestem początkującym zarówno w .NET, jak i stackoverflow, więc mogę się mylić, ale oto:
Korzystanie z TimeZoneInfo.ConvertTimeFromUtc pozwoli na czas letni i przekonwertuje go na prawidłowy czas zgodnie ze strefą czasową + możliwe przesunięcie czasu letniego. Jednak - samo przesunięcie w wynikowym obiekcie pokaże przesunięcie dla czasu standardowego i nie będzie uwzględniać czasu letniego. Więc jeśli chcesz wykonać ToString na obiekcie, skończysz z poprawnym czasem (w godzinach i minutach), ale z niewłaściwym przesunięciem w czasie czasu letniego, co może prowadzić do niewłaściwego momentu później w kodzie.
Jeśli zamiast tego użyjesz GetUtcOffset, aby uzyskać przesunięcie dla określonego czasu, a następnie wykonasz ToOffset w obiekcie DateTimeOffset, zarówno godziny / minuty, jak i samo przesunięcie zostaną poprawnie przekonwertowane i możesz bezpiecznie wykonać ToString.
string ExpectedDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss''zzz"; string timeZoneId = "FLE Standard Time"; string dateTimestr = "2017-10-09T09:00:00+02:00"; DateTimeOffset dto = DateTimeOffset.Parse(dateTimeStr); TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); TimeSpan offset = zone.GetUtcOffset(dto); dto = dto.ToOffset(offset); string localTime = dto.ToString(ExpectedDateTimePattern);
localTime zwróci „2017-10-09T10: 00: 00 + 03: 00”.
datetimeoffset timezoneinfo getutcoffset
źródło