/// <summary> /// Update the prior row with the values from the unbound controls and load the values for the new row /// when the position changes. /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void BindingSource_PositionChanged(object sender, EventArgs e) { ObservanceRule newItem = (ObservanceRule)this.BindingSource.Current; int hours, minutes; // If all deleted, ignore it if (newItem == null) { currentRule = null; return; } // Save changes to the unbound controls to the prior row this.StoreChanges(); // Load the new values into the unbound controls currentRule = newItem; // We'll only edit the first time zone name if (currentRule.TimeZoneNames.Count == 0) { currentRule.TimeZoneNames.Add("GMT"); } txtTZName.Text = currentRule.TimeZoneNames[0].Value; hours = currentRule.OffsetFrom.TimeSpanValue.Hours; minutes = currentRule.OffsetFrom.TimeSpanValue.Minutes; // If hours are specified, keep minutes positive if (hours != 0 && minutes < 0) { minutes *= -1; } udcFromHours.Value = (hours < -23) ? -23 : (hours > 23) ? 23 : hours; udcFromMinutes.Value = (minutes < -59) ? -59 : (minutes > 59) ? 59 : minutes; hours = currentRule.OffsetTo.TimeSpanValue.Hours; minutes = currentRule.OffsetTo.TimeSpanValue.Minutes; // If hours are specified, keep minutes positive if (hours != 0 && minutes < 0) { minutes *= -1; } udcToHours.Value = (hours < -23) ? -23 : (hours > 23) ? 23 : hours; udcToMinutes.Value = (minutes < -59) ? -59 : (minutes > 59) ? 59 : minutes; rcRulesDates.SetValues(currentRule.RecurrenceRules, currentRule.RecurDates); }
//===================================================================== /// <summary> /// This is used to load the VCalendar.TimeZones collection with time zone information from the registry /// </summary> public static void LoadTimeZoneInfo() { string keyName, display, standardDesc, dstDesc; TIMEZONE tz; VCalendar.TimeZones.Clear(); // To keep things simple, we'll load the time zone data from the settings available in the registry. // We could take it a step further and load it from something like a copy of the Olson time zone // database but I haven't been that ambitious yet. if (Environment.OSVersion.Platform == PlatformID.Win32NT) { keyName = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"; } else { keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones"; } using (var rk = Registry.LocalMachine.OpenSubKey(keyName)) { foreach (string s in rk.GetSubKeyNames()) { using (var rsk = rk.OpenSubKey(s)) { display = (string)rsk.GetValue("Display"); standardDesc = (string)rsk.GetValue("Std"); dstDesc = (string)rsk.GetValue("Dlt"); tz = TIMEZONE.FromRegistry(rsk.GetValue("TZI")); } // Create the time zone object VTimeZone vtz = new VTimeZone(); vtz.TimeZoneId.Value = display; ObservanceRule or = vtz.ObservanceRules.Add(ObservanceRuleType.Standard); or.OffsetFrom.TimeSpanValue = TimeSpan.FromMinutes(tz.nBias + tz.nDaylightBias).Negate(); or.OffsetTo.TimeSpanValue = TimeSpan.FromMinutes(tz.nBias + tz.nStandardBias).Negate(); or.TimeZoneNames.Add(standardDesc); // If the standard date month is zero, it doesn't use standard time. Assume 01/01/1970 and // set it up to return the offset. if (tz.standardDate.wMonth == 0) { or.StartDateTime.DateTimeValue = new DateTime(1970, 1, 1); } else { // If year is zero, its a recurrence. If not zero, it's a fixed date. if (tz.standardDate.wYear == 0) { or.StartDateTime.DateTimeValue = tz.standardDate.ToDateTime(1970); RRuleProperty rrule = new RRuleProperty(); rrule.Recurrence.RecurYearly( (tz.standardDate.wDay > 4) ? DayOccurrence.Last : (DayOccurrence)tz.standardDate.wDay, tz.standardDate.DayOfWeek(), tz.standardDate.wMonth, 1); or.RecurrenceRules.Add(rrule); } else { or.StartDateTime.DateTimeValue = tz.standardDate.ToDateTime(); or.RecurDates.Add(or.StartDateTime.DateTimeValue); } } // If the daylight month is zero, it doesn't use DST. The standard rule will handle // everything. if (tz.daylightDate.wMonth != 0) { or = vtz.ObservanceRules.Add(ObservanceRuleType.Daylight); or.OffsetFrom.TimeSpanValue = TimeSpan.FromMinutes(tz.nBias + tz.nStandardBias).Negate(); or.OffsetTo.TimeSpanValue = TimeSpan.FromMinutes(tz.nBias + tz.nDaylightBias).Negate(); or.TimeZoneNames.Add(dstDesc); // If year is zero, its a recurrence. If not zero, it's a fixed date. if (tz.daylightDate.wYear == 0) { or.StartDateTime.DateTimeValue = tz.daylightDate.ToDateTime(1970); RRuleProperty rrule = new RRuleProperty(); rrule.Recurrence.RecurYearly( (tz.daylightDate.wDay > 4) ? DayOccurrence.Last : (DayOccurrence)tz.daylightDate.wDay, tz.daylightDate.DayOfWeek(), tz.daylightDate.wMonth, 1); or.RecurrenceRules.Add(rrule); } else { or.StartDateTime.DateTimeValue = tz.daylightDate.ToDateTime(); or.RecurDates.Add(or.StartDateTime.DateTimeValue); } } VCalendar.TimeZones.Add(vtz); } } // Put the time zones in sorted order VCalendar.TimeZones.Sort(true); }