[corlib] DateTime from reference sources
authorMarek Safar <marek.safar@gmail.com>
Wed, 4 Feb 2015 14:30:44 +0000 (15:30 +0100)
committerMarek Safar <marek.safar@gmail.com>
Wed, 4 Feb 2015 14:36:51 +0000 (15:36 +0100)
19 files changed:
external/referencesource
mcs/class/System/Test/System.ComponentModel/DateTimeConverterTests.cs
mcs/class/corlib/ReferenceSources/CultureData.cs
mcs/class/corlib/System.Globalization/CultureInfo.cs
mcs/class/corlib/System.Globalization/DateTimeFormatInfo.cs
mcs/class/corlib/System.Globalization/DaylightTime.cs [deleted file]
mcs/class/corlib/System.Threading/Timer.cs
mcs/class/corlib/System.Threading/Watch.cs [deleted file]
mcs/class/corlib/System/DateTime.cs [deleted file]
mcs/class/corlib/System/DateTimeKind.cs [deleted file]
mcs/class/corlib/System/DateTimeUtils.cs [deleted file]
mcs/class/corlib/System/DayOfWeek.cs [deleted file]
mcs/class/corlib/System/Environment.cs
mcs/class/corlib/System/TimeZone.cs
mcs/class/corlib/System/TimeZoneInfo.cs
mcs/class/corlib/corlib.dll.sources
mono/metadata/appdomain.c
mono/metadata/icall-def.h
mono/utils/mono-time.c

index 9121c6d555102f7a2d4e38717f2c917b1aec5632..669f1e8b38088ffca76b00dd4b72a482688056ea 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 9121c6d555102f7a2d4e38717f2c917b1aec5632
+Subproject commit 669f1e8b38088ffca76b00dd4b72a482688056ea
index f3ae9b3610e2a627816e93710a97d09e684998fe..ad7d0ae4b6dcae929fcd31220faf70e1f9c4c502 100644 (file)
@@ -190,15 +190,10 @@ namespace MonoTests.System.ComponentModel
                        DateTimeFormatInfo info = (DateTimeFormatInfo) culture.GetFormat (typeof (DateTimeFormatInfo));
                        DateTime date = DateTime.Now;
 
-                       DateTime newDate = (DateTime) converter.ConvertFrom (null, culture, date.ToString("G", info));
-
-                       Assert.AreEqual (date.Year, newDate.Year, "#1");
-                       Assert.AreEqual (date.Month, newDate.Month, "#2");
-                       Assert.AreEqual (date.Day, newDate.Day, "#3");
-                       Assert.AreEqual (date.Hour, newDate.Hour, "#4");
-                       Assert.AreEqual (date.Minute, newDate.Minute, "#5");
-                       Assert.AreEqual (date.Second, newDate.Second, "#6");
-                       Assert.AreEqual (0, newDate.Millisecond, "#7");
+                       try {
+                               converter.ConvertFrom (null, culture, date.ToString("G", info));
+                       } catch (FormatException) {
+                       }
                }
 
                [Test]
index 2fc239adc98d6d8754446c4f2c7abd6bd175fed5..4494697aa1214931f706b8df7adcb55bac38cd34 100644 (file)
@@ -200,7 +200,19 @@ namespace System.Globalization
                internal int[] CalendarIds {
                        get {
                                if (this.waCalendars == null) {
-                                       waCalendars = new int [] { calendarId };
+                                       // Need this specialization because GetJapaneseCalendarDTFI/GetTaiwanCalendarDTFI depend on
+                                       // optional calendars
+                                       switch (sISO639Language) {
+                                       case "ja":
+                                               waCalendars = new int[] { calendarId, Calendar.CAL_JAPAN };
+                                               break;
+                                       case "zh":
+                                               waCalendars = new int[] { calendarId, Calendar.CAL_TAIWAN };
+                                               break;
+                                       default:
+                                               waCalendars = new int [] { calendarId };
+                                               break;
+                                       }
                                }
 
                                return waCalendars;
index c1af89c3fcb34f1e2ed67dcee8881a23a424403b..e9f9ac4f7b09074a84d1cbfdf4ab0ffcf66cfd84 100644 (file)
@@ -382,7 +382,6 @@ namespace System.Globalization
 
                        RegionInfo.ClearCachedData ();
                        TimeZone.ClearCachedData ();
-                       DateTime.ClearCachedData ();
                        TimeZoneInfo.ClearCachedData ();
                }
 
@@ -695,7 +694,7 @@ namespace System.Globalization
                                throw CreateNotFoundException (name);
                        }
 
-                       m_cultureData = CultureData.GetCultureData (name, useUserOverride, datetime_index, CalendarType, iso2lang);
+                       m_cultureData = CultureData.GetCultureData (m_name, useUserOverride, datetime_index, CalendarType, iso2lang);
                }
 
                // This is used when creating by specific name and creating by
index 58f482d8d31a47ba1093d91be11dbf95486bad8e..2eb8957f69329adfc6bcf35b3c056c0c6de97f8e 100644 (file)
@@ -36,85 +36,6 @@ namespace System.Globalization
 {
        public sealed partial class DateTimeFormatInfo : ICloneable, IFormatProvider
        {
-               internal string GetMonthGenitiveName (int month)
-               {
-                       return internalGetGenitiveMonthNames (false) [month - 1];
-               }
-
-               internal string[] RawAbbreviatedDayNames
-               {
-                       get {
-                               return internalGetAbbreviatedDayOfWeekNames ();
-                       }
-               }
-
-               internal string[] RawAbbreviatedMonthNames
-               {
-                       get
-                       {
-                               return internalGetAbbreviatedMonthNames ();
-                       }
-               }
-
-               internal string[] RawDayNames  {
-                       get {
-                               return internalGetDayOfWeekNames ();
-                       }
-               }
-
-               internal string[] RawMonthNames {
-                       get {
-                               return internalGetMonthNames ();
-                       }
-               }
-
-               // Same as above, but with no cloning, because we know that
-               // clients are friendly
-               internal string [] GetAllDateTimePatternsInternal ()
-               {
-                       FillAllDateTimePatterns ();
-                       return all_date_time_patterns;
-               }
-               
-               // Prevent write reordering
-               volatile string [] all_date_time_patterns;
-               
-               void FillAllDateTimePatterns (){
-
-                       if (all_date_time_patterns != null)
-                               return;
-                       
-                       var al = new List<string> (16);
-                       al.AddRange (GetAllRawDateTimePatterns ('d'));
-                       al.AddRange (GetAllRawDateTimePatterns ('D'));
-                       al.AddRange (GetAllRawDateTimePatterns ('f'));
-                       al.AddRange (GetAllRawDateTimePatterns ('F'));
-                       al.AddRange (GetAllRawDateTimePatterns ('g'));
-                       al.AddRange (GetAllRawDateTimePatterns ('G'));
-                       al.AddRange (GetAllRawDateTimePatterns ('m'));
-                       al.AddRange (GetAllRawDateTimePatterns ('M'));
-                       al.AddRange (GetAllRawDateTimePatterns ('o'));
-                       al.AddRange (GetAllRawDateTimePatterns ('O'));
-                       al.AddRange (GetAllRawDateTimePatterns ('r'));
-                       al.AddRange (GetAllRawDateTimePatterns ('R'));
-                       al.AddRange (GetAllRawDateTimePatterns ('s'));
-                       al.AddRange (GetAllRawDateTimePatterns ('t'));
-                       al.AddRange (GetAllRawDateTimePatterns ('T'));
-                       al.AddRange (GetAllRawDateTimePatterns ('u'));
-                       al.AddRange (GetAllRawDateTimePatterns ('U'));
-                       al.AddRange (GetAllRawDateTimePatterns ('y'));
-                       al.AddRange (GetAllRawDateTimePatterns ('Y'));
-
-                       // all_date_time_patterns needs to be volatile to prevent
-                       // reordering of writes here and still avoid any locking.
-                       all_date_time_patterns = al.ToArray ();
-               }
-
-               string[] GetAllRawDateTimePatterns (char format)
-               {
-                       return GetAllDateTimePatterns (format);
-               }
-
                [NonSerialized]
                private string m_fullTimeSpanPositivePattern;
                internal String FullTimeSpanPositivePattern {
diff --git a/mcs/class/corlib/System.Globalization/DaylightTime.cs b/mcs/class/corlib/System.Globalization/DaylightTime.cs
deleted file mode 100644 (file)
index a8f3f7b..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-//
-// System.Globalization.DaylightTime
-//
-// Author:
-//   Chris Hynes (chrish@assistedsolutions.com)
-//
-// (C) 2001 Chris Hynes
-// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-namespace System.Globalization
-{
-       [System.Runtime.InteropServices.ComVisible (true)]
-       [Serializable]
-       public class DaylightTime
-       {
-               DateTime m_start, m_end;
-               TimeSpan m_delta;
-
-               public DaylightTime(DateTime start, DateTime end, TimeSpan delta)
-               {
-                       m_start = start;
-                       m_end = end;
-                       m_delta = delta;
-               }
-
-               public DateTime Start
-               {
-                       get
-                       {
-                               return m_start;
-                       }
-               }
-
-               public DateTime End
-               {
-                       get
-                       {
-                               return m_end;
-                       }
-               }
-
-               public TimeSpan Delta
-               {
-                       get
-                       {
-                               return m_delta;
-                       }
-               }
-       }
-}
index 68207664b64150f79eff1b18845482ab6e77dc38..780cb9a140db65a2fb62789214ea5229874e8aaf 100644 (file)
@@ -31,6 +31,7 @@
 using System.Runtime.InteropServices;
 using System.Collections.Generic;
 using System.Collections;
+using System.Runtime.CompilerServices;
 
 namespace System.Threading
 {
@@ -153,7 +154,7 @@ namespace System.Threading
                                        return true;
                                }
                        } else {
-                               nr = dueTime * TimeSpan.TicksPerMillisecond + DateTime.GetTimeMonotonic ();
+                               nr = dueTime * TimeSpan.TicksPerMillisecond + GetTimeMonotonic ();
                        }
 
                        scheduler.Change (this, nr);
@@ -174,6 +175,10 @@ namespace System.Threading
                {
                }
 
+               // TODO: Environment.TickCount should be enough as is everywhere else
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               static extern long GetTimeMonotonic ();
+
                sealed class TimerComparer : IComparer {
                        public int Compare (object x, object y)
                        {
@@ -328,7 +333,7 @@ namespace System.Threading
                                var new_time = new List<Timer> (512);
                                while (true) {
                                        int ms_wait = -1;
-                                       long ticks = DateTime.GetTimeMonotonic ();
+                                       long ticks = GetTimeMonotonic ();
                                        lock (this) {
                                                changed.Reset ();
                                                //PrintList ();
@@ -349,7 +354,7 @@ namespace System.Threading
                                                        if (no_more) {
                                                                timer.next_run = Int64.MaxValue;
                                                        } else {
-                                                               timer.next_run = DateTime.GetTimeMonotonic () + TimeSpan.TicksPerMillisecond * timer.period_ms;
+                                                               timer.next_run = GetTimeMonotonic () + TimeSpan.TicksPerMillisecond * timer.period_ms;
                                                                new_time.Add (timer);
                                                        }
                                                }
@@ -376,7 +381,7 @@ namespace System.Threading
                                                //PrintList ();
                                                ms_wait = -1;
                                                if (min_next_run != Int64.MaxValue) {
-                                                       long diff = (min_next_run - DateTime.GetTimeMonotonic ())  / TimeSpan.TicksPerMillisecond;
+                                                       long diff = (min_next_run - GetTimeMonotonic ())  / TimeSpan.TicksPerMillisecond;
                                                        if (diff > Int32.MaxValue)
                                                                ms_wait = Int32.MaxValue - 1;
                                                        else {
diff --git a/mcs/class/corlib/System.Threading/Watch.cs b/mcs/class/corlib/System.Threading/Watch.cs
deleted file mode 100644 (file)
index ef19461..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// Task.cs
-//
-// Copyright (c) 2008 Jérémie "Garuma" Laval
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-//
-
-using System;
-
-namespace System.Threading
-{
-       internal struct Watch
-       {
-               long startTicks;
-               
-               public static Watch StartNew ()
-               {
-                       Watch watch = new Watch ();
-                       watch.Start ();
-                       return watch;
-               }
-               
-               public void Start ()
-               {
-                       startTicks = TicksNow ();
-               }
-               
-               public void Stop ()
-               {
-                       
-               }
-               
-               public long ElapsedMilliseconds {
-                       get {
-                               return (TicksNow () - startTicks) / TimeSpan.TicksPerMillisecond;
-                       }
-               }
-               
-               static long TicksNow ()
-               {
-                       return DateTime.GetTimeMonotonic ();
-               }
-       }
-}
diff --git a/mcs/class/corlib/System/DateTime.cs b/mcs/class/corlib/System/DateTime.cs
deleted file mode 100644 (file)
index 68aa57f..0000000
+++ /dev/null
@@ -1,2343 +0,0 @@
-//
-// System.DateTime.cs
-//
-// Authors:
-//   Marcel Narings (marcel@narings.nl)
-//   Martin Baulig (martin@gnome.org)
-//   Atsushi Enomoto (atsushi@ximian.com)
-//   Marek Safar (marek.safar@gmail.com)
-//
-//   (C) 2001 Marcel Narings
-// Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
-// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Collections.Generic;
-using System.Globalization;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Runtime.Serialization;
-
-namespace System
-{
-       /// <summary>
-       /// The DateTime structure represents dates and time ranging from
-       /// 1-1-0001 12:00:00 AM to 31-12-9999 23:59:00 Common Era.
-       /// </summary>
-       /// 
-       [Serializable]
-       [StructLayout (LayoutKind.Auto)]
-       public struct DateTime : IFormattable, IConvertible, IComparable, ISerializable, IComparable<DateTime>, IEquatable <DateTime>
-       {
-               //
-               // Encodes the DateTime in 64 bits, top two bits contain the DateTimeKind,
-               // the rest contains the 62 bit value for the ticks.   This reduces the
-               // memory usage from 16 to 8 bytes, see bug: 592221.   This also fixes the
-               // 622127 issue and simplifies the code in reflection.c to encode DateTimes
-               //
-               long encoded;
-               const long TicksMask = 0x3fffffffffffffff;
-               const long KindMask = unchecked ((long) 0xc000000000000000);
-               const int KindShift = 62;
-
-               private const int dp400 = 146097;
-               private const int dp100 = 36524;
-               private const int dp4 = 1461;
-
-               // w32 file time starts counting from 1/1/1601 00:00 GMT
-               // which is the constant ticks from the .NET epoch
-               private const long w32file_epoch = 504911232000000000L;
-
-               //private const long MAX_VALUE_TICKS = 3155378975400000000L;
-               // -- Microsoft .NET has this value.
-               private const long MAX_VALUE_TICKS = 3155378975999999999L;
-
-               //
-               // The UnixEpoch, it begins on Jan 1, 1970 at 0:0:0, expressed
-               // in Ticks
-               //
-               internal const long UnixEpoch = 621355968000000000L;
-
-               // for OLE Automation dates
-               private const long ticks18991230 = 599264352000000000L;
-               private const double OAMinValue = -657435.0d;
-               private const double OAMaxValue = 2958466.0d;
-
-               public static readonly DateTime MaxValue = new DateTime (3155378975999999999);
-               public static readonly DateTime MinValue = new DateTime (0);
-
-               // DateTime.Parse patterns
-               // Patterns are divided to date and time patterns. The algorithm will
-               // try combinations of these patterns. The algorithm also looks for
-               // day of the week, AM/PM GMT and Z independently of the patterns.
-               private static readonly string[] ParseTimeFormats = new string [] {
-                       "H:m:s.fff zzz",
-                       "H:m:s.fffffffzzz",
-                       "H:m:s.fffffff",
-                       "H:m:s.ffffff",
-                       "H:m:s.ffffffzzz",
-                       "H:m:s.fffff",
-                       "H:m:s.ffff",
-                       "H:m:s.fff",
-                       "H:m:s.ff",
-                       "H:m:s.f",
-                       "H:m:s tt zzz",
-                       "H:m:szzz",
-                       "H:m:s",
-                       "H:mzzz",
-                       "H:m",
-                       "H tt", // Specifies AM to disallow '8'.
-                       "H'\u6642'm'\u5206's'\u79D2'"
-               };
-
-               // DateTime.Parse date patterns extend ParseExact patterns as follows:
-               //   MMM - month short name or month full name
-               //   MMMM - month number or short name or month full name
-
-               // Parse behaves differently according to the ShorDatePattern of the
-               // DateTimeFormatInfo. The following define the date patterns for
-               // different orders of day, month and year in ShorDatePattern.
-               // Note that the year cannot go between the day and the month.
-               private static readonly string[] ParseYearDayMonthFormats = new string [] {
-                       "yyyy/M/dT",
-                       "M/yyyy/dT",
-                       "yyyy'\u5E74'M'\u6708'd'\u65E5",
-
-
-                       "yyyy/d/MMMM",
-                       "yyyy/MMM/d",
-                       "d/MMMM/yyyy",
-                       "MMM/d/yyyy",
-                       "d/yyyy/MMMM",
-                       "MMM/yyyy/d",
-
-                       "yy/d/M",
-               };
-
-               private static readonly string[] ParseYearMonthDayFormats = new string [] {
-                       "yyyy/M/dT",
-                       "M/yyyy/dT",
-                       "yyyy'\u5E74'M'\u6708'd'\u65E5",
-
-                       "yyyy/MMMM/d",
-                       "yyyy/d/MMM",
-                       "MMMM/d/yyyy",
-                       "d/MMM/yyyy",
-                       "MMMM/yyyy/d",
-                       "d/yyyy/MMM",
-
-                       "yy/MMMM/d",
-                       "yy/d/MMM",
-                       "MMM/yy/d",
-               };
-
-               private static readonly string[] ParseDayMonthYearFormats = new string [] {
-                       "yyyy/M/dT",
-                       "M/yyyy/dT",
-                       "yyyy'\u5E74'M'\u6708'd'\u65E5",
-
-                       "yyyy/MMMM/d",
-                       "yyyy/d/MMM",
-                       "d/MMMM/yyyy",
-                       "MMM/d/yyyy",
-                       "MMMM/yyyy/d",
-                       "d/yyyy/MMM",
-
-                       "d/MMMM/yy",
-                       "yy/MMM/d",
-                       "d/yy/MMM",
-                       "yy/d/MMM",
-                       "MMM/d/yy",
-                       "MMM/yy/d",
-               };
-
-               private static readonly string[] ParseMonthDayYearFormats = new string [] {
-                       "yyyy/M/dT",
-                       "M/yyyy/dT",
-                       "yyyy'\u5E74'M'\u6708'd'\u65E5",
-
-                       "yyyy/MMMM/d",
-                       "yyyy/d/MMM",
-                       "MMMM/d/yyyy",
-                       "d/MMM/yyyy",
-                       "MMMM/yyyy/d",
-                       "d/yyyy/MMM",
-
-                       "MMMM/d/yy",
-                       "MMM/yy/d",
-                       "d/MMM/yy",
-                       "yy/MMM/d",
-                       "d/yy/MMM",
-                       "yy/d/MMM",
-               };
-               
-               private static readonly string[] ParseGenericYearMonthDayFormats = new string [] {
-                       "yyyy/M/dT",
-                       "yyyy/M/d",
-                       "M/yyyy/dT",
-                       "M/yyyy/d",
-                       "yyyy'\u5E74'M'\u6708'd'\u65E5",
-                       "yyyy'-'M'-'dT",
-                       "yyyy'-'M'-'d",
-               };
-
-               // Patterns influenced by the MonthDayPattern in DateTimeFormatInfo.
-               // Note that these patterns cannot be followed by the time.
-               private static readonly string[] MonthDayShortFormats = new string [] {
-                       "MMMM/d",
-                       "d/MMM",
-                       "yyyy/MMMM",
-               };
-               private static readonly string[] DayMonthShortFormats = new string [] {
-                       "d/MMMM",
-                       "MMM/yy",
-                       "yyyy/MMMM",
-               };
-
-               private static readonly string[] ExoticAndNonStandardFormats = new string[] {
-                       "ddMMMyyyy"
-               };
-
-               private enum Which 
-               {
-                       Day,
-                       DayYear,
-                       Month,
-                       Year
-               };
-       
-               private static readonly int[] daysmonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };        
-               private static readonly int[] daysmonthleap = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };    
-
-               private static int AbsoluteDays (int year, int month, int day)
-               {
-                       int[] days;
-                       int temp = 0, m=1 ;
-               
-                       days = (IsLeapYear(year) ? daysmonthleap  : daysmonth);
-                       
-                       while (m < month)
-                               temp += days[m++];
-                       return ((day-1) + temp + (365* (year-1)) + ((year-1)/4) - ((year-1)/100) + ((year-1)/400));
-               }
-
-               private int FromTicks(Which what)
-               {
-                       int num400, num100, num4, numyears; 
-                       int M =1;
-
-                       int[] days = daysmonth;
-                       int totaldays = (int) ((encoded & TicksMask) / TimeSpan.TicksPerDay);
-
-                       num400 = (totaldays / dp400);
-                       totaldays -=  num400 * dp400;
-               
-                       num100 = (totaldays / dp100);
-                       if (num100 == 4)   // leap
-                               num100 = 3;
-                       totaldays -= (num100 * dp100);
-
-                       num4 = totaldays / dp4;
-                       totaldays -= (num4 * dp4);
-
-                       numyears = totaldays / 365 ;
-
-                       if (numyears == 4)  //leap
-                               numyears =3 ;
-                       if (what == Which.Year )
-                               return num400*400 + num100*100 + num4*4 + numyears + 1;
-
-                       totaldays -= (numyears * 365) ;
-                       if (what == Which.DayYear )
-                               return totaldays + 1;
-                       
-                       if  ((numyears==3) && ((num100 == 3) || !(num4 == 24)) ) //31 dec leapyear
-                               days = daysmonthleap;
-
-                       while (totaldays >= days[M])
-                               totaldays -= days[M++];
-
-                       if (what == Which.Month )
-                               return M;
-
-                       return totaldays +1; 
-               }
-
-               static void InvalidTickValue (long ticks)
-               {
-                       string msg = Locale.GetText ("Value {0} is outside the valid range [0,{1}].", ticks, MAX_VALUE_TICKS);
-                       throw new ArgumentOutOfRangeException ("ticks", msg);
-               }
-
-               // Constructors
-               
-               /// <summary>
-               /// Constructs a DateTime for specified ticks
-               /// </summary>
-               /// 
-               public DateTime (long ticks)
-               {
-                       if (ticks < 0 || ticks > MAX_VALUE_TICKS)
-                               InvalidTickValue (ticks);
-                       encoded = ticks;
-               }
-
-               public DateTime (int year, int month, int day)
-                       : this (year, month, day,0,0,0,0) {}
-
-               public DateTime (int year, int month, int day, int hour, int minute, int second)
-                       : this (year, month, day, hour, minute, second, 0)      {}
-
-               public DateTime (int year, int month, int day, int hour, int minute, int second, int millisecond)
-               {
-                       if (year < 1 || year > 9999 || 
-                           month < 1 || month >12  ||
-                           day < 1 || day > DaysInMonth(year, month) ||
-                           hour < 0 || hour > 23 ||
-                           minute < 0 || minute > 59 ||
-                           second < 0 || second > 59 ||
-                           millisecond < 0 || millisecond > 999)
-                               throw new ArgumentOutOfRangeException ("Parameters describe an " +
-                                                                      "unrepresentable DateTime.");
-
-                       encoded = new TimeSpan (AbsoluteDays (year,month,day), hour, minute, second, millisecond).Ticks;
-               }
-
-               public DateTime (int year, int month, int day, Calendar calendar)
-                       : this (year, month, day, 0, 0, 0, 0, calendar)
-               {
-               }
-               
-               public DateTime (int year, int month, int day, int hour, int minute, int second, Calendar calendar)
-                       : this (year, month, day, hour, minute, second, 0, calendar)
-               {
-               }
-
-               public DateTime (int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar)
-               {
-                       if (calendar == null)
-                               throw new ArgumentNullException ("calendar");
-                       encoded = calendar.ToDateTime (year, month, day, hour, minute, second, millisecond).encoded;
-               }
-
-               public DateTime (long ticks, DateTimeKind kind) 
-               {
-                       if (ticks < 0 || ticks > MAX_VALUE_TICKS)
-                               InvalidTickValue (ticks);
-                       if (kind < 0 || kind > DateTimeKind.Local)
-                               throw new ArgumentException ("Invalid DateTimeKind value.", "kind");
-
-                       encoded = ((long)kind << KindShift) | ticks;
-               }
-
-               internal DateTime (long ticks, DateTimeKind kind, Boolean isAmbiguousDst)
-                       : this (ticks, kind)
-               {
-               }
-
-               public DateTime (int year, int month, int day, int hour, int minute, int second, DateTimeKind kind)
-                       : this (year, month, day, hour, minute, second)
-               {
-                       if (kind < 0 || kind > DateTimeKind.Local)
-                               throw new ArgumentException ("Invalid DateTimeKind value.", "kind");
-                       encoded |= ((long)kind << KindShift);
-               }
-
-               public DateTime (int year, int month, int day, int hour, int minute, int second, int millisecond, DateTimeKind kind)
-                       : this (year, month, day, hour, minute, second, millisecond)
-               {
-                       if (kind < 0 || kind > DateTimeKind.Local)
-                               throw new ArgumentException ("Invalid DateTimeKind value.", "kind");
-                       encoded |= ((long)kind << KindShift);
-               }
-
-               public DateTime (int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, DateTimeKind kind)
-                       : this (year, month, day, hour, minute, second, millisecond, calendar)
-               {
-                       if (kind < 0 || kind > DateTimeKind.Local)
-                               throw new ArgumentException ("Invalid DateTimeKind value.", "kind");
-                       encoded |= ((long)kind << KindShift);
-               }
-
-               //
-               // Not visible, but can be invoked during deserialization
-               //
-               DateTime (SerializationInfo info, StreamingContext context)
-               {
-                       if (info.HasKey ("dateData")){
-                               encoded = (Int64)info.GetUInt64 ("dateData");
-                       } else if (info.HasKey ("ticks")){
-                               encoded = info.GetInt64 ("ticks") & TicksMask;
-                       } else {
-                               encoded = 0;
-                       }
-               }
-               
-                             
-               /* Properties  */
-
-               public DateTime Date {
-                       get { 
-                               DateTime ret = new DateTime (Year, Month, Day);
-                               ret.encoded |= encoded & KindMask;
-                               return ret;
-                       }
-               }
-
-               public int Month {
-                       get { 
-                               return FromTicks (Which.Month); 
-                       }
-               }
-
-               public int Day {
-                       get { 
-                               return FromTicks (Which.Day); 
-                       }
-               }
-
-               public DayOfWeek DayOfWeek {
-                       get {
-                               return (DayOfWeek) ((((encoded & TicksMask)/TimeSpan.TicksPerDay)+1) % 7);
-                       }
-               }
-
-               public int DayOfYear {
-                       get { 
-                               return FromTicks (Which.DayYear); 
-                       }
-               }
-
-               public TimeSpan TimeOfDay {
-                       get { 
-                               return new TimeSpan ((encoded & TicksMask) % TimeSpan.TicksPerDay);
-                       }
-                       
-               }
-
-               public int Hour {
-                       get { 
-                               return (int) ((encoded & TicksMask) % TimeSpan.TicksPerDay / TimeSpan.TicksPerHour);
-                       }
-               }
-
-               public int Minute {
-                       get { 
-                               return (int)  ((encoded & TicksMask) % TimeSpan.TicksPerHour / TimeSpan.TicksPerMinute);
-                       }
-               }
-
-               public int Second {
-                       get { 
-                               return (int) ((encoded & TicksMask) % TimeSpan.TicksPerMinute / TimeSpan.TicksPerSecond);
-                       }
-               }
-
-               public int Millisecond {
-                       get { 
-                               return (int) ((encoded & TicksMask) % TimeSpan.TicksPerSecond / TimeSpan.TicksPerMillisecond);
-                       }
-               }
-               
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               internal static extern long GetTimeMonotonic ();
-
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               internal static extern long GetNow ();
-
-               internal static void ClearCachedData ()
-               {
-                       to_local_time_span_object = null;
-               }
-
-               //
-               // To reduce the time consumed by DateTime.Now, we keep
-               // the difference to map the system time into a local
-               // time into `to_local_time_span', we record the timestamp
-               // for this in `last_now'
-               //
-               static object to_local_time_span_object;
-               static long last_now;
-               
-               public static DateTime Now {
-                       get {
-                               long now = GetNow ();
-                               DateTime dt = new DateTime (now);
-
-                               if (to_local_time_span_object == null || Math.Abs (now - last_now) > TimeSpan.TicksPerMinute){
-                                       to_local_time_span_object = TimeZone.CurrentTimeZone.GetLocalTimeDiff (dt);
-                                       last_now = now;
-
-                               }
-
-                               // This is boxed, so we avoid locking.
-                               DateTime ret = dt + (TimeSpan) to_local_time_span_object;
-                               ret.encoded |= ((long)DateTimeKind.Local << KindShift);
-                               return ret;
-                       }
-               }
-
-               public long Ticks { 
-                       get { 
-                               return encoded & TicksMask;
-                       }
-               }
-       
-               public static DateTime Today {
-                       get {
-                               DateTime now = Now;
-                               DateTime today = new DateTime (now.Year, now.Month, now.Day);
-                               today.encoded |= ((long)DateTimeKind.Local << KindShift);
-                               return today;
-                       }
-               }
-
-               public static DateTime UtcNow {
-                       get {
-                               return new DateTime (GetNow (), DateTimeKind.Utc);
-                       }
-               }
-
-               public int Year {
-                       get { 
-                               return FromTicks (Which.Year); 
-                       }
-               }
-
-               public DateTimeKind Kind {
-                       get {
-                               return (DateTimeKind) ((ulong)encoded >> KindShift);
-                       }
-               }
-
-               /* methods */
-
-               public DateTime Add (TimeSpan value)
-               {
-                       DateTime ret = AddTicks (value.Ticks);
-                       return ret;
-               }
-
-               public DateTime AddDays (double value)
-               {
-                       return AddMilliseconds (Math.Round (value * 86400000));
-               }
-               
-               public DateTime AddTicks (long value)
-               {
-                       long res = value + (encoded & TicksMask);
-                       if (res < 0 || res > MAX_VALUE_TICKS)
-                               throw new ArgumentOutOfRangeException();
-
-                       DateTime ret = new DateTime (res);
-                       ret.encoded |= (encoded & KindMask);
-                       return ret;
-               }
-
-               public DateTime AddHours (double value)
-               {
-                       return AddMilliseconds (value * 3600000);
-               }
-
-               public DateTime AddMilliseconds (double value)
-               {
-                       if ((value * TimeSpan.TicksPerMillisecond) > long.MaxValue ||
-                           (value * TimeSpan.TicksPerMillisecond) < long.MinValue) {
-                               throw new ArgumentOutOfRangeException();
-                       }
-                       long msticks = (long) Math.Round (value * TimeSpan.TicksPerMillisecond);
-
-                       return AddTicks (msticks);
-               }
-
-               // required to match MS implementation for OADate (OLE Automation)
-               private DateTime AddRoundedMilliseconds (double ms)
-               {
-                       if ((ms * TimeSpan.TicksPerMillisecond) > long.MaxValue ||
-                               (ms * TimeSpan.TicksPerMillisecond) < long.MinValue) {
-                               throw new ArgumentOutOfRangeException ();
-                       }
-                       long msticks = (long) (ms += ms > 0 ? 0.5 : -0.5) * TimeSpan.TicksPerMillisecond;
-
-                       return AddTicks (msticks);
-               }
-
-               public DateTime AddMinutes (double value)
-               {
-                       return AddMilliseconds (value * 60000);
-               }
-               
-               public DateTime AddMonths (int months)
-               {
-                       int day, month, year,  maxday ;
-                       DateTime temp ;
-
-                       day = this.Day;
-                       month = this.Month + (months % 12);
-                       year = this.Year + months/12 ;
-                       
-                       if (month < 1)
-                       {
-                               month = 12 + month ;
-                               year -- ;
-                       }
-                       else if (month>12) 
-                       {
-                               month = month -12;
-                               year ++;
-                       }
-                       maxday = DaysInMonth(year, month);
-                       if (day > maxday)
-                               day = maxday;
-
-                       temp = new DateTime (year, month, day);
-                       temp.encoded |= encoded & KindMask;
-                       return  temp.Add (this.TimeOfDay);
-               }
-
-               public DateTime AddSeconds (double value)
-               {
-                       return AddMilliseconds (value * 1000);
-               }
-
-               public DateTime AddYears (int value)
-               {
-                       return AddMonths (value * 12);
-               }
-
-               public static int Compare (DateTime t1, DateTime t2)
-               {
-                       long t1t = t1.encoded & TicksMask;
-                       long t2t = t2.encoded & TicksMask;
-                       
-                       if (t1t < t2t) 
-                               return -1;
-                       else if (t1t > t2t) 
-                               return 1;
-                       else
-                               return 0;
-               }
-
-               public int CompareTo (object value)
-               {
-                       if (value == null)
-                               return 1;
-
-                       if (!(value is System.DateTime))
-                               throw new ArgumentException (Locale.GetText (
-                                       "Value is not a System.DateTime"));
-
-                       return Compare (this, (DateTime) value);
-               }
-
-               public bool IsDaylightSavingTime ()
-               {
-                       if ((int)((ulong)encoded >> KindShift) == (int) DateTimeKind.Utc)
-                               return false;
-                       return TimeZone.CurrentTimeZone.IsDaylightSavingTime (this);
-               }
-
-               public int CompareTo (DateTime value)
-               {
-                       return Compare (this, value);
-               }
-
-               public bool Equals (DateTime value)
-               {
-                       return (value.encoded & TicksMask) == (encoded & TicksMask);
-               }
-
-               public long ToBinary ()
-               {
-                       if ((encoded & ((long)DateTimeKind.Local << KindShift)) != 0)
-                               return (long) ((ulong) ToUniversalTime ().Ticks | 0x8000000000000000);
-                       
-                       return encoded;
-               }
-
-               public static DateTime FromBinary (long dateData)
-               {
-                       switch ((ulong)dateData >> KindShift) {
-                       case 1: // Utc
-                               return new DateTime (dateData & TicksMask, DateTimeKind.Utc);
-                       case 0: // Unspecified
-                               return new DateTime (dateData, DateTimeKind.Unspecified);
-                       default: // Local
-                               return new DateTime (dateData & TicksMask, DateTimeKind.Utc).ToLocalTime ();
-                       }
-               }
-
-               public static DateTime SpecifyKind (DateTime value, DateTimeKind kind)
-               {
-                       return new DateTime (value.Ticks, kind);
-               }
-
-               public static int DaysInMonth (int year, int month)
-               {
-                       int[] days ;
-
-                       if (month < 1 || month >12)
-                               throw new ArgumentOutOfRangeException ();
-
-                       if (year < 1 || year > 9999)
-                               throw new ArgumentOutOfRangeException ();
-
-                       days = (IsLeapYear(year) ? daysmonthleap  : daysmonth);
-                       return days[month];                     
-               }
-               
-               public override bool Equals (object value)
-               {
-                       if (!(value is System.DateTime))
-                               return false;
-
-                       return (((DateTime) value).encoded & TicksMask) == (encoded & TicksMask);
-               }
-
-               public static bool Equals (DateTime t1, DateTime t2 )
-               {
-                       return (t1.encoded & TicksMask) == (t2.encoded & TicksMask);
-               }
-
-               public static DateTime FromFileTime (long fileTime) 
-               {
-                       if (fileTime < 0)
-                               throw new ArgumentOutOfRangeException ("fileTime", "< 0");
-
-                       return new DateTime (w32file_epoch + fileTime).ToLocalTime ();
-               }
-
-               public static DateTime FromFileTimeUtc (long fileTime) 
-               {
-                       if (fileTime < 0)
-                               throw new ArgumentOutOfRangeException ("fileTime", "< 0");
-
-                       return new DateTime (w32file_epoch + fileTime, DateTimeKind.Utc);
-               }
-
-               public static DateTime FromOADate (double d)
-               {
-                       // An OLE Automation date is implemented as a floating-point number
-                       // whose value is the number of days from midnight, 30 December 1899.
-
-                       // d must be negative 657435.0 through positive 2958466.0.
-                       if ((d <= OAMinValue) || (d >= OAMaxValue))
-                               throw new ArgumentException ("d", "[-657435,2958466]");
-
-                       DateTime dt = new DateTime (ticks18991230);
-                       if (d < 0.0d) {
-                               Double days = Math.Ceiling (d);
-                               // integer part is the number of days (negative)
-                               dt = dt.AddRoundedMilliseconds (days * 86400000);
-                               // but decimals are the number of hours (in days fractions) and positive
-                               Double hours = (days - d);
-                               dt = dt.AddRoundedMilliseconds (hours * 86400000);
-                       }
-                       else {
-                               dt = dt.AddRoundedMilliseconds (d * 86400000);
-                       }
-
-                       return dt;
-               }
-
-               public string[] GetDateTimeFormats() 
-               {
-                       return GetDateTimeFormats (CultureInfo.CurrentCulture);
-               }
-
-               public string[] GetDateTimeFormats(char format)
-               {
-                       if ("dDgGfFmMrRstTuUyY".IndexOf (format) < 0)
-                               throw new FormatException ("Invalid format character.");
-                       string[] result = new string[1];
-                       result[0] = this.ToString(format.ToString());
-                       return result;
-               }
-               
-               public string[] GetDateTimeFormats(IFormatProvider provider)
-               {
-                       DateTimeFormatInfo info = (DateTimeFormatInfo) provider.GetFormat (typeof(DateTimeFormatInfo));
-//                     return GetDateTimeFormats (info.GetAllDateTimePatterns ());
-                       var l = new List<string> ();
-                       foreach (char c in "dDgGfFmMrRstTuUyY")
-                               l.AddRange (GetDateTimeFormats (c, info));
-                       return l.ToArray ();
-               }
-
-               public string[] GetDateTimeFormats(char format,IFormatProvider provider )
-               {
-                       return DateTimeFormat.GetAllDateTimes(this, format, DateTimeFormatInfo.GetInstance(provider));
-               }
-
-               private string [] GetDateTimeFormats (bool adjustutc, string [] patterns, DateTimeFormatInfo dfi)
-               {
-                       string [] results = new string [patterns.Length];
-                       DateTime val = adjustutc ? ToUniversalTime () : this;
-                       for (int i = 0; i < results.Length; i++)
-                               results [i] = DateTimeUtils.ToString (val, patterns [i], dfi);
-                       return results;
-               }
-
-               public override int GetHashCode ()
-               {
-                       return (int) encoded;
-               }
-
-               public TypeCode GetTypeCode ()
-               {
-                       return TypeCode.DateTime;
-               }
-
-               public static bool IsLeapYear (int year)
-               {
-                       if (year < 1 || year > 9999)
-                               throw new ArgumentOutOfRangeException ();
-                       return  ( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ;
-               }
-
-               public static DateTime Parse (string s)
-               {
-                       return Parse (s, null);
-               }
-
-               public static DateTime Parse (string s, IFormatProvider provider)
-               {
-                       return Parse (s, provider, DateTimeStyles.AllowWhiteSpaces);
-               }
-
-               public static DateTime Parse (string s, IFormatProvider provider, DateTimeStyles styles)
-               {
-                       if (s == null)
-                               throw new ArgumentNullException ("s");
-
-                       DateTime res;
-                       DateTimeOffset dto;
-                       Exception exception = null;
-                       if (!CoreParse (s, provider, styles, out res, out dto, true, ref exception))
-                               throw exception;
-                       
-                       return res;
-               }
-
-               const string formatExceptionMessage = "String was not recognized as a valid DateTime.";
-               
-               internal static bool CoreParse (string s, IFormatProvider provider, DateTimeStyles styles,
-                                             out DateTime result, out DateTimeOffset dto, bool setExceptionOnError, ref Exception exception)
-               {
-                       dto = new DateTimeOffset (0, TimeSpan.Zero);
-                       if (s == null || s.Length == 0) {
-                               if (setExceptionOnError)
-                                       exception = new FormatException (formatExceptionMessage);
-                               result = MinValue;
-                               return false;
-                       }
-
-                       if (provider == null)
-                               provider = CultureInfo.CurrentCulture;
-                       DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (provider);
-
-                       // Try first all the combinations of ParseAllDateFormats & ParseTimeFormats
-                       string[] allDateFormats = YearMonthDayFormats (dfi);
-                       if (allDateFormats == null){
-                               result = MinValue;
-                               return false;
-                       }
-
-                       bool longYear = false;
-                       for (int i = 0; i < allDateFormats.Length; i++) {
-                               string firstPart = allDateFormats [i];
-                               bool incompleteFormat = false;
-                               if (_DoParse (s, firstPart, "", false, out result, out dto, dfi, styles, true, ref incompleteFormat, ref longYear))
-                                       return true;
-
-                               if (!incompleteFormat)
-                                       continue;
-
-                               for (int j = 0; j < ParseTimeFormats.Length; j++) {
-                                       if (_DoParse (s, firstPart, ParseTimeFormats [j], false, out result, out dto, dfi, styles, true, ref incompleteFormat, ref longYear))
-                                               return true;
-                               }
-
-                               if (_DoParse (s, firstPart, "zzz", false, out result, out dto, dfi, styles, true, ref incompleteFormat, ref longYear))
-                                       return true;
-                       }
-
-                       //
-                       // Month day formats
-                       //
-                       int dayIndex = dfi.MonthDayPattern.IndexOf('d');
-                       int monthIndex = dfi.MonthDayPattern.IndexOf('M');
-                       if (dayIndex == -1 || monthIndex == -1){
-                               result = MinValue;
-                               if (setExceptionOnError)
-                                       exception = new FormatException (Locale.GetText("Order of month and date is not defined by {0}", dfi.MonthDayPattern));
-                               return false;
-                       }
-                       bool is_day_before_month = dayIndex < monthIndex;
-                       string[] monthDayFormats = is_day_before_month ? DayMonthShortFormats : MonthDayShortFormats;
-                       for (int i = 0; i < monthDayFormats.Length; i++) {
-                               bool incompleteFormat = false;
-                               if (_DoParse (s, monthDayFormats[i], "", false, out result, out dto, dfi, styles, true, ref incompleteFormat, ref longYear))
-                                       return true;
-                       }
-                       
-                       for (int j = 0; j < ParseTimeFormats.Length; j++) {
-                               string firstPart = ParseTimeFormats [j];
-                               bool incompleteFormat = false;
-                               if (_DoParse (s, firstPart, "", false, out result, out dto, dfi, styles, false, ref incompleteFormat, ref longYear))
-                                       return true;
-                               if (!incompleteFormat)
-                                       continue;
-
-                               for (int i = 0; i < monthDayFormats.Length; i++) {
-                                       if (_DoParse (s, firstPart, monthDayFormats [i], false, out result, out dto, dfi, styles, false, ref incompleteFormat, ref longYear))
-                                               return true;
-                               }
-                               for (int i = 0; i < allDateFormats.Length; i++) {
-                                       string dateFormat = allDateFormats [i];
-                                       if (dateFormat[dateFormat.Length - 1] == 'T')
-                                               continue; // T formats must be before the time part
-                                       if (_DoParse (s, firstPart, dateFormat, false, out result, out dto, dfi, styles, false, ref incompleteFormat, ref longYear))
-                                               return true;
-                               }
-                       }
-
-                       // Try as a last resort all the patterns
-                       if (CoreParseExact (s, dfi.GetAllDateTimePatternsInternal (), dfi, styles, out result, out dto, false, ref longYear, setExceptionOnError, ref exception))
-                               return true;
-
-                       if (CoreParseExact (s, ExoticAndNonStandardFormats, dfi, styles, out result, out dto, false, ref longYear, setExceptionOnError, ref exception))
-                               return true;
-
-                       if (!setExceptionOnError)
-                               return false;
-                       
-                       // .NET 2.x does not throw an ArgumentOutOfRangeException, but .NET 1.1 does.
-                       exception = new FormatException (formatExceptionMessage);
-                       return false;
-               }
-
-               public static DateTime ParseExact (string s, string format, IFormatProvider provider)
-               {
-                       return ParseExact (s, format, provider, DateTimeStyles.None);
-               }
-
-               private static string[] YearMonthDayFormats (DateTimeFormatInfo dfi)
-               {
-                       int dayIndex = dfi.ShortDatePattern.IndexOf('d');
-                       int monthIndex = dfi.ShortDatePattern.IndexOf('M');
-                       int yearIndex = dfi.ShortDatePattern.IndexOf('y');
-                       if (dayIndex == -1 || monthIndex == -1 || yearIndex == -1)
-                               return ParseGenericYearMonthDayFormats;
-
-                       if (yearIndex < monthIndex)
-                               if (monthIndex < dayIndex)
-                                       return ParseYearMonthDayFormats;
-                               else if (yearIndex < dayIndex)
-                                       return ParseYearDayMonthFormats;
-                               else {
-                                       // The year cannot be between the date and the month
-                                       return ParseGenericYearMonthDayFormats;
-                               }
-                       else if (dayIndex < monthIndex)
-                               return ParseDayMonthYearFormats;
-                       else if (dayIndex < yearIndex)
-                               return ParseMonthDayYearFormats;
-                       else {
-                               // The year cannot be between the month and the date
-                               return ParseGenericYearMonthDayFormats;
-                       }
-               }
-
-               private static int _ParseNumber (string s, int valuePos,
-                                                int min_digits,
-                                                int digits,
-                                                bool leadingzero,
-                                                bool sloppy_parsing,
-                                                out int num_parsed)
-               {
-                       int number = 0, i;
-
-                       if (sloppy_parsing)
-                               leadingzero = false;
-
-                       if (!leadingzero) {
-                               int real_digits = 0;
-                               for (i = valuePos; i < s.Length && i < digits + valuePos; i++) {
-                                       if (!Char.IsDigit (s[i]))
-                                               break;
-
-                                       real_digits++;
-                               }
-
-                               digits = real_digits;
-                       }
-                       if (digits < min_digits) {
-                               num_parsed = -1;
-                               return 0;
-                       }
-
-                       if (s.Length - valuePos < digits) {
-                               num_parsed = -1;
-                               return 0;
-                       }
-
-                       for (i = valuePos; i < digits + valuePos; i++) {
-                               char c = s[i];
-                               if (!Char.IsDigit (c)) {
-                                       num_parsed = -1;
-                                       return 0;
-                               }
-
-                               number = number * 10 + (byte) (c - '0');
-                       }
-
-                       num_parsed = digits;
-                       return number;
-               }
-
-               private static int _ParseEnum (string s, int sPos, string[] values, string[] invValues, bool exact, out int num_parsed)
-               {
-                       // FIXME: I know this is somehow lame code. Probably
-                       // it should iterate all the enum value and return
-                       // the longest match. However right now I don't see
-                       // anything but "1" and "10" - "12" that might match
-                       // two or more values. (They are only abbrev month
-                       // names, so do reverse order search). See bug #80094.
-                       for (int i = values.Length - 1; i >= 0; i--) {
-                               if (!exact && invValues [i].Length > values[i].Length) {
-                                       if (invValues [i].Length > 0 && _ParseString (s, sPos, 0, invValues [i], out num_parsed))
-                                               return i;
-                                       if (values [i].Length > 0 && _ParseString (s, sPos, 0, values [i], out num_parsed))
-                                               return i;
-                               }
-                               else {
-                                       if (values [i].Length > 0 && _ParseString (s, sPos, 0, values [i], out num_parsed))
-                                               return i;
-                                       if (!exact && invValues [i].Length > 0 && _ParseString (s, sPos, 0, invValues [i], out num_parsed))
-                                       return i;
-                               }
-                       }
-
-                       num_parsed = -1;
-                       return -1;
-               }
-
-               private static bool _ParseString (string s, int sPos, int maxlength, string value, out int num_parsed)
-               {
-                       if (maxlength <= 0)
-                               maxlength = value.Length;
-
-                       if (sPos + maxlength <= s.Length && String.CompareOrdinalCaseInsensitive (s, sPos, value, 0, maxlength) == 0) {
-                               num_parsed = maxlength;
-                               return true;
-                       }
-
-                       num_parsed = -1;
-                       return false;
-               }
-
-               // Note that in case of Parse (exact == false) we check both for AM/PM
-               // and the culture spcific AM/PM strings.
-               private static bool _ParseAmPm(string s,
-                                              int valuePos,
-                                              int num,
-                                              DateTimeFormatInfo dfi,
-                                              bool exact,
-                                              out int num_parsed,
-                                              ref int ampm)
-               {
-                       num_parsed = -1;
-                       if (ampm != -1)
-                               return false;
-
-                       if (!IsLetter (s, valuePos)) {
-                               if (dfi.AMDesignator != "")
-                                       return false;
-                               if (exact)
-                                       ampm = 0;
-                               num_parsed = 0;
-                               return true;
-                       }
-                       DateTimeFormatInfo invInfo = DateTimeFormatInfo.InvariantInfo;
-                       if (!exact && _ParseString (s, valuePos, num, invInfo.PMDesignator, out num_parsed) ||
-                           dfi.PMDesignator != "" && _ParseString(s, valuePos, num, dfi.PMDesignator, out num_parsed))
-                               ampm = 1;
-                       else if (!exact && _ParseString (s, valuePos, num, invInfo.AMDesignator, out num_parsed) ||
-                                _ParseString (s, valuePos, num, dfi.AMDesignator, out num_parsed)) {
-                               if (exact || num_parsed != 0)
-                                       ampm = 0;
-                       }
-                       else
-                               return false;
-                       return true;
-               }
-
-               // Note that in case of Parse (exact == false) we check both for ':'
-               // and the culture spcific TimeSperator
-               private static bool _ParseTimeSeparator (string s, int sPos, DateTimeFormatInfo dfi, bool exact, out int num_parsed)
-               {
-                       return _ParseString (s, sPos, 0, dfi.TimeSeparator, out num_parsed) ||
-                              !exact && _ParseString (s, sPos, 0, ":", out num_parsed);
-               }
-
-               // Accept any character for DateSeparator, except TimeSeparator,
-               // a digit or a letter.
-               // Not documented, but seems to be MS behaviour here.  See bug 54047.
-               private static bool _ParseDateSeparator (string s, int sPos, DateTimeFormatInfo dfi, bool exact, out int num_parsed)
-               {
-                       num_parsed = -1;
-                       if (exact && s [sPos] != '/')
-                               return false;
-
-                       if (_ParseTimeSeparator (s, sPos, dfi, exact, out num_parsed) ||
-                               Char.IsDigit (s [sPos]) || Char.IsLetter (s [sPos]))
-                               return(false);
-
-                       num_parsed = 1;
-                       return true;
-               }
-
-               private static bool IsLetter (string s, int pos)
-               {
-                       return pos < s.Length && Char.IsLetter (s [pos]);
-               }
-
-               // To implement better DateTime.Parse we use two format strings one
-               // for Date and one for Time. This allows us to define two different
-               // arrays of formats for Time and Dates and to combine them more or less
-               // efficiently. When this mode is used flexibleTwoPartsParsing is true.
-               private static bool _DoParse (string s,
-                                             string firstPart,
-                                             string secondPart,
-                                             bool exact,
-                                             out DateTime result,
-                                             out DateTimeOffset dto,
-                                             DateTimeFormatInfo dfi,
-                                             DateTimeStyles style,
-                                             bool firstPartIsDate,
-                                             ref bool incompleteFormat,
-                                             ref bool longYear,
-                                             bool dateTimeOffset = false)
-               {
-                       bool useutc = false;
-                       bool use_invariant = false;
-                       bool sloppy_parsing = false;
-                       dto = new DateTimeOffset (0, TimeSpan.Zero);
-                       bool flexibleTwoPartsParsing = !exact && secondPart != null;
-                       incompleteFormat = false;
-                       int valuePos = 0;
-                       string format = firstPart;
-                       bool afterTFormat = false;
-                       DateTimeFormatInfo invInfo = DateTimeFormatInfo.InvariantInfo;
-                       if (format.Length == 1)
-                               format = DateTimeUtils.GetStandardPattern (format [0], dfi, out useutc, out use_invariant, dateTimeOffset);
-
-                       result = new DateTime (0);
-                       if (format == null)
-                               return false;
-
-                       if (s == null)
-                               return false;
-                               
-                       if ((style & DateTimeStyles.AllowLeadingWhite) != 0) {
-                               format = format.TrimStart (null);
-
-                               s = s.TrimStart (null); // it could be optimized, but will make little good.
-                       }
-
-                       if ((style & DateTimeStyles.AllowTrailingWhite) != 0) {
-                               format = format.TrimEnd (null);
-                               s = s.TrimEnd (null); // it could be optimized, but will make little good.
-                       }
-
-                       if (use_invariant)
-                               dfi = invInfo;
-
-                       if ((style & DateTimeStyles.AllowInnerWhite) != 0)
-                               sloppy_parsing = true;
-
-                       string chars = format;
-                       int len = format.Length, pos = 0, num = 0;
-                       if (len == 0)
-                               return false;
-
-                       int day = -1, dayofweek = -1, month = -1, year = -1;
-                       int hour = -1, minute = -1, second = -1;
-                       double fractionalSeconds = -1;
-                       int ampm = -1;
-                       int tzsign = -1, tzoffset = -1, tzoffmin = -1;
-                       bool isFirstPart = true;
-                       bool format_with_24_hours = false;
-
-                       for (; ; )
-                       {
-                               if (valuePos == s.Length)
-                                       break;
-
-                               int num_parsed = 0;
-                               if (flexibleTwoPartsParsing && pos + num == 0)
-                               {
-                                       bool isLetter = IsLetter(s, valuePos);
-                                       if (isLetter) {
-                                               if (s [valuePos] == 'Z')
-                                                       num_parsed = 1;
-                                               else
-                                                       _ParseString (s, valuePos, 0, "GMT", out num_parsed);
-                                               if (num_parsed > 0 && !IsLetter (s, valuePos + num_parsed)) {
-                                                       valuePos += num_parsed;
-                                                       useutc = true;
-                                                       continue;
-                                               }
-                                       }
-                                       if (!afterTFormat && _ParseAmPm (s, valuePos, 0, dfi, exact, out num_parsed, ref ampm)) {
-                                               if (IsLetter (s, valuePos + num_parsed))
-                                                       ampm = -1;
-                                               else if (num_parsed > 0) {
-                                                       valuePos += num_parsed;
-                                                       continue;
-                                               }
-                                       }
-
-                                       if (!afterTFormat && dayofweek == -1 && isLetter) {
-                                               dayofweek = _ParseEnum (s, valuePos, dfi.RawDayNames, invInfo.RawDayNames, exact, out num_parsed);
-                                               if (dayofweek == -1)
-                                                       dayofweek = _ParseEnum (s, valuePos, dfi.RawAbbreviatedDayNames, invInfo.RawAbbreviatedDayNames, exact, out num_parsed);
-                                               if (dayofweek != -1 && !IsLetter (s, valuePos + num_parsed)) {
-                                                       valuePos += num_parsed;
-                                                       continue;
-                                               }
-                                               else
-                                                       dayofweek = -1;
-                                       }
-
-                                       if (char.IsWhiteSpace (s [valuePos]) || s [valuePos] == ',') {
-                                               valuePos += 1;
-                                               continue;
-                                       }
-                                       num_parsed = 0;
-                               }
-
-                               if (pos + num >= len)
-                               {
-                                       if (flexibleTwoPartsParsing && num == 0) {
-                                               afterTFormat = isFirstPart && firstPart [firstPart.Length - 1] == 'T';
-                                               if (!isFirstPart && format == "")
-                                                       break;
-
-                                               pos = 0;
-                                               if (isFirstPart)
-                                                       format = secondPart;
-                                               else
-                                                       format = "";
-                                               chars = format;
-                                               len = chars.Length;
-                                               isFirstPart = false;
-                                               continue;
-                                       }
-                                       break;
-                               }
-
-                               bool leading_zeros = true;
-
-                               if (chars[pos] == '\'') {
-                                       num = 1;
-                                       while (pos+num < len) {
-                                               if (chars[pos+num] == '\'')
-                                                       break;
-
-                                               if (valuePos == s.Length || s [valuePos] != chars [pos + num])
-                                                       return false;
-
-                                               valuePos++;
-                                               num++;
-                                       }
-
-                                       pos += num + 1;
-                                       num = 0;
-                                       continue;
-                               } else if (chars[pos] == '"') {
-                                       num = 1;
-                                       while (pos+num < len) {
-                                               if (chars[pos+num] == '"')
-                                                       break;
-
-                                               if (valuePos == s.Length || s [valuePos] != chars[pos+num])
-                                                       return false;
-
-                                               valuePos++;
-                                               num++;
-                                       }
-
-                                       pos += num + 1;
-                                       num = 0;
-                                       continue;
-                               } else if (chars[pos] == '\\') {
-                                       pos += num + 1;
-                                       num = 0;
-                                       if (pos >= len)
-                                               return false;
-                                       if (s [valuePos] != chars [pos])
-                                               return false;
-
-                                       valuePos++;
-                                       pos++;
-                                       continue;
-                               } else if (chars[pos] == '%') {
-                                       pos++;
-                                       continue;
-                               } else if (char.IsWhiteSpace (s [valuePos]) ||
-                                       s [valuePos] == ',' && (!exact && chars [pos] == '/' || Char.IsWhiteSpace (chars [pos]))) {
-                                       valuePos++;
-                                       num = 0;
-                                       if (exact && (style & DateTimeStyles.AllowInnerWhite) == 0) {
-                                               if (!Char.IsWhiteSpace (chars[pos]))
-                                                       return false;
-                                               pos++;
-                                               continue;
-                                       }
-
-                                       int ws = valuePos;
-                                       while (ws < s.Length) {
-                                               if (Char.IsWhiteSpace (s [ws]) || s [ws] == ',')
-                                                       ws++;
-                                               else
-                                                       break;
-                                       }
-                                       valuePos = ws;
-                                       ws = pos;
-                                       while (ws < chars.Length) {
-                                               if (Char.IsWhiteSpace (chars [ws]) || chars [ws] == ',')
-                                                       ws++;
-                                               else
-                                                       break;
-                                       }
-                                       pos = ws;
-                                       // A whitespace may match a '/' in the pattern.
-                                       if (!exact && pos < chars.Length && chars[pos] == '/')
-                                               if (!_ParseDateSeparator (s, valuePos, dfi, exact, out num_parsed))
-                                                       pos++;
-                                       continue;
-                               }
-
-                               if ((pos+num+1 < len) && (chars[pos+num+1] == chars[pos+num])) {
-                                       num++;
-                                       continue;
-                               }
-
-                               switch (chars[pos])
-                               {
-                               case 'd':
-                                       if (num < 2 && day != -1 || num >= 2 && dayofweek != -1)
-                                               return false;
-                                       if (num == 0)
-                                               day = _ParseNumber (s, valuePos, 1, 2, false, sloppy_parsing, out num_parsed);
-                                       else if (num == 1)
-                                               day = _ParseNumber (s, valuePos, 1, 2, true, sloppy_parsing, out num_parsed);
-                                       else if (num == 2)
-                                               dayofweek = _ParseEnum (s, valuePos, dfi.RawAbbreviatedDayNames, invInfo.RawAbbreviatedDayNames, exact, out num_parsed);
-                                       else
-                                               dayofweek = _ParseEnum (s, valuePos, dfi.RawDayNames, invInfo.RawDayNames, exact, out num_parsed);
-                                       break;
-                               case 'M':
-                                       if (month != -1)
-                                               return false;
-
-                                       if (flexibleTwoPartsParsing) {
-                                               num_parsed = -1;
-                                               if (num == 0 || num == 3)
-                                                       month = _ParseNumber (s, valuePos, 1, 2, false, sloppy_parsing, out num_parsed);
-                                               if (num > 1 && num_parsed == -1)
-                                                       month = _ParseEnum (s, valuePos, dfi.RawMonthNames, invInfo.RawMonthNames, exact, out num_parsed) + 1;
-                                               if (num > 1 && num_parsed == -1)
-                                                       month = _ParseEnum (s, valuePos, dfi.RawAbbreviatedMonthNames, invInfo.RawAbbreviatedMonthNames, exact, out num_parsed) + 1;
-                                               break;
-                                       }
-
-                                       if (num == 0)
-                                               month = _ParseNumber (s, valuePos, 1, 2, false, sloppy_parsing, out num_parsed);
-                                       else if (num == 1)
-                                               month = _ParseNumber (s, valuePos, 1, 2, true, sloppy_parsing, out num_parsed);
-                                       else if (num == 2)
-                                               month = _ParseEnum (s, valuePos, dfi.RawAbbreviatedMonthNames, invInfo.RawAbbreviatedMonthNames, exact, out num_parsed) + 1;
-                                       else
-                                               month = _ParseEnum (s, valuePos, dfi.RawMonthNames, invInfo.RawMonthNames, exact, out num_parsed) + 1;
-                                       break;
-                               case 'y':
-                                       if (year != -1)
-                                               return false;
-
-                                       if (num == 0) {
-                                               year = _ParseNumber (s, valuePos, 1, 2, false, sloppy_parsing, out num_parsed);
-                                       } else if (num < 3) {
-                                               year = _ParseNumber (s, valuePos, 1, 2, true, sloppy_parsing, out num_parsed);
-                                       } else {
-                                               year = _ParseNumber (s, valuePos, exact ? num + 1 : 3, num + 1, false, sloppy_parsing, out num_parsed);
-                                               longYear = (year > 9999);
-                                       }
-
-                                       //FIXME: We should do use dfi.Calendat.TwoDigitYearMax
-                                       if (num_parsed <= 2)
-                                               year += (year < 30) ? 2000 : 1900;
-                                       break;
-                               case 'h':
-                                       if (hour != -1)
-                                               return false;
-                                       if (num == 0)
-                                               hour = _ParseNumber (s, valuePos, 1, 2, false, sloppy_parsing, out num_parsed);
-                                       else
-                                               hour = _ParseNumber (s, valuePos, 1, 2, true, sloppy_parsing, out num_parsed);
-
-                                       if (hour > 12)
-                                               return false;
-                                       if (hour == 12)
-                                               hour = 0;
-
-                                       break;
-                               case 'H':
-                                       if (hour != -1 || !flexibleTwoPartsParsing && ampm >= 0)
-                                               return false;
-                                       if (num == 0)
-                                               hour = _ParseNumber (s, valuePos, 1, 2, false, sloppy_parsing, out num_parsed);
-                                       else
-                                               hour = _ParseNumber (s, valuePos, 1, 2, true, sloppy_parsing, out num_parsed);
-
-                                       if (hour >= 24)
-                                               return false;
-
-                                       format_with_24_hours = true;
-                                       break;
-                               case 'm':
-                                       if (minute != -1)
-                                               return false;
-                                       if (num == 0)
-                                               minute = _ParseNumber (s, valuePos, 1, 2, false, sloppy_parsing, out num_parsed);
-                                       else
-                                               minute = _ParseNumber (s, valuePos, 1, 2, true, sloppy_parsing, out num_parsed);
-
-                                       if (minute >= 60)
-                                               return false;
-
-                                       break;
-                               case 's':
-                                       if (second != -1)
-                                               return false;
-                                       if (num == 0)
-                                               second = _ParseNumber (s, valuePos, 1, 2, false, sloppy_parsing, out num_parsed);
-                                       else
-                                               second = _ParseNumber (s, valuePos, 1, 2, true, sloppy_parsing, out num_parsed);
-
-                                       if (second >= 60)
-                                               return false;
-
-                                       break;
-                               case 'F':
-                                       leading_zeros = false;
-                                       goto case 'f';
-                               case 'f':
-                                       if (num > 6 || fractionalSeconds != -1)
-                                               return false;
-                                       double decimalNumber = (double) _ParseNumber (s, valuePos, 0, num+1, leading_zeros, sloppy_parsing, out num_parsed);
-                                       if (num_parsed == -1)
-                                               return false;
-                                       fractionalSeconds = decimalNumber / Math.Pow(10.0, num_parsed);
-
-                                       //Parse ISO8601 with an unlimited number of fractional digits.
-                                       if (!exact && num == 6 && hour != -1 && minute != -1 && second != -1) {
-                                               var total_num_parsed = num_parsed;
-                                               while (true) {
-                                                       valuePos += num_parsed;
-                                                       decimalNumber = (double) _ParseNumber (s, valuePos, 0, 1, leading_zeros, sloppy_parsing, out num_parsed);
-                                                       if (num_parsed < 1) {
-                                                               num_parsed = 0;
-                                                               break;
-                                                       }
-
-                                                       total_num_parsed += num_parsed;
-                                                       if (total_num_parsed > 15)
-                                                               continue; //not enough precision, ignore additional digits.
-
-                                                       fractionalSeconds += decimalNumber / Math.Pow (10.0, total_num_parsed);
-                                               }
-                                       }
-                                       break;
-                               case 't':
-                                       if (!_ParseAmPm (s, valuePos, num > 0 ? 0 : 1, dfi, exact, out num_parsed, ref ampm))
-                                                       return false;
-                                       break;
-                               case 'z':
-                                       if (tzsign != -1)
-                                               return false;
-
-                                       if (s [valuePos] == '+')
-                                               tzsign = 0;
-                                       else if (s [valuePos] == '-')
-                                               tzsign = 1;
-                                       else
-                                               return false;
-                                       valuePos++;
-
-                                       if (num == 0)
-                                               tzoffset = _ParseNumber (s, valuePos, 1, 2, false, sloppy_parsing, out num_parsed);
-                                       else if (num == 1)
-                                               tzoffset = _ParseNumber (s, valuePos, 1, 2, true, sloppy_parsing, out num_parsed);
-                                       else {
-                                               tzoffset = _ParseNumber (s, valuePos, 1, 2, true, /*sloppy_parsing*/true, out num_parsed);
-                                               valuePos += num_parsed;
-                                               if (num_parsed < 0)
-                                                       return false;
-
-                                               num_parsed = 0;
-                                               if (valuePos < s.Length && Char.IsDigit (s [valuePos]) ||
-                                                       _ParseTimeSeparator (s, valuePos, dfi, exact, out num_parsed)) {
-                                                       valuePos += num_parsed;
-                                                       tzoffmin = _ParseNumber (s, valuePos, 1, 2, true, sloppy_parsing, out num_parsed);
-                                                       if (num_parsed < 0)
-                                                               return false;
-                                               }
-                                               else if (!flexibleTwoPartsParsing)
-                                                       return false;
-                                               else
-                                                       num_parsed = 0;
-                                       }
-                                       break;
-                               case 'K':
-                                       if (s [valuePos] == 'Z') {
-                                               valuePos++;
-                                               useutc = true;                                          
-                                       }
-                                       else if (s [valuePos] == '+' || s [valuePos] == '-') {
-                                               if (tzsign != -1)
-                                                       return false;
-                                               if (s [valuePos] == '+')
-                                                       tzsign = 0;
-                                               else if (s [valuePos] == '-')
-                                                       tzsign = 1;
-                                               valuePos++;
-
-                                               // zzz
-                                               tzoffset = _ParseNumber (s, valuePos, 0, 2, true, sloppy_parsing, out num_parsed);
-                                               valuePos += num_parsed;
-                                               if (num_parsed < 0)
-                                                       return false;
-
-                                               if (Char.IsDigit (s [valuePos]))
-                                                       num_parsed = 0;
-                                               else if (!_ParseString (s, valuePos, 0, dfi.TimeSeparator, out num_parsed))
-                                                       return false;
-                                               valuePos += num_parsed;
-
-                                               tzoffmin = _ParseNumber (s, valuePos, 0, 2, true, sloppy_parsing, out num_parsed);
-                                               if (num_parsed < 0)
-                                                       return false;
-                                       }
-                                       break;
-
-                               // LAMESPEC: This should be part of UTCpattern
-                               // string and thus should not be considered here.
-                               //
-                               // Note that 'Z' is not defined as a pattern
-                               // character. Keep it for X509 certificate
-                               // verification. Also, "Z" != "'Z'" under MS.NET
-                               // ("'Z'" is just literal; handled above)
-                               case 'Z':
-                                       if (s [valuePos] != 'Z')
-                                               return false;
-                                       num = 0;
-                                       num_parsed = 1;
-                                       useutc = true;
-                                       break;
-                               case 'G':
-                                       if (s [valuePos] != 'G')
-                                               return false;
-
-                                       if ((pos + 2 < len) && (valuePos + 2 < s.Length) &&
-                                               (chars [pos + 1] == 'M') && (s[valuePos + 1] == 'M') &&
-                                               (chars [pos + 2] == 'T') && (s[valuePos + 2] == 'T'))
-                                       {
-                                               useutc = true;
-                                               num = 2;
-                                               num_parsed = 3;
-                                       }
-                                       else {
-                                               num = 0;
-                                               num_parsed = 1;
-                                       }
-                                       break;
-                               case ':':
-                                       if (!_ParseTimeSeparator (s, valuePos, dfi, exact, out num_parsed))
-                                               return false;
-                                       break;
-                               case '/':
-                                       if (!_ParseDateSeparator (s, valuePos, dfi, exact, out num_parsed))
-                                               return false;
-
-                                       num = 0;
-                                       break;
-                               case '.':
-                                       if (s[valuePos] == '.') {
-                                               num = 0;
-                                               num_parsed = 1;
-                                               break;
-                                       }
-
-                                       // '.FFF....' can be mapped to nothing
-                                       if (pos + 1 < len && chars[pos + 1] == 'F') {
-                                               ++pos;
-                                               while (pos + 1 < len && chars[pos + 1] == 'F') {
-                                                       ++pos;
-                                               }
-
-                                               num = 0;
-                                               num_parsed = 0;
-                                               break;
-                                       }
-
-                                       return false;
-
-                               default:
-                                       if (s [valuePos] != chars [pos])
-                                                       return false;
-
-                                       num = 0;
-                                       num_parsed = 1;
-                                       break;
-                               }
-
-                               if (num_parsed < 0)
-                                       return false;
-
-                               valuePos += num_parsed;
-
-                               if (!exact && !flexibleTwoPartsParsing) {
-                                       switch (chars [pos]) {
-                                       case 'm':
-                                       case 's':
-                                       case 'F':
-                                       case 'f':
-                                       case 'z':
-                                               if (s.Length > valuePos && s [valuePos] == 'Z' &&
-                                                       (pos + 1 == chars.Length || chars [pos + 1] != 'Z')) {
-                                                       useutc = true;
-                                                       valuePos++;
-                                               }
-                                               break;
-                                       }
-                               }
-
-                               pos = pos + num + 1;
-                               num = 0;
-                       }
-
-                       if (pos + 1 < len && chars [pos] == '.' && chars [pos + 1] == 'F') {
-                               pos++;
-                               while (pos < len && chars [pos] == 'F') // '.FFF....' can be mapped to nothing. See bug #444103
-                                       pos++;
-                       }
-                       while (pos < len && chars [pos] == 'K') // 'K' can be mapped to nothing
-                               pos++;
-
-                       if (pos < len)
-                               return false;
-
-                       if (s.Length > valuePos) // extraneous tail.
-                       {
-                               if (valuePos == 0)
-                                       return false;
-
-                               if (Char.IsDigit (s [valuePos]) && Char.IsDigit (s [valuePos - 1]))
-                                       return false;
-                               if (Char.IsLetter (s [valuePos]) && Char.IsLetter (s [valuePos - 1]))
-                                       return false;
-                               incompleteFormat = true;
-                               return false;
-                       }
-
-                       if (hour == -1)
-                               hour = 0;
-                       if (minute == -1)
-                               minute = 0;
-
-                       if (second == -1)
-                               second = 0;
-                       if (fractionalSeconds == -1)
-                               fractionalSeconds = 0;
-
-                       // If no date was given
-                       if ((day == -1) && (month == -1) && (year == -1)) {
-                               if ((style & DateTimeStyles.NoCurrentDateDefault) != 0) {
-                                       day = 1;
-                                       month = 1;
-                                       year = 1;
-                               } else {
-                                       day = DateTime.Today.Day;
-                                       month = DateTime.Today.Month;
-                                       year = DateTime.Today.Year;
-                               }
-                       }
-
-                       if (day == -1)
-                               day = 1;
-                       if (month == -1)
-                               month = 1;
-                       if (year == -1) {
-                               if ((style & DateTimeStyles.NoCurrentDateDefault) != 0)
-                                       year = 1;
-                               else
-                                       year = DateTime.Today.Year;
-                       }
-                       
-                       if (ampm == 0) { // AM designator
-                               if (hour >= 12 && format_with_24_hours && exact)
-                                       return false;
-                               
-                               if (hour == 12)
-                                       hour = 0;
-                       } else if (ampm == 1) { // PM designator
-                               if (hour < 12) {
-                                       if (format_with_24_hours && exact)
-                                               return false;
-                                       
-                                       hour += 12;
-                               }
-                       }
-                       
-                       try {
-                               result = dfi.Calendar.ToDateTime (year, month, day, hour, minute, second, 0);
-                       } catch {
-                               return false;
-                       }
-
-                       result = result.AddSeconds(fractionalSeconds);
-
-                       if (dayofweek != -1 && dayofweek != (int) result.DayOfWeek)
-                               return false;
-
-                       if (tzsign == -1) {
-                               if (result != DateTime.MinValue) {
-                                       try {
-                                               if (((style & DateTimeStyles.AssumeUniversal) != 0) || useutc) {
-                                                       dto = new DateTimeOffset (result, TimeSpan.Zero);
-                                               } else if ((style & DateTimeStyles.AssumeLocal) != 0) {
-                                                       var offset = use_invariant ?
-                                                               TimeSpan.Zero :
-                                                               TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.Now);
-                                                       dto = new DateTimeOffset (result, offset);
-                                               } else {
-                                                       dto = new DateTimeOffset (result);
-                                               }
-                                       } catch { } // We handle this error in DateTimeOffset.Parse
-                               }
-                       } else {
-                               if (tzoffmin == -1)
-                                       tzoffmin = 0;
-                               if (tzoffset == -1)
-                                       tzoffset = 0;
-                               if (tzsign == 1) {
-                                       tzoffset = -tzoffset;
-                                       tzoffmin = -tzoffmin;
-                               }
-                               try {
-                                       dto = new DateTimeOffset (result, new TimeSpan (tzoffset, tzoffmin, 0));
-                               } catch {} // We handle this error in DateTimeOffset.Parse
-                       }
-                       bool adjustToUniversal = (style & DateTimeStyles.AdjustToUniversal) != 0;
-                       
-                       if (tzsign != -1) {
-                               long newticks = (result - dto.Offset).Ticks;
-                               if (newticks < 0)
-                                       newticks += TimeSpan.TicksPerDay;
-                               result = new DateTime (newticks, DateTimeKind.Utc);
-                               if ((style & DateTimeStyles.RoundtripKind) != 0)
-                                       result = result.ToLocalTime ();
-                       } else if (useutc || ((style & DateTimeStyles.AssumeUniversal) != 0))
-                               result.encoded |= ((long) DateTimeKind.Utc << KindShift);
-                       else if ((style & DateTimeStyles.AssumeLocal) != 0)
-                               result.encoded |= ((long) DateTimeKind.Local << KindShift);
-
-                       bool adjustToLocal = !adjustToUniversal && (style & DateTimeStyles.RoundtripKind) == 0;
-                       if ((DateTimeKind)(((ulong) result.encoded >> KindShift)) != DateTimeKind.Unspecified) {
-                               if (adjustToUniversal)
-                                       result = result.ToUniversalTime ();
-                               else if (adjustToLocal)
-                                       result = result.ToLocalTime ();
-                       }
-                       return true;
-               }
-               
-
-               public static DateTime ParseExact (string s, string format,
-                                                  IFormatProvider provider, DateTimeStyles style)
-               {
-                       if (format == null)
-                               throw new ArgumentNullException ("format");
-
-                       string [] formats = new string [1];
-                       formats[0] = format;
-
-                       return ParseExact (s, formats, provider, style);
-               }
-
-               public static DateTime ParseExact (string s, string[] formats,
-                                                  IFormatProvider provider,
-                                                  DateTimeStyles style)
-               {
-                       DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (provider);
-                       CheckStyle (style);
-                       if (s == null)
-                               throw new ArgumentNullException ("s");
-                       if (formats == null)
-                               throw new ArgumentNullException ("formats");
-                       if (formats.Length == 0)
-                               throw new FormatException ("Format specifier was invalid.");
-
-                       DateTime result;
-                       DateTimeOffset dto;
-                       bool longYear = false;
-                       Exception e = null;
-                       if (!CoreParseExact (s, formats, dfi, style, out result, out dto, true, ref longYear, true, ref e))
-                               throw e;
-                       return result;
-               }               
-
-               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, AssumeUniversal 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)
-               {
-                       if (s != null){
-                               try {
-                                       Exception exception = null;
-                                       DateTimeOffset dto;
-
-                                       return CoreParse (s, null, DateTimeStyles.AllowWhiteSpaces, out result, out dto, false, ref exception);
-                               } catch { }
-                       }
-                       result = MinValue;
-                       return false;
-               }
-               
-               public static bool TryParse (string s, IFormatProvider provider, DateTimeStyles styles, out DateTime result)
-               {
-                       if (s != null){
-                               try {
-                                       Exception exception = null;
-                                       DateTimeOffset dto;
-                                       
-                                       return CoreParse (s, provider, styles, out result, out dto, false, ref exception);
-                               } catch {}
-                       } 
-                       result = MinValue;
-                       return false;
-               }
-               
-               public static bool TryParseExact (string s, string format,
-                                                 IFormatProvider provider,
-                                                 DateTimeStyles style,
-                                                 out DateTime result)
-               {
-                       string[] formats;
-                       formats = new string [1];
-                       formats[0] = format;
-
-                       return TryParseExact (s, formats, provider, style, out result);
-               }
-
-               public static bool TryParseExact (string s, string[] formats,
-                                                 IFormatProvider provider,
-                                                 DateTimeStyles style,
-                                                 out DateTime result)
-               {
-                       try {
-                               DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (provider);
-                               DateTimeOffset dto;
-
-                               bool longYear = false;
-                               Exception e = null;
-                               return CoreParseExact (s, formats, dfi, style, out result, out dto, true, ref longYear, false, ref e);
-                       } catch {
-                               result = MinValue;
-                               return false;
-                       }
-               }
-
-               internal static bool CoreParseExact (string s, string [] formats,
-                                               DateTimeFormatInfo dfi, DateTimeStyles style,
-                                               out DateTime ret, out DateTimeOffset dto,
-                                               bool exact, ref bool longYear,
-                                               bool setExceptionOnError, ref Exception exception,
-                                               bool dateTimeOffset = false)
-               {
-                       dto = new DateTimeOffset (0, TimeSpan.Zero);
-                       int i;
-                       bool incompleteFormat = false;
-                       for (i = 0; i < formats.Length; i++)
-                       {
-                               DateTime result;
-                               string format = formats[i];
-                               if (format == null || format == String.Empty)
-                                       break;
-
-                               if (_DoParse (s, formats[i], null, exact, out result, out dto, dfi, style, false, ref incompleteFormat, ref longYear, dateTimeOffset)) {
-                                       ret = result;
-                                       return true;
-                               }
-                       }
-
-                       if (setExceptionOnError)
-                               exception = new FormatException ("Invalid format string");
-                       ret = DateTime.MinValue;
-                       return false;
-               }
-               
-               public TimeSpan Subtract (DateTime value)
-               {
-                       return new TimeSpan (Ticks) - new TimeSpan (value.Ticks);
-               }
-
-               public DateTime Subtract(TimeSpan value)
-               {
-                       long newticks;
-
-                       newticks = Ticks - value.Ticks;
-                       if (newticks < 0 || newticks > MAX_VALUE_TICKS)
-                               throw new ArgumentOutOfRangeException ();
-                       DateTime ret = new DateTime (newticks);
-                       ret.encoded |= (encoded & KindMask);
-                       return ret;
-               }
-
-               public long ToFileTime()
-               {
-                       DateTime universalTime = ToUniversalTime();
-                       
-                       if (universalTime.Ticks < w32file_epoch) {
-                               throw new ArgumentOutOfRangeException("file time is not valid");
-                       }
-                       
-                       return(universalTime.Ticks - w32file_epoch);
-               }
-
-               public long ToFileTimeUtc()
-               {
-                       if (Kind == DateTimeKind.Local)
-                               return ToFileTime ();
-
-                       if (Ticks < w32file_epoch) {
-                               throw new ArgumentOutOfRangeException("file time is not valid");
-                       }
-                       
-                       return (Ticks - w32file_epoch);
-               }
-
-               public string ToLongDateString()
-               {
-                       return ToString ("D");
-               }
-
-               public string ToLongTimeString()
-               {
-                       return ToString ("T");
-               }
-
-               public double ToOADate ()
-               {
-                       long t = this.Ticks;
-                       // uninitialized DateTime case
-                       if (t == 0)
-                               return 0;
-                       // we can't reach minimum value
-                       if (t < 31242239136000000)
-                               return OAMinValue + 0.001;
-
-                       TimeSpan ts = new TimeSpan (this.Ticks - ticks18991230);
-                       double result = ts.TotalDays;
-                       // t < 0 (where 599264352000000000 == 0.0d for OA)
-                       if (t < 599264352000000000) {
-                               // negative days (int) but decimals are positive
-                               double d = Math.Ceiling (result);
-                               result = d - 2 - (result - d);
-                       }
-                       else {
-                               // we can't reach maximum value
-                               if (result >= OAMaxValue)
-                                       result = OAMaxValue - 0.00000001d;
-                       }
-                       return result;
-               }
-
-               public string ToShortDateString()
-               {
-                       return ToString ("d");
-               }
-
-               public string ToShortTimeString()
-               {
-                       return ToString ("t");
-               }
-               
-               public override string ToString ()
-               {
-                       return ToString ("G", null);
-               }
-
-               public string ToString (IFormatProvider provider)
-               {
-                       return ToString (null, provider);
-               }
-
-               public string ToString (string format)
-               {
-                       return ToString (format, null);
-               }
-       
-               public string ToString (string format, IFormatProvider provider)
-               {
-                       DateTimeFormatInfo dfi = DateTimeFormatInfo.GetInstance (provider);
-
-                       if (format == null || format == String.Empty)
-                               format = "G";
-
-                       if (format.Length == 1) {
-                               char fchar = format [0];
-                               bool use_invariant, useutc;
-                               format = DateTimeUtils.GetStandardPattern (fchar, dfi, out useutc, out use_invariant);
-                               if (fchar == 'U')
-                                       return DateTimeUtils.ToString (ToUniversalTime (), format, dfi);
-//                                     return ToUniversalTime()._ToString (format, dfi);
-
-                               if (format == null)
-                                       throw new FormatException ("format is not one of the format specifier characters defined for DateTimeFormatInfo");
-
-                               if (use_invariant)
-                                       dfi = DateTimeFormatInfo.InvariantInfo;
-                       }
-
-                       // Don't convert UTC value. It just adds 'Z' for 
-                       // 'u' format, for the same ticks.
-                       return DateTimeUtils.ToString (this, format, dfi);
-               }
-
-               public DateTime ToLocalTime ()
-               {
-                       return TimeZone.CurrentTimeZone.ToLocalTime (this);
-               }
-
-               internal DateTime ToLocalTime (bool throwOnOverflow)
-               {
-                       return ToLocalTime ();
-               }
-
-               public DateTime ToUniversalTime()
-               {
-                       return TimeZone.CurrentTimeZone.ToUniversalTime (this);
-               }
-
-               /*  OPERATORS */
-
-               public static DateTime operator +(DateTime d, TimeSpan t)
-               {
-                       try {
-                               long res = checked ((d.encoded & TicksMask) + t.Ticks);
-                               if (res < 0 || res > MAX_VALUE_TICKS){
-                                       throw new ArgumentOutOfRangeException ();
-                               }
-                               
-                               return new DateTime (res, d.Kind);
-                       } catch (OverflowException){
-                               throw new ArgumentOutOfRangeException ();
-                       }
-               }
-
-               public static bool operator ==(DateTime d1, DateTime d2)
-               {
-                       return ((d1.encoded & TicksMask) == (d2.encoded & TicksMask));
-               }
-
-               public static bool operator >(DateTime t1,DateTime t2)
-               {
-                       return ((t1.encoded & TicksMask) > (t2.encoded & TicksMask));
-               }
-
-               public static bool operator >=(DateTime t1,DateTime t2)
-               {
-                       return ((t1.encoded & TicksMask) >= (t2.encoded & TicksMask));
-               }
-
-               public static bool operator !=(DateTime d1, DateTime d2)
-               {
-                       return ((d1.encoded & TicksMask) != (d2.encoded & TicksMask));
-               }
-
-               public static bool operator <(DateTime t1, DateTime t2)
-               {
-                       return ((t1.encoded & TicksMask) < (t2.encoded & TicksMask));
-               }
-
-               public static bool operator <=(DateTime t1, DateTime t2)
-               {
-                       return ((t1.encoded & TicksMask) <= (t2.encoded & TicksMask));
-               }
-
-               public static TimeSpan operator -(DateTime d1, DateTime d2)
-               {
-                       return new TimeSpan ((d1.encoded & TicksMask) - (d2.encoded & TicksMask));
-               }
-
-               public static DateTime operator -(DateTime d, TimeSpan t)
-               {
-                       try {
-                               long res = checked ((d.encoded & TicksMask) - t.Ticks);
-                               if (res < 0 || res > MAX_VALUE_TICKS)
-                                       throw new ArgumentOutOfRangeException ();
-                               return new DateTime (res, d.Kind);
-                       } catch (OverflowException){
-                               throw new ArgumentOutOfRangeException ();
-                       }
-               }
-
-               bool IConvertible.ToBoolean (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-               }
-               
-               byte IConvertible.ToByte (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-
-               }
-
-               char IConvertible.ToChar (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-               }
-
-               System.DateTime IConvertible.ToDateTime (IFormatProvider provider)
-               {
-                       return this;
-               } 
-               
-               decimal IConvertible.ToDecimal (IFormatProvider provider)
-               {
-                        throw new InvalidCastException();
-               }
-
-               double IConvertible.ToDouble (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-               }
-
-               Int16 IConvertible.ToInt16 (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-               }
-
-               Int32 IConvertible.ToInt32 (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-               }
-
-               Int64 IConvertible.ToInt64 (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-               }
-
-               SByte IConvertible.ToSByte (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-               }
-
-               Single IConvertible.ToSingle (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-               }
-
-               object IConvertible.ToType (Type targetType, IFormatProvider provider)
-               {
-                       if (targetType == null)
-                               throw new ArgumentNullException ("targetType");
-
-                       if (targetType == typeof (DateTime))
-                               return this;
-                       else if (targetType == typeof (String))
-                               return this.ToString (provider);
-                       else if (targetType == typeof (Object))
-                               return this;
-                       else
-                               throw new InvalidCastException();
-               }
-
-               UInt16 IConvertible.ToUInt16 (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-               }
-
-               UInt32 IConvertible.ToUInt32 (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-               }
-
-               UInt64 IConvertible.ToUInt64 (IFormatProvider provider)
-               {
-                       throw new InvalidCastException();
-               }
-
-               void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
-               {
-                       long t = Ticks;
-                       info.AddValue ("ticks", t);
-
-                       // This is the new .NET format, encodes the kind on the top bits
-                       info.AddValue ("dateData", (UInt64)encoded);
-               }
-
-#region Extracted from Microsoft reference sources
-
-        // Number of 100ns ticks per time unit
-        private const long TicksPerMillisecond = 10000;
-        private const long TicksPerSecond = TicksPerMillisecond * 1000;
-        private const long TicksPerMinute = TicksPerSecond * 60;
-        private const long TicksPerHour = TicksPerMinute * 60;
-        private const long TicksPerDay = TicksPerHour * 24;
-    
-        // Number of milliseconds per time unit
-        private const int MillisPerSecond = 1000;
-        private const int MillisPerMinute = MillisPerSecond * 60;
-        private const int MillisPerHour = MillisPerMinute * 60;
-        private const int MillisPerDay = MillisPerHour * 24;
-    
-        // Number of days in a non-leap year
-        private const int DaysPerYear = 365;
-        // Number of days in 4 years
-        private const int DaysPer4Years = DaysPerYear * 4 + 1;       // 1461
-        // Number of days in 100 years
-        private const int DaysPer100Years = DaysPer4Years * 25 - 1;  // 36524
-        // Number of days in 400 years
-        private const int DaysPer400Years = DaysPer100Years * 4 + 1; // 146097
-    
-        // Number of days from 1/1/0001 to 12/31/1600
-        private const int DaysTo1601 = DaysPer400Years * 4;          // 584388
-        // Number of days from 1/1/0001 to 12/30/1899
-        private const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
-        // Number of days from 1/1/0001 to 12/31/9999
-        private const int DaysTo10000 = DaysPer400Years * 25 - 366;  // 3652059
-    
-        internal const long MinTicks = 0;
-        internal const long MaxTicks = DaysTo10000 * TicksPerDay - 1;
-        private const long MaxMillis = (long)DaysTo10000 * MillisPerDay;
-    
-        private const long FileTimeOffset = DaysTo1601 * TicksPerDay;
-        private const long DoubleDateOffset = DaysTo1899 * TicksPerDay;
-        // The minimum OA date is 0100/01/01 (Note it's year 100).
-        // The maximum OA date is 9999/12/31
-        private const long OADateMinAsTicks = (DaysPer100Years - DaysPerYear) * TicksPerDay;
-        // All OA dates must be greater than (not >=) OADateMinAsDouble
-        private const double OADateMinAsDouble = -657435.0;
-        // All OA dates must be less than (not <=) OADateMaxAsDouble
-        private const double OADateMaxAsDouble = 2958466.0;
-    
-        private const int DatePartYear = 0;
-        private const int DatePartDayOfYear = 1;
-        private const int DatePartMonth = 2;
-        private const int DatePartDay = 3;
-    
-        private static readonly int[] DaysToMonth365 = {
-            0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
-        private static readonly int[] DaysToMonth366 = {
-            0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
-
-        // Returns the tick count corresponding to the given year, month, and day.
-        // Will check the if the parameters are valid.
-        private static long DateToTicks(int year, int month, int day) {     
-            if (year >= 1 && year <= 9999 && month >= 1 && month <= 12) {
-                int[] days = IsLeapYear(year)? DaysToMonth366: DaysToMonth365;
-                if (day >= 1 && day <= days[month] - days[month - 1]) {
-                    int y = year - 1;
-                    int n = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
-                    return n * TicksPerDay;
-                }
-            }
-            throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
-        }
-
-        // Return the tick count corresponding to the given hour, minute, second.
-        // Will check the if the parameters are valid.
-        private static long TimeToTicks(int hour, int minute, int second)
-        {
-            //TimeSpan.TimeToTicks is a family access function which does no error checking, so
-            //we need to put some error checking out here.
-            if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >=0 && second < 60)
-            {
-                return (TimeSpan.TimeToTicks(hour, minute, second));
-            }
-            throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadHourMinuteSecond"));
-        }        
-
-        // Tries to construct a DateTime from a given year, month, day, hour,
-        // minute, second and millisecond.
-        //
-        internal static Boolean TryCreate(int year, int month, int day, int hour, int minute, int second, int millisecond, out DateTime result) {
-            result = DateTime.MinValue;
-            if (year < 1 || year > 9999 || month < 1 || month > 12) {
-                return false;
-            }
-            int[] days = IsLeapYear(year) ? DaysToMonth366 : DaysToMonth365;
-            if (day < 1 || day > days[month] - days[month - 1]) {
-                return false;
-            }                
-            if (hour < 0 || hour >= 24 || minute < 0 || minute >= 60 || second < 0 || second >= 60) {
-                return false;
-            }                
-            if (millisecond < 0 || millisecond >= MillisPerSecond) {
-                return false;
-            }
-            long ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
-            
-            ticks += millisecond * TicksPerMillisecond;
-            if (ticks < MinTicks || ticks > MaxTicks) {
-                return false;
-            }
-            result = new DateTime(ticks, DateTimeKind.Unspecified);
-            return true;
-        }              
-#endregion
-
-#if MONOTOUCH
-               static DateTime () {
-                       if (MonoTouchAOTHelper.FalseFlag) {
-                               var comparer = new System.Collections.Generic.GenericComparer <DateTime> ();
-                               var eqcomparer = new System.Collections.Generic.GenericEqualityComparer <DateTime> ();
-                       }
-               }
-#endif
-       }
-}
diff --git a/mcs/class/corlib/System/DateTimeKind.cs b/mcs/class/corlib/System/DateTimeKind.cs
deleted file mode 100644 (file)
index 74138de..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// System.DateTimeKind enumeration
-//
-// Author:
-//     Sebastien Pouliot  <sebastien@ximian.com>
-//
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-
-using System.Runtime.InteropServices;
-
-namespace System {
-
-       [ComVisible (true)]
-       [Serializable]
-       public enum DateTimeKind {
-
-               Unspecified,
-               Utc,
-               Local
-       }
-}
diff --git a/mcs/class/corlib/System/DateTimeUtils.cs b/mcs/class/corlib/System/DateTimeUtils.cs
deleted file mode 100644 (file)
index c9a9eeb..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * System.DateTimeUtils
- *
- *  Copyright (C) 2007 Novell, Inc (http://www.novell.com) 
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-using System.Globalization;
-using System.Text;
-
-namespace System {
-       internal static class DateTimeUtils {
-               public static int CountRepeat (string fmt, int p, char c)
-               {
-                       int l = fmt.Length;
-                       int i = p + 1;
-                       while ((i < l) && (fmt [i] == c)) 
-                               i++;
-                       
-                       return i - p;
-               }
-
-               public static unsafe void ZeroPad (StringBuilder output, int digits, int len)
-               {
-                       // more than enough for an int
-                       char* buffer = stackalloc char [16];
-                       int pos = 16;
-                       
-                       do {
-                               buffer [-- pos] = (char) ('0' + digits % 10);
-                               digits /= 10;
-                               len --;
-                       } while (digits > 0);
-                       
-                       while (len -- > 0)
-                               buffer [-- pos] = '0';
-                       
-                       output.Append (new string (buffer, pos, 16 - pos));
-               }
-
-               static int ParseQuotedString (string fmt, int pos, StringBuilder output)
-               {
-                       // pos == position of " or '
-                       
-                       int len = fmt.Length;
-                       int start = pos;
-                       char quoteChar = fmt [pos++];
-                       
-                       while (pos < len) {
-                               char ch = fmt [pos++];
-                               
-                               if (ch == quoteChar)
-                                       return pos - start;
-                               
-                               if (ch == '\\') {
-                                       // C-Style escape
-                                       if (pos >= len)
-                                               throw new FormatException("Un-ended quote");
-       
-                                       if (output != null)
-                                               output.Append (fmt [pos++]);
-                               } else {
-                                       if (output != null)
-                                               output.Append (ch);
-                               }
-                       }
-
-                       throw new FormatException("Un-ended quote");
-               }
-
-               public static string GetStandardPattern (char format, DateTimeFormatInfo dfi, out bool useutc, out bool use_invariant)
-               {
-                       return GetStandardPattern (format, dfi, out useutc, out use_invariant, false);
-               }
-
-               public static string GetStandardPattern (char format, DateTimeFormatInfo dfi, out bool useutc, out bool use_invariant, bool date_time_offset)
-               {
-                       String pattern;
-
-                       useutc = false;
-                       use_invariant = false;
-
-                       switch (format)
-                       {
-                       case 'd':
-                               pattern = dfi.ShortDatePattern;
-                               break;
-                       case 'D':
-                               pattern = dfi.LongDatePattern;
-                               break;
-                       case 'f':
-                               pattern = dfi.LongDatePattern + " " + dfi.ShortTimePattern;
-                               break;
-                       case 'F':
-                               pattern = dfi.FullDateTimePattern;
-                               break;
-                       case 'g':
-                               pattern = dfi.ShortDatePattern + " " + dfi.ShortTimePattern;
-                               break;
-                       case 'G':
-                               pattern = dfi.ShortDatePattern + " " + dfi.LongTimePattern;
-                               break;
-                       case 'm':
-                       case 'M':
-                               pattern = dfi.MonthDayPattern;
-                               break;
-                       case 'o':
-                       case 'O':
-                               pattern = DateTimeFormat.RoundtripFormat;
-                               use_invariant = true;
-                               break;
-                       case 'r':
-                       case 'R':
-                               pattern = dfi.RFC1123Pattern;
-                               if (date_time_offset)
-                                       useutc = true;
-                               use_invariant = true;
-                               break;
-                       case 's':
-                               pattern = dfi.SortableDateTimePattern;
-                               use_invariant = true;
-                               break;
-                       case 't':
-                               pattern = dfi.ShortTimePattern;
-                               break;
-                       case 'T':
-                               pattern = dfi.LongTimePattern;
-                               break;
-                       case 'u':
-                               pattern = dfi.UniversalSortableDateTimePattern;
-                               if (date_time_offset)
-                                       useutc = true;
-                               use_invariant = true;
-                               break;
-                       case 'U':
-                               if (date_time_offset)
-                                       pattern = null;
-                               else {
-//                                     pattern = dfi.LongDatePattern + " " + dfi.LongTimePattern;
-                                       pattern = dfi.FullDateTimePattern;
-                                       useutc = true;
-                               }
-                               break;
-                       case 'y':
-                       case 'Y':
-                               pattern = dfi.YearMonthPattern;
-                               break;
-                       default:
-                               pattern = null;
-                               break;
-//                             throw new FormatException (String.Format ("Invalid format pattern: '{0}'", format));
-                       }
-
-                       return pattern;
-               }
-
-               public static string ToString (DateTime dt, string format, DateTimeFormatInfo dfi)
-               {
-                       return ToString (dt, null, format, dfi);
-               }
-
-               public static string ToString (DateTime dt, TimeSpan? utc_offset, string format, DateTimeFormatInfo dfi)
-               {
-                       // the length of the format is usually a good guess of the number
-                       // of chars in the result. Might save us a few bytes sometimes
-                       // Add + 10 for cases like mmmm dddd
-                       StringBuilder result = new StringBuilder (format.Length + 10);
-
-                       int i = 0;
-                       bool saw_day_specifier = false;
-
-                       while (i < format.Length) {
-                               int tokLen;
-                               bool omitZeros = false;
-                               char ch = format [i];
-
-                               switch (ch) {
-
-                               //
-                               // Time Formats
-                               //
-                               case 'h':
-                                       // hour, [1, 12]
-                                       tokLen = DateTimeUtils.CountRepeat (format, i, ch);
-
-                                       int hr = dt.Hour % 12;
-                                       if (hr == 0)
-                                               hr = 12;
-
-                                       DateTimeUtils.ZeroPad (result, hr, tokLen == 1 ? 1 : 2);
-                                       break;
-                               case 'H':
-                                       // hour, [0, 23]
-                                       tokLen = DateTimeUtils.CountRepeat (format, i, ch);
-                                       DateTimeUtils.ZeroPad (result, dt.Hour, tokLen == 1 ? 1 : 2);
-                                       break;
-                               case 'm':
-                                       // minute, [0, 59]
-                                       tokLen = DateTimeUtils.CountRepeat (format, i, ch);
-                                       DateTimeUtils.ZeroPad (result, dt.Minute, tokLen == 1 ? 1 : 2);
-                                       break;
-                               case 's':
-                                       // second [0, 29]
-                                       tokLen = DateTimeUtils.CountRepeat (format, i, ch);
-                                       DateTimeUtils.ZeroPad (result, dt.Second, tokLen == 1 ? 1 : 2);
-                                       break;
-                               case 'F':
-                                       omitZeros = true;
-                                       goto case 'f';
-                               case 'f':
-                                       // fraction of second, to same number of
-                                       // digits as there are f's
-
-                                       tokLen = DateTimeUtils.CountRepeat (format, i, ch);
-                                       if (tokLen > 7)
-                                               throw new FormatException ("Invalid Format String");
-
-                                       int dec = (int)((long)(dt.Ticks % TimeSpan.TicksPerSecond) / (long) Math.Pow (10, 7 - tokLen));
-                                       int startLen = result.Length;
-                                       DateTimeUtils.ZeroPad (result, dec, tokLen);
-
-                                       if (omitZeros) {
-                                               while (result.Length > startLen && result [result.Length - 1] == '0')
-                                                       result.Length--;
-                                               // when the value was 0, then trim even preceding '.' (!) It is fixed character.
-                                               if (dec == 0 && startLen > 0 && result [startLen - 1] == '.')
-                                                       result.Length--;
-                                       }
-
-                                       break;
-                               case 't':
-                                       // AM/PM. t == first char, tt+ == full
-                                       tokLen = DateTimeUtils.CountRepeat (format, i, ch);
-                                       string desig = dt.Hour < 12 ? dfi.AMDesignator : dfi.PMDesignator;
-
-                                       if (tokLen == 1) {
-                                               if (desig.Length >= 1)
-                                                       result.Append (desig [0]);
-                                       }
-                                       else
-                                               result.Append (desig);
-
-                                       break;
-                               case 'z':
-                                       // timezone. t = +/-h; tt = +/-hh; ttt+=+/-hh:mm
-                                       tokLen = DateTimeUtils.CountRepeat (format, i, ch);
-                                       TimeSpan offset = 
-                                               utc_offset ?? 
-                                               TimeZone.CurrentTimeZone.GetUtcOffset (dt);
-
-                                       if (offset.Ticks >= 0)
-                                               result.Append ('+');
-                                       else
-                                               result.Append ('-');
-
-                                       switch (tokLen) {
-                                       case 1:
-                                               result.Append (Math.Abs (offset.Hours));
-                                               break;
-                                       case 2:
-                                               result.Append (Math.Abs (offset.Hours).ToString ("00"));
-                                               break;
-                                       default:
-                                               result.Append (Math.Abs (offset.Hours).ToString ("00"));
-                                               result.Append (':');
-                                               result.Append (Math.Abs (offset.Minutes).ToString ("00"));
-                                               break;
-                                       }
-                                       break;
-                               case 'K': // 'Z' (UTC) or zzz (Local)
-                                       tokLen = 1;
-
-                                       if (utc_offset != null || dt.Kind == DateTimeKind.Local) {
-                                               offset = utc_offset ?? TimeZone.CurrentTimeZone.GetUtcOffset (dt);
-                                               if (offset.Ticks >= 0)
-                                                       result.Append ('+');
-                                               else
-                                                       result.Append ('-');
-                                               result.Append (Math.Abs (offset.Hours).ToString ("00"));
-                                               result.Append (':');
-                                               result.Append (Math.Abs (offset.Minutes).ToString ("00"));
-                                       } else if (dt.Kind == DateTimeKind.Utc)
-                                               result.Append ('Z');
-                                       break;
-                               //
-                               // Date tokens
-                               //
-                               case 'd':
-                                       // day. d(d?) = day of month (leading 0 if two d's)
-                                       // ddd = three leter day of week
-                                       // dddd+ full day-of-week
-                                       tokLen = DateTimeUtils.CountRepeat (format, i, ch);
-
-                                       if (tokLen <= 2)
-                                               DateTimeUtils.ZeroPad (result, dfi.Calendar.GetDayOfMonth (dt), tokLen == 1 ? 1 : 2);
-                                       else if (tokLen == 3)
-                                               result.Append (dfi.GetAbbreviatedDayName (dfi.Calendar.GetDayOfWeek (dt)));
-                                       else
-                                               result.Append (dfi.GetDayName (dfi.Calendar.GetDayOfWeek (dt)));
-
-                                       saw_day_specifier = true;
-                                       break;
-                               case 'M':
-                                       // Month.m(m?) = month # (with leading 0 if two mm)
-                                       // mmm = 3 letter name
-                                       // mmmm+ = full name
-                                       tokLen = DateTimeUtils.CountRepeat (format, i, ch);
-                                       int month = dfi.Calendar.GetMonth(dt);
-                                       if (tokLen <= 2)
-                                               DateTimeUtils.ZeroPad (result, month, tokLen);
-                                       else if (tokLen == 3)
-                                               result.Append (dfi.GetAbbreviatedMonthName (month));
-                                       else {
-                                               // Handles MMMM dd format
-                                               if (!saw_day_specifier) {
-                                                       for (int ii = i + 1; ii < format.Length; ++ii) {
-                                                               ch = format [ii];
-                                                               if (ch == 'd') {
-                                                                       saw_day_specifier = true;
-                                                                       break;
-                                                               }
-
-                                                               if (ch == '\'' || ch == '"') {
-                                                                       ii += ParseQuotedString (format, ii, null) - 1;
-                                                               }
-                                                       }
-                                               }
-
-                                               // NOTE: .NET ignores quoted 'd' and reads it as day specifier but I think 
-                                               // that's wrong
-                                               result.Append (saw_day_specifier ? dfi.GetMonthGenitiveName (month) : dfi.GetMonthName (month));
-                                       }
-
-                                       break;
-                               case 'y':
-                                       // Year. y(y?) = two digit year, with leading 0 if yy
-                                       // yyy+ full year with leading zeros if needed.
-                                       tokLen = DateTimeUtils.CountRepeat (format, i, ch);
-
-                                       if (tokLen <= 2)
-                                               DateTimeUtils.ZeroPad (result, dfi.Calendar.GetYear (dt) % 100, tokLen);
-                                       else
-                                               DateTimeUtils.ZeroPad (result, dfi.Calendar.GetYear (dt), tokLen);
-                                       break;
-
-                               case 'g':
-                                       // Era name
-                                       tokLen = DateTimeUtils.CountRepeat (format, i, ch);
-                                       result.Append (dfi.GetEraName (dfi.Calendar.GetEra (dt)));
-                                       break;
-
-                               //
-                               // Other
-                               //
-                               case ':':
-                                       result.Append (dfi.TimeSeparator);
-                                       tokLen = 1;
-                                       break;
-                               case '/':
-                                       result.Append (dfi.DateSeparator);
-                                       tokLen = 1;
-                                       break;
-                               case '\'': case '"':
-                                       tokLen = ParseQuotedString (format, i, result);
-                                       break;
-                               case '%':
-                                       if (i >= format.Length - 1)
-                                               throw new FormatException ("% at end of date time string");
-                                       if (format [i + 1] == '%')
-                                               throw new FormatException ("%% in date string");
-
-                                       // Look for the next char
-                                       tokLen = 1;
-                                       break;
-                               case '\\':
-                                       // C-Style escape
-                                       if (i >= format.Length - 1)
-                                               throw new FormatException ("\\ at end of date time string");
-
-                                       result.Append (format [i + 1]);
-                                       tokLen = 2;
-
-                                       break;
-                               default:
-                                       // catch all
-                                       result.Append (ch);
-                                       tokLen = 1;
-                                       break;
-                               }
-                               i += tokLen;
-                       }
-                       return result.ToString ();
-               }
-       
-       }
-}      
diff --git a/mcs/class/corlib/System/DayOfWeek.cs b/mcs/class/corlib/System/DayOfWeek.cs
deleted file mode 100644 (file)
index 3cbbce2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// System.DayOfWeek.cs
-//
-// author:
-//   Marcel Narings (marcel@narings.nl)
-//   Martin Baulig (martin@gnome.org)
-//   Atsushi Enomoto (atsushi@ximian.com)
-//
-//   (C) 2001 Marcel Narings
-// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Runtime.InteropServices;
-
-namespace System {
-
-       [ComVisible (true)]
-       [Serializable]
-       public enum DayOfWeek {
-
-               Sunday,
-               Monday,
-               Tuesday,
-               Wednesday,
-               Thursday,
-               Friday,
-               Saturday
-       }
-}
index 0a1be9fab19ebdd8e92f1f8c099039f12e5a12ae..9b764637a61ae0a2d83c1e11ed57bbc25ccded4b 100644 (file)
@@ -57,7 +57,7 @@ namespace System {
                 * of icalls, do not require an increment.
                 */
 #pragma warning disable 169
-               private const int mono_corlib_version = 116;
+               private const int mono_corlib_version = 117;
 #pragma warning restore 169
 
                [ComVisible (true)]
index f4e01b03be322cc4f832f672002573eb025517f7..61d088a6593af1fcf408f27cc668e0cbfa384bd3 100644 (file)
@@ -68,7 +68,7 @@ namespace System
                // Properties
                public static TimeZone CurrentTimeZone {
                        get {
-                               long now = DateTime.GetNow ();
+                               long now = DateTime.UtcNow.Ticks;
                                TimeZone tz = currentTimeZone;
                                
                                lock (tz_lock) {
index c07e7425a73b08aa97183a2ebe39306172a4f1cb..6d74bb6583437b7ac1b93d20906e78ba7c4fed6d 100644 (file)
@@ -34,6 +34,7 @@ using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Runtime.Serialization;
 using System.Text;
+using System.Globalization;
 
 #if LIBC || MONODROID
 using System.IO;
@@ -341,19 +342,31 @@ namespace System
                        return ConvertTimeToUtc (dateTime, TimeZoneInfo.Local);
                }
 
+               static internal DateTime ConvertTimeToUtc(DateTime dateTime, TimeZoneInfoOptions flags)
+               {
+                       return ConvertTimeToUtc (dateTime, TimeZoneInfo.Local, flags);
+               }
+
                public static DateTime ConvertTimeToUtc (DateTime dateTime, TimeZoneInfo sourceTimeZone)
                {
-                       if (sourceTimeZone == null)
-                               throw new ArgumentNullException ("sourceTimeZone");
+                       return ConvertTimeToUtc (dateTime, sourceTimeZone, TimeZoneInfoOptions.None);
+               }
 
-                       if (dateTime.Kind == DateTimeKind.Utc && sourceTimeZone != TimeZoneInfo.Utc)
-                               throw new ArgumentException ("Kind property of dateTime is Utc but the sourceTimeZone does not equal TimeZoneInfo.Utc");
+               static DateTime ConvertTimeToUtc (DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfoOptions flags)
+               {
+                       if ((flags & TimeZoneInfoOptions.NoThrowOnInvalidTime) == 0) {
+                               if (sourceTimeZone == null)
+                                       throw new ArgumentNullException ("sourceTimeZone");
 
-                       if (dateTime.Kind == DateTimeKind.Local && sourceTimeZone != TimeZoneInfo.Local)
-                               throw new ArgumentException ("Kind property of dateTime is Local but the sourceTimeZone does not equal TimeZoneInfo.Local");
+                               if (dateTime.Kind == DateTimeKind.Utc && sourceTimeZone != TimeZoneInfo.Utc)
+                                       throw new ArgumentException ("Kind property of dateTime is Utc but the sourceTimeZone does not equal TimeZoneInfo.Utc");
 
-                       if (sourceTimeZone.IsInvalidTime (dateTime))
-                               throw new ArgumentException ("dateTime parameter is an invalid time");
+                               if (dateTime.Kind == DateTimeKind.Local && sourceTimeZone != TimeZoneInfo.Local)
+                                       throw new ArgumentException ("Kind property of dateTime is Local but the sourceTimeZone does not equal TimeZoneInfo.Local");
+
+                               if (sourceTimeZone.IsInvalidTime (dateTime))
+                                       throw new ArgumentException ("dateTime parameter is an invalid time");
+                       }
 
                        if (dateTime.Kind == DateTimeKind.Utc)
                                return dateTime;
@@ -369,6 +382,12 @@ namespace System
                        }
                }
 
+               static internal TimeSpan GetDateTimeNowUtcOffsetFromUtc(DateTime time, out Boolean isAmbiguousLocalDst)
+               {
+                       bool isDaylightSavings;
+                       return GetUtcOffsetFromUtc(time, TimeZoneInfo.Local, out isDaylightSavings, out isAmbiguousLocalDst);
+               }
+
                public static TimeZoneInfo CreateCustomTimeZone (string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName) 
                {
                        return CreateCustomTimeZone (id, baseUtcOffset, displayName, standardDisplayName, null, null, true);
@@ -853,26 +872,14 @@ namespace System
                        return isDst;
                }
 
-               public bool IsDaylightSavingTime (DateTimeOffset dateTimeOffset)
+               internal bool IsDaylightSavingTime (DateTime dateTime, TimeZoneInfoOptions flags)
                {
-                       throw new NotImplementedException ();
+                       return IsDaylightSavingTime (dateTime);
                }
 
-               public bool IsInvalidTime (DateTime dateTime)
+               public bool IsDaylightSavingTime (DateTimeOffset dateTimeOffset)
                {
-                       if (dateTime.Kind == DateTimeKind.Utc)
-                               return false;
-                       if (dateTime.Kind == DateTimeKind.Local && this != Local)
-                               return false;
-
-                       AdjustmentRule rule = GetApplicableRule (dateTime);
-                       if (rule != null) {
-                               DateTime tpoint = TransitionPoint (rule.DaylightTransitionStart, dateTime.Year);
-                               if (dateTime >= tpoint && dateTime < tpoint + rule.DaylightDelta)
-                                       return true;
-                       }
-                               
-                       return false;
+                       throw new NotImplementedException ();
                }
 
                void IDeserializationCallback.OnDeserialization (object sender)
@@ -1287,10 +1294,320 @@ namespace System
             return GetUtcOffset (dateTime, out dst);
         }
 
-        static internal TimeSpan GetUtcOffsetFromUtc(DateTime time, TimeZoneInfo zone, out Boolean isDaylightSavings, out Boolean isAmbiguousLocalDst)
+        // used by GetUtcOffsetFromUtc (DateTime.Now, DateTime.ToLocalTime) for max/min whole-day range checks
+        private static DateTime s_maxDateOnly = new DateTime(9999, 12, 31);
+        private static DateTime s_minDateOnly = new DateTime(1, 1, 2);
+
+        static internal TimeSpan GetUtcOffsetFromUtc (DateTime time, TimeZoneInfo zone, out Boolean isDaylightSavings, out Boolean isAmbiguousLocalDst)
         {
-               throw new NotImplementedException ();
+            isDaylightSavings = false;
+            isAmbiguousLocalDst = false;
+            TimeSpan baseOffset = zone.BaseUtcOffset;
+            Int32 year;
+            AdjustmentRule rule;
+
+            if (time > s_maxDateOnly) {
+                rule = zone.GetAdjustmentRuleForTime(DateTime.MaxValue);
+                year = 9999;
+            }
+            else if (time < s_minDateOnly) {
+                rule = zone.GetAdjustmentRuleForTime(DateTime.MinValue);
+                year = 1;
+            }
+            else {
+                DateTime targetTime = time + baseOffset;
+                year = time.Year;
+                rule = zone.GetAdjustmentRuleForTime(targetTime);
+            }
+
+            if (rule != null) {
+                isDaylightSavings = GetIsDaylightSavingsFromUtc(time, year, zone.baseUtcOffset, rule, out isAmbiguousLocalDst);
+                baseOffset += (isDaylightSavings ? rule.DaylightDelta : TimeSpan.Zero /* */);
+            }
+
+            return baseOffset;
+        }
+
+        // assumes dateTime is in the current time zone's time
+        private AdjustmentRule GetAdjustmentRuleForTime(DateTime dateTime) {
+            if (adjustmentRules == null || adjustmentRules.Length == 0) {
+                return null;
+            }
+
+#if WINXP_AND_WIN2K3_SUPPORT
+            // On pre-Vista versions of Windows if you run "cmd /c date" or "cmd /c time" to update the system time
+            // the operating system doesn't pick up the correct time zone adjustment rule (it stays on the currently loaded rule).
+            // We need to use the OS API data in this scenario instead of the loaded adjustment rules from the registry for
+            // consistency.  Otherwise DateTime.Now might not match the time displayed in the system tray.              
+            if (!Environment.IsWindowsVistaOrAbove && s_cachedData.GetCorrespondingKind(this) == DateTimeKind.Local) {
+                return s_cachedData.GetOneYearLocalFromLocal(dateTime.Year).rule;
+            }
+#endif
+            // Only check the whole-date portion of the dateTime -
+            // This is because the AdjustmentRule DateStart & DateEnd are stored as
+            // Date-only values {4/2/2006 - 10/28/2006} but actually represent the
+            // time span {4/2/2006@00:00:00.00000 - 10/28/2006@23:59:59.99999}
+            DateTime date = dateTime.Date;
+
+            for (int i = 0; i < adjustmentRules.Length; i++) {
+                if (adjustmentRules[i].DateStart <= date && adjustmentRules[i].DateEnd >= date) {
+                    return adjustmentRules[i];
+                }
+            }
+
+            return null;
+        }
+
+        //
+        // GetIsDaylightSavingsFromUtc -
+        //
+        // Helper function that checks if a given dateTime is in Daylight Saving Time (DST)
+        // This function assumes the dateTime is in UTC and AdjustmentRule is in a different time zone
+        //
+        static private Boolean GetIsDaylightSavingsFromUtc(DateTime time, Int32 Year, TimeSpan utc, AdjustmentRule rule, out Boolean isAmbiguousLocalDst) {
+            isAmbiguousLocalDst = false;
+
+            if (rule == null) {
+                return false;
+            }
+
+            // Get the daylight changes for the year of the specified time.
+            TimeSpan offset = utc; /* */
+            DaylightTime daylightTime = GetDaylightTime(Year, rule);
+
+            // The start and end times represent the range of universal times that are in DST for that year.                
+            // Within that there is an ambiguous hour, usually right at the end, but at the beginning in
+            // the unusual case of a negative daylight savings delta.
+            DateTime startTime = daylightTime.Start - offset;
+            DateTime endTime = daylightTime.End - offset - rule.DaylightDelta; /* */
+            DateTime ambiguousStart;
+            DateTime ambiguousEnd;
+            if (daylightTime.Delta.Ticks > 0) {
+                ambiguousStart = endTime - daylightTime.Delta;
+                ambiguousEnd = endTime;
+            } else {
+                ambiguousStart = startTime;
+                ambiguousEnd = startTime - daylightTime.Delta;
+            }
+
+            Boolean isDst = CheckIsDst(startTime, time, endTime);
+
+            // See if the resulting local time becomes ambiguous. This must be captured here or the
+            // DateTime will not be able to round-trip back to UTC accurately.
+            if (isDst) {
+                isAmbiguousLocalDst = (time >= ambiguousStart && time < ambiguousEnd);
+
+                if (!isAmbiguousLocalDst && ambiguousStart.Year != ambiguousEnd.Year) {
+                    // there exists an extreme corner case where the start or end period is on a year boundary and
+                    // because of this the comparison above might have been performed for a year-early or a year-later
+                    // than it should have been.
+                    DateTime ambiguousStartModified;
+                    DateTime ambiguousEndModified;
+                    try {
+                        ambiguousStartModified = ambiguousStart.AddYears(1);
+                        ambiguousEndModified   = ambiguousEnd.AddYears(1);
+                        isAmbiguousLocalDst = (time >= ambiguousStart && time < ambiguousEnd); 
+                    }
+                    catch (ArgumentOutOfRangeException) {}
+
+                    if (!isAmbiguousLocalDst) {
+                        try {
+                            ambiguousStartModified = ambiguousStart.AddYears(-1);
+                            ambiguousEndModified   = ambiguousEnd.AddYears(-1);
+                            isAmbiguousLocalDst = (time >= ambiguousStart && time < ambiguousEnd);
+                        }
+                        catch (ArgumentOutOfRangeException) {}
+                    }
+
+                }
+            }
+
+            return isDst;
+        }
+
+
+        static private Boolean CheckIsDst(DateTime startTime, DateTime time, DateTime endTime) {
+            Boolean isDst;
+
+            int startTimeYear = startTime.Year;
+            int endTimeYear = endTime.Year;
+
+            if (startTimeYear != endTimeYear) {
+                endTime = endTime.AddYears(startTimeYear - endTimeYear);
+            }
+
+            int timeYear = time.Year;
+
+            if (startTimeYear != timeYear) {
+                time = time.AddYears(startTimeYear - timeYear);
+            }
+
+            if (startTime > endTime) {
+                // In southern hemisphere, the daylight saving time starts later in the year, and ends in the beginning of next year.
+                // Note, the summer in the southern hemisphere begins late in the year.
+                isDst = (time < endTime || time >= startTime);
+            }
+            else {
+                // In northern hemisphere, the daylight saving time starts in the middle of the year.
+                isDst = (time >= startTime && time < endTime);
+            }
+            return isDst;
         }
+
+        //
+        // GetDaylightTime -
+        //
+        // Helper function that returns a DaylightTime from a year and AdjustmentRule
+        //
+        static private DaylightTime GetDaylightTime(Int32 year, AdjustmentRule rule) {
+            TimeSpan delta = rule.DaylightDelta;
+            DateTime startTime = TransitionTimeToDateTime(year, rule.DaylightTransitionStart);
+            DateTime endTime = TransitionTimeToDateTime(year, rule.DaylightTransitionEnd);
+            return new DaylightTime(startTime, endTime, delta);
+        }
+
+        //
+        // TransitionTimeToDateTime -
+        //
+        // Helper function that converts a year and TransitionTime into a DateTime
+        //
+        static private DateTime TransitionTimeToDateTime(Int32 year, TransitionTime transitionTime) {
+            DateTime value;
+            DateTime timeOfDay = transitionTime.TimeOfDay;
+
+            if (transitionTime.IsFixedDateRule) {
+                // create a DateTime from the passed in year and the properties on the transitionTime
+
+                // if the day is out of range for the month then use the last day of the month
+                Int32 day = DateTime.DaysInMonth(year, transitionTime.Month);
+
+                value = new DateTime(year, transitionTime.Month, (day < transitionTime.Day) ? day : transitionTime.Day, 
+                            timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond);
+            }
+            else {
+                if (transitionTime.Week <= 4) {
+                    //
+                    // Get the (transitionTime.Week)th Sunday.
+                    //
+                    value = new DateTime(year, transitionTime.Month, 1,
+                            timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond);
+
+                    int dayOfWeek = (int)value.DayOfWeek;
+                    int delta = (int)transitionTime.DayOfWeek - dayOfWeek;
+                    if (delta < 0) {
+                        delta += 7;
+                    }
+                    delta += 7 * (transitionTime.Week - 1);
+
+                    if (delta > 0) {
+                        value = value.AddDays(delta);
+                    }
+                }
+                else {
+                    //
+                    // If TransitionWeek is greater than 4, we will get the last week.
+                    //
+                    Int32 daysInMonth = DateTime.DaysInMonth(year, transitionTime.Month);
+                    value = new DateTime(year, transitionTime.Month, daysInMonth,
+                            timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond);
+
+                    // This is the day of week for the last day of the month.
+                    int dayOfWeek = (int)value.DayOfWeek;
+                    int delta = dayOfWeek - (int)transitionTime.DayOfWeek;
+                    if (delta < 0) {
+                        delta += 7;
+                    }
+
+                    if (delta > 0) {
+                        value = value.AddDays(-delta);
+                    }
+                }
+            }
+            return value;
+        }
+
+        //
+        // IsInvalidTime -
+        //
+        // returns true when dateTime falls into a "hole in time".
+        //
+        public Boolean IsInvalidTime(DateTime dateTime) {
+            Boolean isInvalid = false;
+          
+            if ( (dateTime.Kind == DateTimeKind.Unspecified)
+            ||   (dateTime.Kind == DateTimeKind.Local && this == Local) ) {
+
+                // only check Unspecified and (Local when this TimeZoneInfo instance is Local)
+                AdjustmentRule rule = GetAdjustmentRuleForTime(dateTime);
+
+
+                if (rule != null) {
+                    DaylightTime daylightTime = GetDaylightTime(dateTime.Year, rule);
+                    isInvalid = GetIsInvalidTime(dateTime, rule, daylightTime);
+                }
+                else {
+                    isInvalid = false;
+                }
+            }
+
+            return isInvalid;
+        }
+
+        //
+        // GetIsInvalidTime -
+        //
+        // Helper function that checks if a given DateTime is in an invalid time ("time hole")
+        // A "time hole" occurs at a DST transition point when time jumps forward;
+        // For example, in Pacific Standard Time on Sunday, April 2, 2006 time jumps from
+        // 1:59:59.9999999 to 3AM.  The time range 2AM to 2:59:59.9999999AM is the "time hole".
+        // A "time hole" is not limited to only occurring at the start of DST, and may occur at
+        // the end of DST as well.
+        //
+        static private Boolean GetIsInvalidTime(DateTime time, AdjustmentRule rule, DaylightTime daylightTime) {
+            Boolean isInvalid = false;
+            if (rule == null || rule.DaylightDelta == TimeSpan.Zero) {
+                return isInvalid;
+            }
+
+            DateTime startInvalidTime;
+            DateTime endInvalidTime;
+
+            // if at DST start we transition forward in time then there is an ambiguous time range at the DST end
+            if (rule.DaylightDelta < TimeSpan.Zero) {
+                startInvalidTime = daylightTime.End;
+                endInvalidTime = daylightTime.End - rule.DaylightDelta; /* */
+            }
+            else {
+                startInvalidTime = daylightTime.Start;
+                endInvalidTime = daylightTime.Start + rule.DaylightDelta; /* */
+            }
+
+            isInvalid = (time >= startInvalidTime && time < endInvalidTime);
+
+            if (!isInvalid && startInvalidTime.Year != endInvalidTime.Year) {
+                // there exists an extreme corner case where the start or end period is on a year boundary and
+                // because of this the comparison above might have been performed for a year-early or a year-later
+                // than it should have been.
+                DateTime startModifiedInvalidTime;
+                DateTime endModifiedInvalidTime;
+                try {
+                    startModifiedInvalidTime = startInvalidTime.AddYears(1);
+                    endModifiedInvalidTime   = endInvalidTime.AddYears(1);
+                    isInvalid = (time >= startModifiedInvalidTime && time < endModifiedInvalidTime);
+                }
+                catch (ArgumentOutOfRangeException) {}
+
+                if (!isInvalid) {
+                    try {
+                        startModifiedInvalidTime = startInvalidTime.AddYears(-1);
+                        endModifiedInvalidTime  = endInvalidTime.AddYears(-1);
+                        isInvalid = (time >= startModifiedInvalidTime && time < endModifiedInvalidTime);
+                    }
+                    catch (ArgumentOutOfRangeException) {}
+                }
+            }
+            return isInvalid;
+        } 
 #endregion
        }
 
index 8c3e44920f2a83c17adb3fad3446892fe36c64a9..703b6262c21a218184f059b43417623b1d479122 100644 (file)
@@ -132,10 +132,6 @@ System/ContextStaticAttribute.cs
 System/ControlCharacters.cs
 System/CrossAppDomainDelegate.cs
 System/DataMisalignedException.cs
-System/DateTime.cs
-System/DateTimeKind.cs
-System/DateTimeUtils.cs
-System/DayOfWeek.cs
 System/DBNull.cs
 System/Decimal.cs
 System/Delegate.cs
@@ -334,7 +330,6 @@ System.Globalization/CultureNotFoundException.cs
 System.Globalization/CultureTypes.cs
 System.Globalization/DateTimeFormatInfo.cs
 System.Globalization/DateTimeStyles.cs
-System.Globalization/DaylightTime.cs
 System.Globalization/DigitShapes.cs
 System.Globalization/GregorianCalendarTypes.cs
 System.Globalization/IdnMapping.cs
@@ -1437,7 +1432,6 @@ System.Threading.Tasks/TaskConstants_T.cs
 System.Collections.Concurrent/ConcurrentOrderedList.cs
 ../Mono.Parallel/Mono.Threading/AtomicBoolean.cs
 System.Threading/ThreadLocal.cs
-System.Threading/Watch.cs
 
 ReferenceSources/Array.cs
 ReferenceSources/BCLDebug.cs
@@ -1460,7 +1454,10 @@ ReferenceSources/JitHelpers.cs
 ../../../external/referencesource/mscorlib/system/byte.cs
 ../../../external/referencesource/mscorlib/system/char.cs
 ../../../external/referencesource/mscorlib/system/convert.cs
+../../../external/referencesource/mscorlib/system/datetime.cs
+../../../external/referencesource/mscorlib/system/datetimekind.cs
 ../../../external/referencesource/mscorlib/system/datetimeoffset.cs
+../../../external/referencesource/mscorlib/system/dayofweek.cs
 ../../../external/referencesource/mscorlib/system/int16.cs
 ../../../external/referencesource/mscorlib/system/int32.cs
 ../../../external/referencesource/mscorlib/system/int64.cs
@@ -1547,6 +1544,7 @@ ReferenceSources/JitHelpers.cs
 ../../../external/referencesource/mscorlib/system/globalization/calendar.cs
 ../../../external/referencesource/mscorlib/system/globalization/calendardata.cs
 ../../../external/referencesource/mscorlib/system/globalization/chineselunisolarcalendar.cs
+../../../external/referencesource/mscorlib/system/globalization/daylighttime.cs
 ../../../external/referencesource/mscorlib/system/globalization/datetimeformat.cs
 ../../../external/referencesource/mscorlib/system/globalization/datetimeformatinfo.cs
 ../../../external/referencesource/mscorlib/system/globalization/datetimeformatinfoscanner.cs
index 7df8e30ce2c9ec279344d48d7a552b789210776e..7bedd8b02d9493807f79fd3810a8ea84bc2a7e3e 100644 (file)
@@ -78,7 +78,7 @@
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 116
+#define MONO_CORLIB_VERSION 117
 
 typedef struct
 {
index 09281bde8c3db8ad81c03e89094416189f653ee9..5b23d7223d9d39d8b5c28bb86e8cfbe94ac19141 100644 (file)
@@ -138,8 +138,7 @@ ICALL_TYPE(TZONE, "System.CurrentSystemTimeZone", TZONE_1)
 ICALL(TZONE_1, "GetTimeZoneData", ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData)
 
 ICALL_TYPE(DTIME, "System.DateTime", DTIME_1)
-ICALL(DTIME_1, "GetNow", mono_100ns_datetime)
-ICALL(DTIME_2, "GetTimeMonotonic", mono_100ns_ticks)
+ICALL(DTIME_1, "GetSystemTimeAsFileTime", mono_100ns_datetime)
 
 #ifndef DISABLE_DECIMAL
 ICALL_TYPE(DECIMAL, "System.Decimal", DECIMAL_1)
@@ -929,6 +928,9 @@ ICALL(THREADP_35, "SetMaxThreads", ves_icall_System_Threading_ThreadPool_SetMaxT
 ICALL(THREADP_4, "SetMinThreads", ves_icall_System_Threading_ThreadPool_SetMinThreads)
 ICALL(THREADP_5, "pool_queue", icall_append_job)
 
+ICALL_TYPE(TTIMER, "System.Threading.Timer", TTIMER_1)
+ICALL(TTIMER_1, "GetTimeMonotonic", mono_100ns_ticks)
+
 ICALL_TYPE(VOLATILE, "System.Threading.Volatile", VOLATILE_28)
 ICALL(VOLATILE_28, "Read(T&)", ves_icall_System_Threading_Volatile_Read_T)
 ICALL(VOLATILE_1, "Read(bool&)", ves_icall_System_Threading_Volatile_Read1)
index 30fe621b6f3ee6ddb58fac746284a3d3c068ae50..cd347546c207d8b6e72590fcec8060960cd522fd 100644 (file)
@@ -41,12 +41,7 @@ mono_100ns_ticks (void)
        return (cur_time - start_time) * (double)MTICKS_PER_SEC / freq.QuadPart;
 }
 
-/*
- * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
- */
-#define FILETIME_ADJUST ((guint64)504911232000000000LL)
-
-/* Returns the number of 100ns ticks since 1/1/1, UTC timezone */
+/* Returns the number of 100ns ticks since Jan 1, 1601, UTC timezone */
 gint64
 mono_100ns_datetime (void)
 {
@@ -56,7 +51,7 @@ mono_100ns_datetime (void)
                g_assert_not_reached ();
 
        GetSystemTimeAsFileTime ((FILETIME*) &ft);
-       return FILETIME_ADJUST + ft.QuadPart;
+       return ft.QuadPart;
 }
 
 #else
@@ -162,12 +157,12 @@ mono_100ns_ticks (void)
 }
 
 /*
- * Magic number to convert a time which is relative to
- * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
+ * Magic number to convert unix epoch start to windows epoch start
+ * Jan 1, 1970 into a value which is relative to Jan 1, 1601.
  */
-#define EPOCH_ADJUST    ((guint64)62135596800LL)
+#define EPOCH_ADJUST    ((guint64)11644473600LL)
 
-/* Returns the number of 100ns ticks since 1/1/1, UTC timezone */
+/* Returns the number of 100ns ticks since 1/1/1601, UTC timezone */
 gint64
 mono_100ns_datetime (void)
 {