private void EnsureProperties() { if (string.IsNullOrEmpty(UID)) { // Create a new UID for the component UID = new UIDFactory().Build(); } // NOTE: removed setting the 'CREATED' property here since it breaks serialization. // See https://sourceforge.net/projects/dday-ical/forums/forum/656447/topic/3754354 if (DTStamp == null) { // Here, we don't simply set to DateTime.Now because DateTime.Now contains milliseconds, and // the iCalendar standard doesn't care at all about milliseconds. Therefore, when comparing // two calendars, one generated, and one loaded from file, they may be functionally identical, // but be determined to be different due to millisecond differences. // // NOTE: also ensure we're in UTC, so our CLR implementation closely matches the RFC. // See bug #3485766. DateTime now = DateTime.UtcNow; DTStamp = new iCalDateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); DTStamp.IsUniversalTime = true; } }
public static iCalTimeZone FromSystemTimeZone(System.TimeZoneInfo tzinfo, DateTime earlistDateTimeToSupport, bool includeHistoricalData) { var adjustmentRules = tzinfo.GetAdjustmentRules(); var utcOffset = tzinfo.BaseUtcOffset; var dday_tz = new iCalTimeZone(); dday_tz.TZID = tzinfo.Id; IDateTime earliest = new iCalDateTime(earlistDateTimeToSupport); foreach (var adjustmentRule in adjustmentRules) { // Only include historical data if asked to do so. Otherwise, // use only the most recent adjustment rule available. if (!includeHistoricalData && adjustmentRule.DateEnd < earlistDateTimeToSupport) continue; var delta = adjustmentRule.DaylightDelta; var dday_tzinfo_standard = new iCalTimeZoneInfo(); dday_tzinfo_standard.Name = "STANDARD"; dday_tzinfo_standard.TimeZoneName = tzinfo.StandardName; dday_tzinfo_standard.Start = new iCalDateTime(new DateTime(adjustmentRule.DateStart.Year, adjustmentRule.DaylightTransitionEnd.Month, adjustmentRule.DaylightTransitionEnd.Day, adjustmentRule.DaylightTransitionEnd.TimeOfDay.Hour, adjustmentRule.DaylightTransitionEnd.TimeOfDay.Minute, adjustmentRule.DaylightTransitionEnd.TimeOfDay.Second).AddDays(1)); if (dday_tzinfo_standard.Start.LessThan(earliest)) dday_tzinfo_standard.Start = dday_tzinfo_standard.Start.AddYears(earliest.Year - dday_tzinfo_standard.Start.Year); dday_tzinfo_standard.OffsetFrom = new UTCOffset(utcOffset + delta); dday_tzinfo_standard.OffsetTo = new UTCOffset(utcOffset); PopulateiCalTimeZoneInfo(dday_tzinfo_standard, adjustmentRule.DaylightTransitionEnd, adjustmentRule.DateStart.Year); // Add the "standard" time rule to the time zone dday_tz.AddChild(dday_tzinfo_standard); if (tzinfo.SupportsDaylightSavingTime) { var dday_tzinfo_daylight = new iCalTimeZoneInfo(); dday_tzinfo_daylight.Name = "DAYLIGHT"; dday_tzinfo_daylight.TimeZoneName = tzinfo.DaylightName; dday_tzinfo_daylight.Start = new iCalDateTime(new DateTime(adjustmentRule.DateStart.Year, adjustmentRule.DaylightTransitionStart.Month, adjustmentRule.DaylightTransitionStart.Day, adjustmentRule.DaylightTransitionStart.TimeOfDay.Hour, adjustmentRule.DaylightTransitionStart.TimeOfDay.Minute, adjustmentRule.DaylightTransitionStart.TimeOfDay.Second)); if (dday_tzinfo_daylight.Start.LessThan(earliest)) dday_tzinfo_daylight.Start = dday_tzinfo_daylight.Start.AddYears(earliest.Year - dday_tzinfo_daylight.Start.Year); dday_tzinfo_daylight.OffsetFrom = new UTCOffset(utcOffset); dday_tzinfo_daylight.OffsetTo = new UTCOffset(utcOffset + delta); PopulateiCalTimeZoneInfo(dday_tzinfo_daylight, adjustmentRule.DaylightTransitionStart, adjustmentRule.DateStart.Year); // Add the "daylight" time rule to the time zone dday_tz.AddChild(dday_tzinfo_daylight); } } // If no time zone information was recorded, at least // add a STANDARD time zone element to indicate the // base time zone information. if (dday_tz.TimeZoneInfos.Count == 0) { var dday_tzinfo_standard = new iCalTimeZoneInfo(); dday_tzinfo_standard.Name = "STANDARD"; dday_tzinfo_standard.TimeZoneName = tzinfo.StandardName; dday_tzinfo_standard.Start = earliest; dday_tzinfo_standard.OffsetFrom = new UTCOffset(utcOffset); dday_tzinfo_standard.OffsetTo = new UTCOffset(utcOffset); // Add the "standard" time rule to the time zone dday_tz.AddChild(dday_tzinfo_standard); } return dday_tz; }
protected IDateTime ConvertToIDateTime(DateTime dt, IDateTime referenceDate) { IDateTime newDt = new iCalDateTime(dt, referenceDate.TZID); newDt.AssociateWith(referenceDate); return newDt; }
public void AssociateWith(IDateTime dt) { if (AssociatedObject == null && dt.AssociatedObject != null) AssociatedObject = dt.AssociatedObject; else if (AssociatedObject != null && dt.AssociatedObject == null) dt.AssociatedObject = AssociatedObject; // If these share the same TZID, then let's see if we // can share the time zone observance also! if (TZID != null && string.Equals(TZID, dt.TZID)) { if (TimeZoneObservance != null && dt.TimeZoneObservance == null) { IDateTime normalizedDt = new iCalDateTime(TimeZoneObservance.Value.TimeZoneInfo.OffsetTo.ToUTC(dt.Value)); if (TimeZoneObservance.Value.Contains(normalizedDt)) dt.TimeZoneObservance = TimeZoneObservance; } else if (dt.TimeZoneObservance != null && TimeZoneObservance == null) { IDateTime normalizedDt = new iCalDateTime(dt.TimeZoneObservance.Value.TimeZoneInfo.OffsetTo.ToUTC(Value)); if (dt.TimeZoneObservance.Value.Contains(normalizedDt)) TimeZoneObservance = dt.TimeZoneObservance; } } }
public override bool Equals(object obj) { if (obj is IDateTime) { this.AssociateWith((IDateTime)obj); return ((IDateTime)obj).UTC.Equals(UTC); } else if (obj is DateTime) { iCalDateTime dt = new iCalDateTime((DateTime)obj); this.AssociateWith(dt); return object.Equals(dt.UTC, UTC); } return false; }
private IRecurrencePattern ProcessRecurrencePattern(IDateTime referenceDate) { RecurrencePattern r = new RecurrencePattern(); r.CopyFrom(Pattern); // Convert the UNTIL value to a local date/time based on the time zone information that // is in the reference date if (r.Until != DateTime.MinValue) { // Build an iCalDateTime with the correct time zone & calendar var until = new iCalDateTime(r.Until, referenceDate.TZID); until.AssociatedObject = referenceDate.AssociatedObject; // Convert back to local time so time zone comparisons match r.Until = until.Local; } if (r.Frequency > FrequencyType.Secondly && r.BySecond.Count == 0 && referenceDate.HasTime /* NOTE: Fixes a bug where all-day events have BySecond/ByMinute/ByHour added incorrectly */) r.BySecond.Add(referenceDate.Second); if (r.Frequency > FrequencyType.Minutely && r.ByMinute.Count == 0 && referenceDate.HasTime /* NOTE: Fixes a bug where all-day events have BySecond/ByMinute/ByHour added incorrectly */) r.ByMinute.Add(referenceDate.Minute); if (r.Frequency > FrequencyType.Hourly && r.ByHour.Count == 0 && referenceDate.HasTime /* NOTE: Fixes a bug where all-day events have BySecond/ByMinute/ByHour added incorrectly */) r.ByHour.Add(referenceDate.Hour); // If BYDAY, BYYEARDAY, or BYWEEKNO is specified, then // we don't default BYDAY, BYMONTH or BYMONTHDAY if (r.ByDay.Count == 0) { // If the frequency is weekly, use the original date's day of week. // NOTE: fixes WeeklyCount1() and WeeklyUntil1() handling // If BYWEEKNO is specified and BYMONTHDAY/BYYEARDAY is not specified, // then let's add BYDAY to BYWEEKNO. // NOTE: fixes YearlyByWeekNoX() handling if (r.Frequency == FrequencyType.Weekly || ( r.ByWeekNo.Count > 0 && r.ByMonthDay.Count == 0 && r.ByYearDay.Count == 0 )) r.ByDay.Add(new WeekDay(referenceDate.DayOfWeek)); // If BYMONTHDAY is not specified, // default to the current day of month. // NOTE: fixes YearlyByMonth1() handling, added BYYEARDAY exclusion // to fix YearlyCountByYearDay1() handling if (r.Frequency > FrequencyType.Weekly && r.ByWeekNo.Count == 0 && r.ByYearDay.Count == 0 && r.ByMonthDay.Count == 0) r.ByMonthDay.Add(referenceDate.Day); // If BYMONTH is not specified, default to // the current month. // NOTE: fixes YearlyCountByYearDay1() handling if (r.Frequency > FrequencyType.Monthly && r.ByWeekNo.Count == 0 && r.ByYearDay.Count == 0 && r.ByMonth.Count == 0) r.ByMonth.Add(referenceDate.Month); } return r; }
IPeriod CreatePeriod(DateTime dt, IDateTime referenceDate) { // Turn each resulting date/time into an IDateTime and associate it // with the reference date. IDateTime newDt = new iCalDateTime(dt, referenceDate.TZID); // NOTE: fixes bug #2938007 - hasTime missing newDt.HasTime = referenceDate.HasTime; newDt.AssociateWith(referenceDate); // Create a period from the new date/time. return new Period(newDt); }
public List<Period> Evaluate(iCalDateTime StartDate, iCalDateTime FromDate, iCalDateTime EndDate) { List<Period> periods = new List<Period>(); if (StartDate > FromDate) FromDate = StartDate; if (EndDate < FromDate || FromDate > EndDate) return periods; foreach (Period p in Periods) if (!periods.Contains(p)) periods.Add(p); return periods; }