[corlib] Cope with the reference sources' inability to support sub-minute DST offsets.
authorRolf Bjarne Kvinge <rolf@xamarin.com>
Fri, 24 Apr 2015 11:16:31 +0000 (13:16 +0200)
committerRolf Bjarne Kvinge <rolf@xamarin.com>
Mon, 27 Apr 2015 10:28:40 +0000 (12:28 +0200)
The reference sources do not support sub-minute DST offsets as the exception below
shows, while Europe/Dublin has a DST offset of 34:39 in 1916.

There is no equivalent TimeZoneInfo for Europe/Dublin in .NET, so the problem
doesn't show up there.

System.ArgumentException: The TimeSpan parameter cannot be specified more precisely than whole minutes.
Parameter name: daylightDelta

  at System.TimeZoneInfo/AdjustmentRule.ValidateAdjustmentRule (System.DateTime,System.DateTime,System.TimeSpan,System.TimeZoneInfo/TransitionTime,System.TimeZoneInfo/TransitionTime) [0x0012c] in /work/mono/master/external/referencesource/mscorlib/system/timezoneinfo.cs:3907
  at System.TimeZoneInfo/AdjustmentRule.CreateAdjustmentRule (System.DateTime,System.DateTime,System.TimeSpan,System.TimeZoneInfo/TransitionTime,System.TimeZoneInfo/TransitionTime) [0x00000] in /work/mono/master/external/referencesource/mscorlib/system/timezoneinfo.cs:3836
  at System.TimeZoneInfo.ParseTZBuffer (string,byte[],int) [0x002ca] in /work/mono/master/mcs/class/corlib/System/TimeZoneInfo.cs:1230
  at System.TimeZoneInfo.BuildFromStream (string,System.IO.Stream) [0x00030] in /work/mono/master/mcs/class/corlib/System/TimeZoneInfo.cs:479
  at System.TimeZoneInfo.FindSystemTimeZoneByFileName (string,string) [0x00018] in /work/mono/master/mcs/class/corlib/System/TimeZoneInfo.cs:463
  at System.TimeZoneInfo.FindSystemTimeZoneById (string) [0x00075] in /work/mono/master/mcs/class/corlib/System/TimeZoneInfo.cs:450
  at MonoTests.System.TimeZoneInfoTest/FindSystemTimeZoneByIdTests.Dublin () [0x00015] in /work/mono/master/mcs/class/corlib/Test/System/TimeZoneInfoTest.cs:812

mcs/class/corlib/System/TimeZoneInfo.cs
mcs/class/corlib/Test/System/TimeZoneInfoTest.cs

index aa93584c933c92e8461a9929723304005038acf9..dadd2b7003e8b8b045b054e60d0e345ab4f197ce 100644 (file)
@@ -1233,8 +1233,12 @@ namespace System
                                } else {
                                        if (daylightDisplayName != ttype.Name)
                                                daylightDisplayName = ttype.Name;
-                                       if (dstDelta.TotalSeconds != ttype.Offset - baseUtcOffset.TotalSeconds)
-                                               dstDelta = new TimeSpan(0, 0, ttype.Offset) - baseUtcOffset;
+                                       if (dstDelta.TotalSeconds != ttype.Offset - baseUtcOffset.TotalSeconds) {
+                                               // Round to nearest minute, since it's not possible to create an adjustment rule
+                                               // with sub-minute precision ("The TimeSpan parameter cannot be specified more precisely than whole minutes.")
+                                               // This happens with Europe/Dublin, which had an offset of 34 minutes and 39 seconds in 1916.
+                                               dstDelta = new TimeSpan (0, 0, ttype.Offset - ttype.Offset % 60) - baseUtcOffset;
+                                       }
 
                                        dst_start = ttime;
                                        dst_observed = true;
index 14c1246a4e6b50c2bec1fd30200a12aa26aaa51d..73bed53d10f0686626a00ea00d3e2d7de1edbcda 100644 (file)
@@ -802,6 +802,16 @@ namespace MonoTests.System
                                }               
                        }
                #endif
+
+                       [Test]
+                       public void Dublin ()
+                       {
+                               if (Environment.OSVersion.Platform != PlatformID.Unix)
+                                       Assert.Ignore ();
+                               // Europe/Dublin has a DST offset of 34 minutes and 39 seconds in 1916.
+                               TimeZoneInfo.FindSystemTimeZoneById ("Europe/Dublin");
+                       }
+
                }
                
                [TestFixture]