From c2b5d5a707e3bb037df847e17b4e55e19fd5bfa8 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Tue, 14 Mar 2017 12:12:04 -0700 Subject: [PATCH] Fix tz rules (#10169) * Fix the TZ Rule data on Linux On Linux when the caller ask for the TZ adjustment rules we convert the internal stored rule data from UTC to local time. we used to TZI.Convert which is wrong because calculating the start the daylight start time should always not include the daylight delta because we didn't start the daylight saving yet. and calculating the end of daylight should always include the daylight delta because we were in the daylight saving period. The fix here is manually calculating the start and end of the daylight saving inside the rule * Revert the comment change * Add a comment --- src/mscorlib/src/System/TimeZoneInfo.Unix.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/mscorlib/src/System/TimeZoneInfo.Unix.cs b/src/mscorlib/src/System/TimeZoneInfo.Unix.cs index b94c8b7..bb12c6b 100644 --- a/src/mscorlib/src/System/TimeZoneInfo.Unix.cs +++ b/src/mscorlib/src/System/TimeZoneInfo.Unix.cs @@ -128,8 +128,8 @@ namespace System return Array.Empty(); } - // The rules we use in Unix cares mostly about the start and end dates but doesn’t fill the transition start and end info. - // as the rules now is public, we should fill it properly so the caller doesn’t have to know how we use it internally + // The rules we use in Unix care mostly about the start and end dates but don't fill the transition start and end info. + // as the rules now is public, we should fill it properly so the caller doesn't have to know how we use it internally // and can use it as it is used in Windows AdjustmentRule[] rules = new AdjustmentRule[_adjustmentRules.Length]; @@ -138,10 +138,14 @@ namespace System { var rule = _adjustmentRules[i]; var start = rule.DateStart.Kind == DateTimeKind.Utc ? - new DateTime(TimeZoneInfo.ConvertTime(rule.DateStart, this).Ticks, DateTimeKind.Unspecified) : + // At the daylight start we didn't start the daylight saving yet then we convert to Local time + // by adding the _baseUtcOffset to the UTC time + new DateTime(rule.DateStart.Ticks + _baseUtcOffset.Ticks, DateTimeKind.Unspecified) : rule.DateStart; var end = rule.DateEnd.Kind == DateTimeKind.Utc ? - new DateTime(TimeZoneInfo.ConvertTime(rule.DateEnd, this).Ticks - 1, DateTimeKind.Unspecified) : + // At the daylight saving end, the UTC time is mapped to local time which is already shifted by the daylight delta + // we calculate the local time by adding _baseUtcOffset + DaylightDelta to the UTC time + new DateTime(rule.DateEnd.Ticks + _baseUtcOffset.Ticks + rule.DaylightDelta.Ticks, DateTimeKind.Unspecified) : rule.DateEnd; var startTransition = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, start.Hour, start.Minute, start.Second), start.Month, start.Day); -- 2.7.4