Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mcs/class
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@gnome.org>2010-06-19 03:38:07 +0400
committerMiguel de Icaza <miguel@gnome.org>2010-06-19 03:38:07 +0400
commitb433a909ab4658cd1c0f5cea95f89094ae26c696 (patch)
tree83faccc0237e4877952a4180359e3548e3949799 /mcs/class
parent5e585590bbf5d7c05497b948556becf277719d21 (diff)
Backport
svn path=/branches/mono-2-6/mcs/; revision=159164
Diffstat (limited to 'mcs/class')
-rw-r--r--mcs/class/System.Core/System/TimeZoneInfo.cs170
1 files changed, 155 insertions, 15 deletions
diff --git a/mcs/class/System.Core/System/TimeZoneInfo.cs b/mcs/class/System.Core/System/TimeZoneInfo.cs
index d5e77e89709..0f5889ed958 100644
--- a/mcs/class/System.Core/System/TimeZoneInfo.cs
+++ b/mcs/class/System.Core/System/TimeZoneInfo.cs
@@ -43,6 +43,8 @@ using System.IO;
using Mono;
#endif
+using Microsoft.Win32;
+
namespace System
{
#if NET_4_0 || BOOTSRAP_NET_4_0
@@ -131,6 +133,23 @@ namespace System
#endif
private AdjustmentRule [] adjustmentRules;
+ static RegistryKey timeZoneKey = null;
+ static bool timeZoneKeySet = false;
+ static RegistryKey TimeZoneKey {
+ get {
+ if (!timeZoneKeySet) {
+ int p = (int) Environment.OSVersion.Platform;
+ /* Only use the registry on non-Unix platforms. */
+ if ((p != 4) && (p != 6) && (p != 128))
+ timeZoneKey = Registry.LocalMachine.OpenSubKey (
+ "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
+ false);
+ timeZoneKeySet = true;
+ }
+ return timeZoneKey;
+ }
+ }
+
public static void ClearCachedData ()
{
local = null;
@@ -288,6 +307,13 @@ namespace System
//FIXME: this method should check for cached values in systemTimeZones
if (id == null)
throw new ArgumentNullException ("id");
+ if (TimeZoneKey != null)
+ {
+ RegistryKey key = TimeZoneKey.OpenSubKey (id, false);
+ if (key == null)
+ throw new TimeZoneNotFoundException ();
+ return FromRegistryKey(id, key);
+ }
#if LIBC
string filepath = Path.Combine (TimeZoneDirectory, id);
return FindSystemTimeZoneByFileName (id, filepath);
@@ -320,6 +346,110 @@ namespace System
}
#endif
+ private static TimeZoneInfo FromRegistryKey (string id, RegistryKey key)
+ {
+ byte [] reg_tzi = (byte []) key.GetValue ("TZI");
+
+ if (reg_tzi == null)
+ throw new InvalidTimeZoneException ();
+
+ int bias = BitConverter.ToInt32 (reg_tzi, 0);
+ TimeSpan baseUtcOffset = new TimeSpan (0, -bias, 0);
+
+ string display_name = (string) key.GetValue ("Display");
+ string standard_name = (string) key.GetValue ("Std");
+ string daylight_name = (string) key.GetValue ("Dlt");
+
+ List<AdjustmentRule> adjustmentRules = new List<AdjustmentRule> ();
+
+ RegistryKey dst_key = key.OpenSubKey ("Dynamic DST", false);
+ if (dst_key != null) {
+ int first_year = (int) dst_key.GetValue ("FirstEntry");
+ int last_year = (int) dst_key.GetValue ("LastEntry");
+ int year;
+
+ for (year=first_year; year<=last_year; year++) {
+ byte [] dst_tzi = (byte []) dst_key.GetValue (year.ToString ());
+ if (dst_tzi != null) {
+ int start_year = year == first_year ? 1 : year;
+ int end_year = year == last_year ? 9999 : year;
+ ParseRegTzi(adjustmentRules, start_year, end_year, dst_tzi);
+ }
+ }
+ }
+ else
+ ParseRegTzi(adjustmentRules, 1, 9999, reg_tzi);
+
+ return CreateCustomTimeZone (id, baseUtcOffset, display_name, standard_name, daylight_name, ValidateRules (adjustmentRules).ToArray ());
+ }
+
+ private static void ParseRegTzi (List<AdjustmentRule> adjustmentRules, int start_year, int end_year, byte [] buffer)
+ {
+ //int standard_bias = BitConverter.ToInt32 (buffer, 4); /* not sure how to handle this */
+ int daylight_bias = BitConverter.ToInt32 (buffer, 8);
+
+ int standard_year = BitConverter.ToInt16 (buffer, 12);
+ int standard_month = BitConverter.ToInt16 (buffer, 14);
+ int standard_dayofweek = BitConverter.ToInt16 (buffer, 16);
+ int standard_day = BitConverter.ToInt16 (buffer, 18);
+ int standard_hour = BitConverter.ToInt16 (buffer, 20);
+ int standard_minute = BitConverter.ToInt16 (buffer, 22);
+ int standard_second = BitConverter.ToInt16 (buffer, 24);
+ int standard_millisecond = BitConverter.ToInt16 (buffer, 26);
+
+ int daylight_year = BitConverter.ToInt16 (buffer, 28);
+ int daylight_month = BitConverter.ToInt16 (buffer, 30);
+ int daylight_dayofweek = BitConverter.ToInt16 (buffer, 32);
+ int daylight_day = BitConverter.ToInt16 (buffer, 34);
+ int daylight_hour = BitConverter.ToInt16 (buffer, 36);
+ int daylight_minute = BitConverter.ToInt16 (buffer, 38);
+ int daylight_second = BitConverter.ToInt16 (buffer, 40);
+ int daylight_millisecond = BitConverter.ToInt16 (buffer, 42);
+
+ if (standard_month == 0 || daylight_month == 0)
+ return;
+
+ DateTime start_date;
+ DateTime start_timeofday = new DateTime (1, 1, 1, daylight_hour, daylight_minute, daylight_second, daylight_millisecond);
+ TransitionTime start_transition_time;
+
+ if (daylight_year == 0) {
+ start_date = new DateTime (start_year, 1, 1);
+ start_transition_time = TransitionTime.CreateFloatingDateRule (
+ start_timeofday, daylight_month, daylight_day,
+ (DayOfWeek) daylight_dayofweek);
+ }
+ else {
+ start_date = new DateTime (daylight_year, daylight_month, daylight_day,
+ daylight_hour, daylight_minute, daylight_second, daylight_millisecond);
+ start_transition_time = TransitionTime.CreateFixedDateRule (
+ start_timeofday, daylight_month, daylight_day);
+ }
+
+ DateTime end_date;
+ DateTime end_timeofday = new DateTime (1, 1, 1, standard_hour, standard_minute, standard_second, standard_millisecond);
+ TransitionTime end_transition_time;
+
+ if (standard_year == 0) {
+ end_date = new DateTime (end_year, 12, 31);
+ end_transition_time = TransitionTime.CreateFloatingDateRule (
+ end_timeofday, standard_month, standard_day,
+ (DayOfWeek) standard_dayofweek);
+ }
+ else {
+ end_date = new DateTime (standard_year, standard_month, standard_day,
+ standard_hour, standard_minute, standard_second, standard_millisecond);
+ end_transition_time = TransitionTime.CreateFixedDateRule (
+ end_timeofday, standard_month, standard_day);
+ }
+
+ TimeSpan daylight_delta = new TimeSpan(0, -daylight_bias, 0);
+
+ adjustmentRules.Add (AdjustmentRule.CreateAdjustmentRule (
+ start_date, end_date, daylight_delta,
+ start_transition_time, end_transition_time));
+ }
+
public static TimeZoneInfo FromSerializedString (string source)
{
throw new NotImplementedException ();
@@ -369,25 +499,35 @@ namespace System
{
if (systemTimeZones == null) {
systemTimeZones = new List<TimeZoneInfo> ();
+ if (TimeZoneKey != null) {
+ foreach (string id in TimeZoneKey.GetSubKeyNames ()) {
+ try {
+ systemTimeZones.Add (FindSystemTimeZoneById (id));
+ } catch {}
+ }
+ }
#if LIBC
- string[] continents = new string [] {"Africa", "America", "Antarctica", "Arctic", "Asia", "Atlantic", "Brazil", "Canada", "Chile", "Europe", "Indian", "Mexico", "Mideast", "Pacific", "US"};
- foreach (string continent in continents) {
- try {
- foreach (string zonepath in Directory.GetFiles (Path.Combine (TimeZoneDirectory, continent))) {
- try {
- string id = String.Format ("{0}/{1}", continent, Path.GetFileName (zonepath));
- systemTimeZones.Add (FindSystemTimeZoneById (id));
- } catch (ArgumentNullException) {
- } catch (TimeZoneNotFoundException) {
- } catch (InvalidTimeZoneException) {
- } catch (Exception) {
- throw;
+ else {
+ string[] continents = new string [] {"Africa", "America", "Antarctica", "Arctic", "Asia", "Atlantic", "Brazil", "Canada", "Chile", "Europe", "Indian", "Mexico", "Mideast", "Pacific", "US"};
+ foreach (string continent in continents) {
+ try {
+ foreach (string zonepath in Directory.GetFiles (Path.Combine (TimeZoneDirectory, continent))) {
+ try {
+ string id = String.Format ("{0}/{1}", continent, Path.GetFileName (zonepath));
+ systemTimeZones.Add (FindSystemTimeZoneById (id));
+ } catch (ArgumentNullException) {
+ } catch (TimeZoneNotFoundException) {
+ } catch (InvalidTimeZoneException) {
+ } catch (Exception) {
+ throw;
+ }
}
- }
- } catch {}
+ } catch {}
+ }
}
#else
- throw new NotImplementedException ("This method is not implemented for this platform");
+ else
+ throw new NotImplementedException ("This method is not implemented for this platform");
#endif
}
return new ReadOnlyCollection<TimeZoneInfo> (systemTimeZones);