ARTICLE AD BOX
C# .NET 8 appears to be mishandling conversion of local times to UTC for times 12am..2am on daylight saving transition days. E.g.
var fallBack = new DateOnly(2026, 10, 25); var tzi = TimeZoneInfo.FindSystemTimeZoneById("Europe/London"); var oneAm = fallBack.ToDateTime(new TimeOnly(1, 0)); var utc = TimeZoneInfo.ConvertTimeToUtc(oneAm, tzi); // wrong because transition occurs at 2am Debug.Assert(!tzi.IsDaylightSavingTime(oneAm)); // wrong because utc should be midnight Debug.Assert(utc.Hour != 0);This is confusing because TimeZoneInfo.ConvertTimeToUtc() will throw an exception for impossible local times (during spring forward) giving the false impression of proper transition day handling.
I have a workaround but want this here for others to find and for alternative solutions.
1
I've discovered a couple things:
Daylight saving transition days occur on different days depending on the time zone / region (e.g. London different to Toronto)
While TimeZoneInfo.ConvertTimeToUtc() does throw for impossible local times, it only understands daylight saving on a whole-day basis (and so 1am calculations will be wrong)
Work around: subtract 2 hours when necessary (and add it back later)
/// Convert to UTC public static DateTime ResolveUtc(DateOnly date, TimeOnly time, TimeZoneInfo tzi) { // Need to work around UTC conversion not working in early morning before transitions var workAround = tzi.SupportsDaylightSavingTime && time < new TimeOnly(2, 0); var dateTime = date.ToDateTime(time); if (workAround) { dateTime = dateTime.AddHours(-2); } var result = TimeZoneInfo.ConvertTimeToUtc(dateTime, tzi); if (workAround) { result = result.AddHours(2); } return result; }Explore related questions
See similar questions with these tags.
