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