Bug #352210 fix, and add support for RoundtripKind parsing.
authorRoei Erez <roeie@mono-cvs.ximian.com>
Sun, 2 Mar 2008 06:56:47 +0000 (06:56 -0000)
committerRoei Erez <roeie@mono-cvs.ximian.com>
Sun, 2 Mar 2008 06:56:47 +0000 (06:56 -0000)
svn path=/trunk/mcs/; revision=97116

mcs/class/corlib/System/ChangeLog
mcs/class/corlib/System/DateTime.cs
mcs/class/corlib/Test/System/ChangeLog
mcs/class/corlib/Test/System/DateTimeTest.cs

index 85f186f111fa4b678a687749ffae79866038b818..b38e8ee27d406f2d3d275edf8204495de7a77c61 100644 (file)
@@ -1,3 +1,9 @@
+2008-03-02  Roei Erez  <roeie@mainsoft.com>
+
+       * DateTime.cs: Improve the patch supplied by James Purcell to be
+         dotnet-compatible, and add support for RoundTripKind parsing. 
+         Fixed reopened bug #352210.
+
 
 Tue Feb 26 17:50:17 CET 2008 Paolo Molaro <lupus@ximian.com>
 
index d78746efb606652b6465406d7ef9b1576997b87d..768ee3b1751b01e306e186261efef0bba232f4df 100644 (file)
@@ -1546,8 +1546,7 @@ namespace System
                                case 'K':
                                        if (s [valuePos] == 'Z') {
                                                valuePos++;
-                                               useutc = true;
-                                               style |= DateTimeStyles.AdjustToUniversal;
+                                               useutc = true;                                          
                                        }
                                        else if (s [valuePos] == '+' || s [valuePos] == '-') {
                                                if (tzsign != -1)
@@ -1733,6 +1732,8 @@ namespace System
                        bool kind_specified = true;
                        TimeSpan utcoffset;
 
+                       bool adjustToUniversal = (style & DateTimeStyles.AdjustToUniversal) != 0;
+                       
                        if (tzsign != -1) {
                                if (tzoffmin == -1)
                                        tzoffmin = 0;
@@ -1742,41 +1743,34 @@ namespace System
                                        tzoffset = -tzoffset;
 
                                utcoffset = new TimeSpan (tzoffset, tzoffmin, 0);
-                       }
+                               long newticks = (result.ticks - utcoffset).Ticks;
+                               if (newticks < 0)
+                                       newticks += TimeSpan.TicksPerDay;
+                               result = new DateTime (false, new TimeSpan (newticks));
 #if NET_2_0
-                       else if (useutc || ((style & DateTimeStyles.AssumeUniversal) != 0))
-#else
-                       else if (useutc)
-#endif
-                               utcoffset = new TimeSpan (0, 0, 0);
-                       else {
-                               // If no timezone was specified, default to the local timezone.
-                               TimeZone tz = TimeZone.CurrentTimeZone;
-                               utcoffset = tz.GetUtcOffset (result);
-
-#if NET_2_0
-                               if ((style & DateTimeStyles.AssumeLocal) == 0)
+                               result.kind = DateTimeKind.Utc;
+                               if ((style & DateTimeStyles.RoundtripKind) != 0)
+                                       result = result.ToLocalTime ();
 #endif
-                                       kind_specified = false;
                        }
-
-                       long newticks = (result.ticks - utcoffset).Ticks;
-
-                       result = new DateTime (false, new TimeSpan (newticks));
-
-                       if (kind_specified && ((style & DateTimeStyles.AdjustToUniversal) != 0)) {
-#if NET_2_0
+#if NET_2_0                                                    
+                       else if (useutc || ((style & DateTimeStyles.AssumeUniversal) != 0))
                                result.kind = DateTimeKind.Utc;
-#endif
+                       else if ((style & DateTimeStyles.AssumeLocal) != 0)
+                               result.kind = DateTimeKind.Local;                                               
+
+                       bool adjustToLocal = !adjustToUniversal && (style & DateTimeStyles.RoundtripKind) == 0;
+                       if (result.kind != DateTimeKind.Unspecified)
+                       {                               
+                               if (adjustToUniversal)
+                                       result = result.ToUniversalTime ();
+                               else if (adjustToLocal)
+                                       result = result.ToLocalTime ();
                        }
-                       else {
+#else
+                       if (!adjustToUniversal && (useutc || tzsign != -1))
                                result = result.ToLocalTime ();
-#if NET_2_0
-                               if (!kind_specified)
-                                       result.kind = DateTimeKind.Unspecified;
 #endif
-                       }
-
                        return true;
                }
 
@@ -1797,7 +1791,9 @@ namespace System
                                                   DateTimeStyles style)
                {
                        DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (fp);
-
+#if NET_2_0
+                       CheckStyle (style);
+#endif
                        if (s == null)
                                throw new ArgumentNullException ("s");
                        if (formats == null)
@@ -1810,9 +1806,21 @@ namespace System
                        if (!ParseExact (s, formats, dfi, style, out result, true, ref longYear))
                                throw new FormatException ();
                        return result;
-               }
+               }               
 
 #if NET_2_0
+               private static void CheckStyle (DateTimeStyles style)
+               {
+                       if ( (style & DateTimeStyles.RoundtripKind) != 0)
+                       {
+                               if ((style & DateTimeStyles.AdjustToUniversal) != 0 || (style & DateTimeStyles.AssumeLocal) != 0 ||
+                                        (style & DateTimeStyles.AssumeUniversal) != 0)
+                                       throw new ArgumentException ("The DateTimeStyles value RoundtripKind cannot be used with the values AssumeLocal, Asersal or AdjustToUniversal.", "style");
+                       }
+                       if ((style & DateTimeStyles.AssumeUniversal) != 0 && (style & DateTimeStyles.AssumeLocal) != 0)                 
+                               throw new ArgumentException ("The DateTimeStyles values AssumeLocal and AssumeUniversal cannot be used together.", "style");
+               }
+
                public static bool TryParse (string s, out DateTime result)
                {
                        try {
index 3e6d7768a0908e7b1e8d266c8964affc5d9cba23..b523ae8b3ca6c897af057516bbea43e643e4713c 100644 (file)
@@ -1,3 +1,7 @@
+2008-03-02  Roei Erez  <roeie@mainsoft.com>
+
+       * DateTimeTest.cs : add test cases for  Bug3522210.
+
 2008-02-26  Ivan N. Zlatev  <contact@i-nz.net>
 
        * AttributeTest.cs: Remove NotWorking as we pass those tests now.
index c19476099af78693c5131f06f2090ae586d1b56e..25bcec3026d7dbb57c89b54f5eee8c60a2e3fa0a 100644 (file)
@@ -2261,6 +2261,105 @@ namespace MonoTests.System
                        Assert.AreEqual (dt.Ticks, d1.Ticks, "#3");
                        Assert.AreEqual (DateTimeKind.Unspecified, d1.Kind, "#4");
                }
+
+               [Test]
+               public void TestRoundTrip () {
+                       DateTime result;
+                       DateTimeStyles roundTripStyle = DateTimeStyles.RoundtripKind;
+                       string utcDate = "2008-02-21T11:14:18.2721262Z";
+                       string localDate = "2008-02-21T11:14:18.2721262+02:00";
+                       string unspec = "2008-02-21T11:14:18.2721262";
+                       String [] formats = {"yyyy-MM-ddTHH:mm:ssK", "yyyy-MM-ddTHH:mm:ss.FFFFFFFK"};
+
+                       result = DateTime.ParseExact (localDate, formats, CultureInfo.InvariantCulture, roundTripStyle);
+                       Assert.AreEqual (result.Kind, DateTimeKind.Local);
+                       Assert.AreEqual (result.ToUniversalTime ().Ticks, 633391820582721262);
+                       
+                       result = DateTime.ParseExact (unspec, formats, CultureInfo.InvariantCulture, roundTripStyle);
+                       Assert.AreEqual (result.Kind, DateTimeKind.Unspecified);
+                       Assert.AreEqual (result.Ticks, 633391892582721262);
+                       
+                       result = DateTime.ParseExact (utcDate, formats, CultureInfo.InvariantCulture, roundTripStyle);
+                       Assert.AreEqual (result.Kind, DateTimeKind.Utc);
+                       Assert.AreEqual (result.Ticks, 633391892582721262);
+
+               }               
+
+               [Test]
+               public void TestRegularStyle () {
+                       DateTime result;
+                       DateTimeStyles style = DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite;
+                       string utcDate = "2008-02-21T11:14:18.2721262Z";
+                       string localDate = "2008-02-21T11:14:18.2721262+02:00";
+                       string unspec = "2008-02-21T11:14:18.2721262";
+                       String [] formats = {"yyyy-MM-ddTHH:mm:ssK", "yyyy-MM-ddTHH:mm:ss.FFFFFFFK"};
+
+                       result = DateTime.ParseExact (localDate, formats, CultureInfo.InvariantCulture, style);
+                       Assert.AreEqual (result.Kind, DateTimeKind.Local);
+                       Assert.AreEqual (result.ToUniversalTime ().Ticks, 633391820582721262);
+
+                       result = DateTime.ParseExact (unspec, formats, CultureInfo.InvariantCulture, style);
+                       Assert.AreEqual (result.Kind, DateTimeKind.Unspecified);                        
+                       Assert.AreEqual (result.Ticks, 633391892582721262);
+
+                       result = DateTime.ParseExact (utcDate, formats, CultureInfo.InvariantCulture, style);
+                       Assert.AreEqual (result.Kind, DateTimeKind.Local);
+                       Assert.AreEqual (result.ToUniversalTime ().Ticks, 633391892582721262);
+               }
+
+               [Test]
+               public void TestAssumeLocal () {
+                       DateTime result;
+                       DateTimeStyles assumeLocal =  DateTimeStyles.AssumeLocal;
+                       string utcDate = "2008-02-21T11:14:18.2721262Z";
+                       string localDate = "2008-02-21T11:14:18.2721262+02:00";
+                       string unspec = "2008-02-21T11:14:18.2721262";
+                       String [] formats = {"yyyy-MM-ddTHH:mm:ssK", "yyyy-MM-ddTHH:mm:ss.FFFFFFFK"};
+
+                       result = DateTime.ParseExact (localDate, formats, CultureInfo.InvariantCulture, assumeLocal);
+                       Assert.AreEqual (result.Kind, DateTimeKind.Local);
+                       Assert.AreEqual (result.ToUniversalTime ().Ticks, 633391820582721262);
+
+                       result = DateTime.ParseExact (unspec, formats, CultureInfo.InvariantCulture, assumeLocal);
+                       Assert.AreEqual (result.Kind, DateTimeKind.Local);
+                       Assert.AreEqual (result.Ticks, 633391892582721262);
+
+                       result = DateTime.ParseExact (utcDate, formats, CultureInfo.InvariantCulture, assumeLocal);
+                       Assert.AreEqual (result.Kind, DateTimeKind.Local);
+                       Assert.AreEqual (result.ToUniversalTime ().Ticks, 633391892582721262);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void IllegalStyleCombination1()
+               {
+                       DateTimeStyles illegal = DateTimeStyles.RoundtripKind | DateTimeStyles.AssumeLocal;
+                       DateTime.ParseExact ("", "", null, illegal);                    
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void IllegalStyleCombination2()
+               {
+                       DateTimeStyles illegal = DateTimeStyles.RoundtripKind | DateTimeStyles.AdjustToUniversal;
+                       DateTime.ParseExact ("", "", null, illegal);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void IllegalStyleCombination3()
+               {
+                       DateTimeStyles illegal = DateTimeStyles.RoundtripKind | DateTimeStyles.AssumeUniversal;
+                       DateTime.ParseExact ("", "", null, illegal);
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void IllegalStyleCombination4()
+               {
+                       DateTimeStyles illegal = DateTimeStyles.AssumeLocal | DateTimeStyles.AssumeUniversal;
+                       DateTime.ParseExact ("", "", null, illegal);
+               }
 #endif
        }
 }