Author: miguel
Date: 2006-11-22 19:10:10 -0500 (Wed, 22 Nov 2006)
New Revision: 68376

Modified:
   trunk/mcs/class/corlib/System/ChangeLog
   trunk/mcs/class/corlib/System/DateTime.cs
   trunk/mcs/class/corlib/System/TimeZone.cs
Log:
2006-11-21  Miguel de Icaza  <[EMAIL PROTECTED]>

        * TimeZone.cs (CurrentSystemTimeZone): Cache the current year
        daylight savings time in static variables.

        (CurrentSystemTimeZone.OnDeserialization): Initialize
        this_year_dlt and this_year on this method.

        (TimeZone): init statically the currentTimeZone instead of
        delaying that to the static property, avoiding a compare. 



Modified: trunk/mcs/class/corlib/System/ChangeLog
===================================================================
--- trunk/mcs/class/corlib/System/ChangeLog     2006-11-22 23:44:28 UTC (rev 
68375)
+++ trunk/mcs/class/corlib/System/ChangeLog     2006-11-23 00:10:10 UTC (rev 
68376)
@@ -1,3 +1,14 @@
+2006-11-21  Miguel de Icaza  <[EMAIL PROTECTED]>
+
+       * TimeZone.cs (CurrentSystemTimeZone): Cache the current year
+       daylight savings time in static variables.
+
+       (CurrentSystemTimeZone.OnDeserialization): Initialize
+       this_year_dlt and this_year on this method.
+
+       (TimeZone): init statically the currentTimeZone instead of
+       delaying that to the static property, avoiding a compare. 
+
 2006-11-22  Lluis Sanchez Gual  <[EMAIL PROTECTED]>
 
        * Array.cs: (compare<T>) if a comparer is provided, it has

Modified: trunk/mcs/class/corlib/System/DateTime.cs
===================================================================
--- trunk/mcs/class/corlib/System/DateTime.cs   2006-11-22 23:44:28 UTC (rev 
68375)
+++ trunk/mcs/class/corlib/System/DateTime.cs   2006-11-23 00:10:10 UTC (rev 
68376)
@@ -417,11 +417,28 @@
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                internal static extern long GetNow ();
 
+               //
+               // 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 TimeSpan to_local_time_span;
+               static long last_now;
+               
                public static DateTime Now 
                {
                        get     
                        {
-                               return new DateTime (GetNow ()).ToLocalTime ();
+                               long now = GetNow ();
+                               DateTime dt = new DateTime (now);
+                               
+                               if ((now - last_now) > TimeSpan.TicksPerMinute){
+                                       to_local_time_span = 
TimeZone.CurrentTimeZone.GetLocalTimeDiff (dt);
+                                       last_now = now;
+
+                               }
+                               return dt + to_local_time_span;
                        }
                }
 

Modified: trunk/mcs/class/corlib/System/TimeZone.cs
===================================================================
--- trunk/mcs/class/corlib/System/TimeZone.cs   2006-11-22 23:44:28 UTC (rev 
68375)
+++ trunk/mcs/class/corlib/System/TimeZone.cs   2006-11-23 00:10:10 UTC (rev 
68376)
@@ -7,7 +7,7 @@
 //   Martin Baulig ([EMAIL PROTECTED])
 //
 // (C) Ximian, Inc.
-// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2006 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
@@ -28,7 +28,17 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-
+//
+// TODO:
+//
+//    Rewrite ToLocalTime to use GetLocalTimeDiff(DateTime,TimeSpan),
+//    this should only leave the validation at the beginning (for MaxValue)
+//    and then call the helper function.  This would remove all the
+//    ifdefs in that code, and replace it with only one, for the construction
+//    of the object.
+//
+//    Rewrite ToUniversalTime to use a similar setup to that
+//
 using System.Collections;
 using System.Globalization;
 using System.Runtime.CompilerServices;
@@ -40,7 +50,7 @@
        public abstract class TimeZone
        {
                // Fields
-               private static TimeZone currentTimeZone;
+               private static TimeZone currentTimeZone = new 
CurrentSystemTimeZone (DateTime.GetNow ());
 
                // Constructor
                protected TimeZone ()
@@ -50,19 +60,10 @@
                // Properties
                public static TimeZone CurrentTimeZone {
                        get {
-                               if (currentTimeZone == null) {
-                                       DateTime now = new DateTime 
(DateTime.GetNow ());
-                                       currentTimeZone = new 
CurrentSystemTimeZone (now);
-                               }
                                return currentTimeZone;
                        }
                }
 
-               internal static void ClearCurrentTimeZone ()
-               {
-                       currentTimeZone = null;
-               }
-
                public abstract string DaylightName {
                        get;
                }
@@ -112,7 +113,6 @@
                                return time;
 #endif
 
-                       DaylightTime dlt = GetDaylightChanges (time.Year);
                        TimeSpan utcOffset = GetUtcOffset (time);
                        if (utcOffset.Ticks > 0) {
                                if (DateTime.MaxValue - utcOffset < time)
@@ -127,6 +127,7 @@
                        }
 
                        DateTime local = time.Add (utcOffset);
+                       DaylightTime dlt = GetDaylightChanges (time.Year);
                        if (dlt.Delta.Ticks == 0)
 #if NET_2_0
                                return DateTime.SpecifyKind (local, 
DateTimeKind.Local);
@@ -192,6 +193,62 @@
                        return new DateTime (time.Ticks - offset.Ticks);
 #endif         
                }
+
+               //
+               // This routine returns the TimeDiff that would have to be
+               // added to "time" to turn it into a local time.   This would
+               // be equivalent to call ToLocalTime.
+               //
+               // There is one important consideration:
+               //
+               //    This information is only valid during the minute it
+               //    was called.
+               //
+               //    This only works with a real time, not one of the boundary
+               //    cases like DateTime.MaxValue, so validation must be done
+               //    before.
+               // 
+               //    This is intended to be used by DateTime.Now
+               //
+               // We use a minute, just to be conservative and cope with
+               // any potential time zones that might be defined in the future
+               // that might not nicely fit in hour or half-hour steps. 
+               //    
+               internal TimeSpan GetLocalTimeDiff (DateTime time)
+               {
+                       return GetLocalTimeDiff (time, GetUtcOffset (time));
+               }
+
+               //
+               // This routine is intended to be called by 
GetLocalTimeDiff(DatetTime)
+               // or by ToLocalTime after validation has been performed
+               //
+               // time is the time to map, utc_offset is the utc_offset that
+               // has been computed for calling GetUtcOffset on time.
+               //
+               // When called by GetLocalTime, utc_offset is assumed to come
+               // from a time constructed by new DateTime (DateTime.GetNow 
()), that
+               // is a valid time.
+               //
+               // When called by ToLocalTime ranges are checked before this is
+               // called.
+               //
+               internal TimeSpan GetLocalTimeDiff (DateTime time, TimeSpan 
utc_offset)
+               {
+                       DaylightTime dlt = GetDaylightChanges (time.Year);
+
+                       if (dlt.Delta.Ticks == 0)
+                               return utc_offset;
+
+                       DateTime local = time.Add (utc_offset);
+                       if (local < dlt.End && dlt.End.Subtract (dlt.Delta) <= 
local)
+                               return utc_offset;
+
+                       if (local >= dlt.Start && dlt.Start.Add (dlt.Delta) > 
local)
+                               return utc_offset - dlt.Delta;
+
+                       return GetUtcOffset (local);
+               }
        }
 
        [Serializable]
@@ -244,11 +301,23 @@
                {
                }
 
-               internal CurrentSystemTimeZone (DateTime now)
+               //
+               // Initialized by the constructor
+               //
+               static int this_year;
+               static DaylightTime this_year_dlt;
+               
+               //
+               // The "lnow" parameter must be the current time, I could have 
moved
+               // the code here, but I do not want to interfere with 
serialization
+               // which is why I kept the other constructor around
+               //
+               internal CurrentSystemTimeZone (long lnow)
                {
                        Int64[] data;
                        string[] names;
 
+                       DateTime now = new DateTime (lnow);
                        if (!GetTimeZoneData (now.Year, out data, out names))
                                throw new NotSupportedException (Locale.GetText 
("Can't get timezone name."));
 
@@ -279,6 +348,13 @@
                                throw new ArgumentOutOfRangeException ("year", 
year +
                                        Locale.GetText (" is not in a range 
between 1 and 9999."));
 
+                       //
+                       // First we try the case for this year, very common, 
and is used
+                       // by DateTime.Now (a popular call) indirectly.
+                       //
+                       if (year == this_year)
+                               return this_year_dlt;
+                       
                        lock (m_CachedDaylightChanges) {
                                DaylightTime dlt = (DaylightTime) 
m_CachedDaylightChanges [year];
                                if (dlt == null) {
@@ -314,13 +390,16 @@
                                Int64[] data;
                                string[] names;
 
-                               int year = DateTime.Now.Year;
-                               if (!GetTimeZoneData (year, out data, out 
names))
-                                       throw new ArgumentException 
(Locale.GetText ("Can't get timezone data for " + year));
+                               this_year = DateTime.Now.Year;
+                               if (!GetTimeZoneData (this_year, out data, out 
names))
+                                       throw new ArgumentException 
(Locale.GetText ("Can't get timezone data for " + this_year));
                                dlt = GetDaylightTimeFromData (data);
-                       }
+                       } else
+                               this_year = dlt.Start.Year;
+                       
                        utcOffsetWithOutDLS = new TimeSpan (m_ticksOffset);
                        utcOffsetWithDLS = new TimeSpan (m_ticksOffset + 
dlt.Delta.Ticks);
+                       this_year_dlt = dlt;
                }
 
                private DaylightTime GetDaylightTimeFromData (long[] data)
@@ -329,5 +408,6 @@
                                new DateTime 
(data[(int)TimeZoneData.DaylightSavingEndIdx]),
                                new TimeSpan 
(data[(int)TimeZoneData.AdditionalDaylightOffsetIdx]));
                }
+
        }
 }

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

Reply via email to