TimeZone.GetUtcOffset should use Standard UTC offsets for the period when daylight...
authorAlistair Bush <alistair.bush@gmail.com>
Sun, 10 Nov 2013 09:36:11 +0000 (09:36 +0000)
committerAlistair Bush <alistair.bush@gmail.com>
Sun, 10 Nov 2013 09:36:11 +0000 (09:36 +0000)
mcs/class/corlib/System/TimeZone.cs
mcs/class/corlib/Test/System/TimeZoneTest.cs

index 316e99ce44b45950e71ca0162b679ae5ad439fef..5e11d8d53dd6ad74baf301dd1cbd8ddbc7b3412c 100644 (file)
@@ -357,12 +357,22 @@ namespace System
                        if (time.Kind == DateTimeKind.Utc)
                                return TimeSpan.Zero;
 
-                       if (IsDaylightSavingTime (time))
+                       if (IsDaylightSavingTime (time) && !IsAmbiguousTime (time))
                                return utcOffsetWithDLS;
 
                        return utcOffsetWithOutDLS;
                }
 
+               private bool IsAmbiguousTime (DateTime time)
+               {
+                       if (time.Kind == DateTimeKind.Utc)
+                               return false;
+
+                       DaylightTime changes = GetDaylightChanges (time.Year);
+
+                       return time < changes.End && time >= changes.End - changes.Delta;
+               }
+
                void IDeserializationCallback.OnDeserialization (object sender)
                {
                        OnDeserialization (null);
index 0e369de49b9e25aa7fc89af8b4fb039d22a6060b..4403fd6346bf0c9433bc4f3c2a9a6877ddb708c2 100644 (file)
@@ -280,6 +280,45 @@ public class TimeZoneTest {
                Assert.IsTrue (tz.ToLocalTime (dst_start_utc.Add (new TimeSpan (1, 0, 0))) < tz.ToLocalTime (dst_start_utc.Add (new TimeSpan (1, 1, 0))), "0:4:00 < 0:4:01");
        }
 
+               [Test]
+               public void GetUtcOffsetAtDSTBoundary ()
+               {
+                       /*
+                        * Getting a definitive list of timezones which do or don't observe Daylight
+                        * Savings is difficult (can't say America's or USA definitively) and lengthy see 
+                        *
+                        * http://en.wikipedia.org/wiki/Daylight_saving_time_by_country
+                        *
+                        * as a good starting point for a list.
+                        *
+                        * The following are SOME of the timezones/regions which do support daylight savings.
+                        *
+                        * Pacific/Auckland
+                        * Pacific/Sydney
+                        * USA (EST, CST, MST, PST, AKST) note this does not cover all states or regions
+                        * Europe/London (GMT)
+                        * CET (member states of the European Union)
+                        *
+                        * This test should work in all the above timezones
+                        */
+
+
+                       TimeZone tz = TimeZone.CurrentTimeZone;
+                       DaylightTime daylightChanges = tz.GetDaylightChanges(2007);
+                       DateTime dst_end = daylightChanges.End;
+
+                       if (dst_end == DateTime.MinValue)
+                               Assert.Ignore (tz.StandardName + " did not observe daylight saving time during 2007.");
+
+                       var standardOffset = tz.GetUtcOffset(daylightChanges.Start.AddMinutes(-1));
+
+                       Assert.AreEqual(standardOffset, tz.GetUtcOffset (dst_end));
+                       Assert.AreEqual(standardOffset, tz.GetUtcOffset (dst_end.Add (daylightChanges.Delta.Negate ().Add (TimeSpan.FromSeconds(1)))));
+                       Assert.AreEqual(standardOffset, tz.GetUtcOffset (dst_end.Add(daylightChanges.Delta.Negate ())));
+                       Assert.AreNotEqual(standardOffset, tz.GetUtcOffset (dst_end.Add(daylightChanges.Delta.Negate ().Add (TimeSpan.FromSeconds(-1)))));
+               }
+
+
                [Test]
                public void StaticProperties ()
                {