/// <summary> /// Returns the time bias specification for the specified year. /// </summary> /// <param name="year">The year for which the bias applies.</param> private BiasSettings GetBiasSettings(int year) { // Check whether the time zone uses dynamic DST if (!isDaylightDynamic) { return(actualSettings); } if (year < firstDaylightEntry) { year = firstDaylightEntry; } else if (year > lastDaylightEntry) { year = lastDaylightEntry; } // Get the collection of dynamic DST data Dictionary <int, BiasSettings> years = null; lock (standardName) { string key = standardName + " Dynamic DST data"; //TODO: Use caching to increase performance //years = (Dictionary<int, BiasSettings>)Application.Cache[key]; if (years == null) { years = new Dictionary <int, BiasSettings>(); //Application.Cache.Add(key, years); } } // Get the DST data for the specified year BiasSettings result = null; lock (years) { if (years.TryGetValue(year, out result)) { return(result); } string keyName = TimeZoneManager.TimeZoneDatabaseKey; keyName += string.Format(@"\{0}\Dynamic DST", standardName); using (RegistryKey key = Registry. LocalMachine.OpenSubKey(keyName)) { byte[] rawData = (byte[])key.GetValue(year.ToString()); result = (rawData == null) ? actualSettings : new BiasSettings(rawData); } years.Add(year, result); } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="UITimeZone"/> class. /// </summary> /// <param name="name">The name of the time zone /// as recorded in the Windows registry.</param> /// <param name="data">The time zone's registry data.</param> internal UITimeZone(string name, RegistryKey data) { cachedDaylightChanges = new Dictionary <int, DaylightTime>(); // Convert the signed number obtained from the registry // to the unsigned value of the system index. int?indexValue = (int?)data.GetValue("Index"); if (indexValue.HasValue) { index = (((uint)(indexValue.Value >> 16)) << 16) | ((uint)(indexValue.Value & 0xFFFF)); } // Get the display name of the time zone. displayName = (string)data.GetValue("Display"); Match m = displayNameRegex.Match(displayName); description = m.Groups["Dscr"].Value; // Get other descriptive data of the time zone standardName = (string)data.GetValue("Std"); daylightName = (string)data.GetValue("Dlt"); actualSettings = new BiasSettings( (byte[])data.GetValue("TZI")); // Check whether the time zone uses dynamic DST string[] subKeyNames = data.GetSubKeyNames(); foreach (string subKeyName in subKeyNames) { if (subKeyName != "Dynamic DST") { continue; } isDaylightDynamic = true; using (RegistryKey subKey = data.OpenSubKey(subKeyName)) { firstDaylightEntry = (int)subKey.GetValue("FirstEntry"); lastDaylightEntry = (int)subKey.GetValue("LastEntry"); } if (standardName != name) // it should not be { standardName = name; // is used when accessing the registry } return; } isDaylightDynamic = false; firstDaylightEntry = int.MinValue; lastDaylightEntry = int.MaxValue; }
/// <summary> /// Returns the coordinated universal time (UTC) offset /// for the specified local time. /// </summary> /// <param name="time">The local date and time.</param> public override TimeSpan GetUtcOffset(DateTime time) { if (time.Kind == DateTimeKind.Utc) { return(TimeSpan.Zero); } int year = time.Year; DaylightTime daylightTimes = GetDaylightChanges(year); BiasSettings settings = GetBiasSettings(year); if (!IsDaylightSavingTime(time, daylightTimes)) { return(settings.ZoneBias); } return(settings.ZoneBias + daylightTimes.Delta); }
/// <summary> /// Returns the daylight saving time period for a particular year. /// </summary> /// <param name="year">The year to which /// the daylight saving time period applies.</param> /// <exception cref="T:System.ArgumentOutOfRangeException"> /// <paramref name="year"/> is less than 1 or greater than 9999.</exception> public override DaylightTime GetDaylightChanges(int year) { if ((year < 1) || (year > 9999)) { throw new ArgumentOutOfRangeException("year"); } lock (cachedDaylightChanges) { DaylightTime result = null; if (cachedDaylightChanges.TryGetValue(year, out result)) { return(result); } BiasSettings settings = GetBiasSettings(year); result = settings.GetDaylightChanges(year); cachedDaylightChanges.Add(year, result); return(result); } }
/// <summary> /// Returns the coordinated universal time (UTC) offset /// for the specified universal time. /// </summary> /// <param name="time">The UTC date and time.</param> private TimeSpan GetUtcOffsetFromUniversalTime(DateTime time) { int year = time.Year; DaylightTime daylightTimes = GetDaylightChanges(year); BiasSettings settings = GetBiasSettings(year); TimeSpan result = settings.ZoneBias; if ((daylightTimes == null) || (daylightTimes.Delta.Ticks == 0)) { return(result); } DateTime time3 = daylightTimes.Start - result; DateTime time4 = (daylightTimes.End - result) - daylightTimes.Delta; DateTime time5, time6; if (daylightTimes.Delta.Ticks > 0) { time5 = time4 - daylightTimes.Delta; time6 = time4; } else { time5 = time3; time6 = time3 - daylightTimes.Delta; } bool flag = false; if (time3 > time4) { flag = (time < time4) || (time >= time3); } else { flag = (time >= time3) && (time < time4); } return(flag ? result + daylightTimes.Delta : result); }