[mono/mono] [2 commits] 5c3c64d3: TimeZone.GetUtcOffset should use Standard UTC offsets for the period when daylight savings ends.

"Miguel de Icaza ([email protected])" <[email protected]> Wed, 20 Nov 2013 17:36:13 +0000
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <0000014276956b81-e8566b2a-09d4-43de-a280-6290c6e421fb-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/9a587b5266b8...05007a63c593

   Commit: 5c3c64d36838b9373b43516bdcda97e6abb1afc1
   Author: Alistair Bush <[email protected]> (alistair)
     Date: 2013-11-10 09:36:11 GMT
      URL: https://github.com/mono/mono/commit/5c3c64d36838b9373b43516bdcda97e6abb1afc1

TimeZone.GetUtcOffset should use Standard UTC offsets for the period when daylight savings ends.

Changed paths:
  M mcs/class/corlib/System/TimeZone.cs
  M mcs/class/corlib/Test/System/TimeZoneTest.cs

Modified: mcs/class/corlib/System/TimeZone.cs
===================================================================
@@ -357,12 +357,22 @@ public override TimeSpan GetUtcOffset (DateTime time)
 			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);

Modified: mcs/class/corlib/Test/System/TimeZoneTest.cs
===================================================================
@@ -281,6 +281,45 @@ public void ToLocalTimeAtDSTBoundaries ()
 	}
 
 		[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 ()
 		{
 			Assert.IsNotNull (TimeZoneInfo.Local, "Local");

   Commit: 05007a63c593ae2ae959613d4fc95896f7d6cf60
   Author: Miguel de Icaza <[email protected]> (migueldeicaza)
     Date: 2013-11-20 17:34:07 GMT
      URL: https://github.com/mono/mono/commit/05007a63c593ae2ae959613d4fc95896f7d6cf60

Merge pull request #802 from alistair/universaltime_at_boundary_end

TimeZone.GetUtcOffset daylight savings improvements

Changed paths:
  M mcs/class/corlib/System/TimeZone.cs
  M mcs/class/corlib/Test/System/TimeZoneTest.cs

Modified: mcs/class/corlib/System/TimeZone.cs
===================================================================
@@ -357,12 +357,22 @@ public override TimeSpan GetUtcOffset (DateTime time)
 			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);

Modified: mcs/class/corlib/Test/System/TimeZoneTest.cs
===================================================================
@@ -281,6 +281,45 @@ public void ToLocalTimeAtDSTBoundaries ()
 	}
 
 		[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 ()
 		{
 			Assert.IsNotNull (TimeZoneInfo.Local, "Local");


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches