Beispiel #1
0
        /// <summary>
        /// This is called by the containing form to apply a new time zone to the RDATE/EXDATE property date/time
        /// values in the control.
        /// </summary>
        /// <param name="oldTZ">The old time zone's ID</param>
        /// <param name="newTZ">The new time zone's ID</param>
        public void ApplyTimeZone(string oldTZ, string newTZ)
        {
            DateTimeInstance dti;
            int idx = 0;

            // This only applies to RDATE/EXDATE properties with a time
            foreach (RDateProperty rdt in rDates)
            {
                if (rdt.ValueLocation == ValLocValue.DateTime)
                {
                    if (oldTZ == null)
                    {
                        dti = VCalendar.LocalTimeToTimeZoneTime(rdt.TimeZoneDateTime, newTZ);
                    }
                    else
                    {
                        dti = VCalendar.TimeZoneToTimeZone(rdt.TimeZoneDateTime, oldTZ, newTZ);
                    }

                    rdt.TimeZoneDateTime = dti.StartDateTime;
                    lbRDates.Items[idx]  = dti.StartDateTime.ToString("G");
                }

                idx++;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Convert the selected date/time to local time and back and to the selected time zone and back to test
        /// the time zone conversion code.
        /// </summary>
        /// <param name="sender">The sender of the event</param>
        /// <param name="e">The event arguments</param>
        protected void btnApplySrc_Click(object sender, EventArgs e)
        {
            DateTime dt;

            VTimeZone vtzSource = VCalendar.TimeZones[cboSourceTimeZone.SelectedItem.Text];
            VTimeZone vtzDest   = VCalendar.TimeZones[cboDestTimeZone.SelectedItem.Text];

            // Show information for the selected time zones
            lblTimeZoneInfo.Text = String.Format("<strong>From Time Zone:</strong>\r\n\r\n" +
                                                 "{0}\r\n<strong>To Time Zone:</strong>\r\n\r\n{1}", vtzSource.ToString(), vtzDest.ToString());

            // Do the conversions.  Each is round tripped to make sure it gets the expected results.  Note that
            // there will be some anomalies when round tripping times that are near the standard time/DST shift
            // as these times are somewhat ambiguous and their meaning can vary depending on which side of the
            // shift you are on and the direction of the conversion.
            if (!DateTime.TryParse(txtSourceDate.Text, CultureInfo.CurrentCulture, DateTimeStyles.None, out dt))
            {
                lblLocalTime.Text         = "Invalid date/time format";
                lblLocalBackToSource.Text = lblDestTime.Text = lblDestBackToSource.Text = String.Empty;
                return;
            }

            DateTimeInstance dti = VCalendar.TimeZoneTimeToLocalTime(dt, vtzSource.TimeZoneId.Value);

            lblLocalTime.Text = String.Format("{0} {1}", dti.StartDateTime, dti.StartTimeZoneName);

            dti = VCalendar.LocalTimeToTimeZoneTime(dti.StartDateTime, vtzSource.TimeZoneId.Value);
            lblLocalBackToSource.Text = String.Format("{0} {1}", dti.StartDateTime, dti.StartTimeZoneName);

            dti = VCalendar.TimeZoneToTimeZone(dt, vtzSource.TimeZoneId.Value, vtzDest.TimeZoneId.Value);
            lblDestTime.Text = String.Format("{0} {1}", dti.StartDateTime, dti.StartTimeZoneName);

            dti = VCalendar.TimeZoneToTimeZone(dti.StartDateTime, vtzDest.TimeZoneId.Value, vtzSource.TimeZoneId.Value);
            lblDestBackToSource.Text = String.Format("{0} {1}", dti.StartDateTime, dti.StartTimeZoneName);
        }
Beispiel #3
0
        /// <summary>
        /// This is called by the containing form to apply a new time zone to the date/time values in the control
        /// </summary>
        /// <param name="oldTZ">The old time zone's ID</param>
        /// <param name="newTZ">The new time zone's ID</param>
        public void ApplyTimeZone(string oldTZ, string newTZ)
        {
            DateTimeInstance dti;

            if (oldTZ == null)
            {
                if (dtpStartDate.Checked)
                {
                    dti = VCalendar.LocalTimeToTimeZoneTime(dtpStartDate.Value, newTZ);
                    dtpStartDate.Value = dti.StartDateTime;
                }

                if (dtpEndDate.Checked)
                {
                    dti = VCalendar.LocalTimeToTimeZoneTime(dtpEndDate.Value, newTZ);
                    dtpEndDate.Value = dti.StartDateTime;
                }
            }
            else
            {
                if (dtpStartDate.Checked)
                {
                    dti = VCalendar.TimeZoneToTimeZone(dtpStartDate.Value, oldTZ, newTZ);
                    dtpStartDate.Value = dti.StartDateTime;
                }

                if (dtpEndDate.Checked)
                {
                    dti = VCalendar.TimeZoneToTimeZone(dtpEndDate.Value, oldTZ, newTZ);
                    dtpEndDate.Value = dti.StartDateTime;
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// This converts the date/time info to the specified time zone
        /// </summary>
        /// <param name="tzid">The time zone to which to convert this instance</param>
        /// <remarks>This converts the date time instance information from its current time zone identified by
        /// the <see cref="TimeZoneId"/> property to the specified time zone.  The time zone ID property will be
        /// set to the specified time zone after conversion.</remarks>
        public void ToTimeZone(string tzid)
        {
            DateTimeInstance dti, dtiEnd;

            // Already in the specified time zone?
            if (timeZoneID == tzid)
            {
                return;
            }

            // Convert from local time?
            if (timeZoneID == null)
            {
                dti    = VCalendar.LocalTimeToTimeZoneTime(startDate, tzid);
                dtiEnd = VCalendar.LocalTimeToTimeZoneTime(endDate, tzid);
            }
            else
            {
                dti    = VCalendar.TimeZoneToTimeZone(startDate, timeZoneID, tzid);
                dtiEnd = VCalendar.TimeZoneToTimeZone(endDate, timeZoneID, tzid);
            }

            timeZoneID  = dti.TimeZoneId;
            startDate   = dti.StartDateTime;
            startIsDST  = dti.StartIsDaylightSavingTime;
            startTZName = dti.StartTimeZoneName;
            endDate     = dtiEnd.EndDateTime;
            endIsDST    = dtiEnd.EndIsDaylightSavingTime;
            endTZName   = dtiEnd.EndTimeZoneName;
        }
Beispiel #5
0
        /// <summary>
        /// This method can be used to quickly determine the end date of an item regardless of whether it uses
        /// recurrence or not.
        /// </summary>
        /// <param name="inLocalTime">If true, the date/time is returned expressed in local time.  If false, it
        /// is returned expressed in the time zone of the object as specified by the <see cref="TimeZoneId"/>
        /// property.  If no time zone ID has been specified or it cannot be found, local time is used.</param>
        /// <returns>For non-recurring items, it returns the starting date plus the duration.  For recurring
        /// items, it scans the recurrence rules' <see cref="PDI.Recurrence.RecurUntil"/> property values and the
        /// recurrence dates' <see cref="RDateProperty.DateTimeValue"/> or it's <see cref="RDateProperty.PeriodValue"/>'s
        /// <see cref="PDI.Period.EndDateTime"/> property values to find the highest date/time and returns that
        /// plus the duration.  Note that it will not expand the recurrence rules.  Exception rules and exception
        /// dates are ignored.  This is useful for finding out whether or not an item may generate a date in a
        /// given range without actually expanding it completely.</returns>
        public DateTime LastInstance(bool inLocalTime)
        {
            DateTime endDate, dt = this.StartDateTime.DateTimeValue;
            TimeSpan ts = this.InstanceDuration.TimeSpan;

            if (this.IsRecurring)
            {
                foreach (RRuleProperty r in this.RecurrenceRules)
                {
                    if (r.Recurrence.RecurUntil > dt)
                    {
                        dt = r.Recurrence.RecurUntil;

                        if (dt != DateTime.MaxValue)
                        {
                            dt = dt.Add(ts);
                        }
                    }
                }

                foreach (RDateProperty rd in this.RecurDates)
                {
                    if (rd.ValueLocation != ValLocValue.Period)
                    {
                        // If it's not a period, use the component's duration.  If it's only a date, assume it's
                        // the whole day.  The spec is not clear on this so I'm making a best guess.
                        if (rd.ValueLocation == ValLocValue.DateTime)
                        {
                            endDate = rd.DateTimeValue.Add(ts);
                        }
                        else
                        {
                            endDate = rd.DateTimeValue.Add(new TimeSpan(TimeSpan.TicksPerDay));
                        }
                    }
                    else
                    {
                        endDate = rd.PeriodValue.EndDateTime;
                    }

                    if (endDate > dt)
                    {
                        dt = endDate;
                    }
                }
            }
            else
            if (dt != DateTime.MaxValue)
            {
                dt = dt.Add(ts);
            }

            return(inLocalTime ? dt : VCalendar.LocalTimeToTimeZoneTime(dt, this.TimeZoneId).StartDateTime);
        }
Beispiel #6
0
        /// <summary>
        /// This is called by the containing form to apply a new time zone to the date/time values in the control
        /// </summary>
        /// <param name="oldTZ">The old time zone's ID</param>
        /// <param name="newTZ">The new time zone's ID</param>
        public void ApplyTimeZone(string oldTZ, string newTZ)
        {
            DateTimeInstance dti;

            if (dtpTrigger.Checked)
            {
                if (oldTZ == null)
                {
                    dti = VCalendar.LocalTimeToTimeZoneTime(dtpTrigger.Value, newTZ);
                }
                else
                {
                    dti = VCalendar.TimeZoneToTimeZone(dtpTrigger.Value, oldTZ, newTZ);
                }

                dtpTrigger.Value = dti.StartDateTime;
                this.StoreChanges();
            }
        }
Beispiel #7
0
        /// <summary>
        /// Convert the selected date/time to local time and back and to the selected time zone and back to test
        /// the time zone conversion code.
        /// </summary>
        /// <param name="sender">The sender of the event</param>
        /// <param name="e">The event arguments</param>
        private void UpdateTimes(object sender, EventArgs e)
        {
            // Wait until both have a value selected
            if (cboSourceTimeZone.SelectedIndex == -1 || cboDestTimeZone.SelectedIndex == -1)
            {
                return;
            }

            VTimeZone vtzSource = VCalendar.TimeZones[cboSourceTimeZone.SelectedIndex];
            VTimeZone vtzDest   = VCalendar.TimeZones[cboDestTimeZone.SelectedIndex];

            // Show information for the selected time zones
            txtTimeZoneInfo.Clear();
            txtTimeZoneInfo.AppendText("From Time Zone:\r\n");
            txtTimeZoneInfo.AppendText(vtzSource.ToString());
            txtTimeZoneInfo.AppendText("\r\n");
            txtTimeZoneInfo.AppendText("To Time Zone:\r\n");
            txtTimeZoneInfo.AppendText(vtzDest.ToString());

            // Do the conversions.  Each is round tripped to make sure it gets the expected results.  Note that
            // there will be some anomalies when round tripping times that are near the standard time/DST shift
            // as these times are somewhat ambiguous and their meaning can vary depending on which side of the
            // shift you are on and the direction of the conversion.
            DateTime dt = dtpSourceDate.Value;

            DateTimeInstance dti = VCalendar.TimeZoneTimeToLocalTime(dt, vtzSource.TimeZoneId.Value);

            lblLocalTime.Text = String.Format("{0} {1}", dti.StartDateTime, dti.StartTimeZoneName);

            dti = VCalendar.LocalTimeToTimeZoneTime(dti.StartDateTime, vtzSource.TimeZoneId.Value);
            lblLocalBackToSource.Text = String.Format("{0} {1}", dti.StartDateTime, dti.StartTimeZoneName);

            dti = VCalendar.TimeZoneToTimeZone(dt, vtzSource.TimeZoneId.Value, vtzDest.TimeZoneId.Value);
            lblDestTime.Text = String.Format("{0} {1}", dti.StartDateTime, dti.StartTimeZoneName);

            dti = VCalendar.TimeZoneToTimeZone(dti.StartDateTime, vtzDest.TimeZoneId.Value, vtzSource.TimeZoneId.Value);
            lblDestBackToSource.Text = String.Format("{0} {1}", dti.StartDateTime, dti.StartTimeZoneName);
        }
Beispiel #8
0
        /// <summary>
        /// This is used to apply the time zone selection to all date/time values in the dialog box
        /// </summary>
        /// <param name="sender">The sender of the event</param>
        /// <param name="e">The event parameters</param>
        private void btnApplyTZ_Click(object sender, EventArgs e)
        {
            DateTimeInstance dti;
            string           sourceTZ, destTZ;

            if (cboTimeZone.SelectedIndex == timeZoneIdx)
            {
                MessageBox.Show("The time zone has not changed", "No Change", MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation);
                return;
            }

            if (MessageBox.Show(String.Format("Do you want to convert all times from the '{0}' time zone to " +
                                              "the '{1}' time zone?", cboTimeZone.Items[timeZoneIdx], cboTimeZone.Items[cboTimeZone.SelectedIndex]),
                                "Change Time Zone", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
            {
                return;
            }

            // Get the time zone IDs
            if (timeZoneIdx == 0)
            {
                sourceTZ = null;
            }
            else
            {
                sourceTZ = (string)cboTimeZone.Items[timeZoneIdx];
            }

            destTZ = (string)cboTimeZone.Items[cboTimeZone.SelectedIndex];

            // Convert the times
            if (sourceTZ == null)
            {
                if (dtpStartDate.Checked)
                {
                    dti = VCalendar.LocalTimeToTimeZoneTime(dtpStartDate.Value, destTZ);
                    dtpStartDate.Value = dti.StartDateTime;
                }

                if (dtpEndDate.Checked)
                {
                    dti = VCalendar.LocalTimeToTimeZoneTime(dtpEndDate.Value, destTZ);
                    dtpEndDate.Value = dti.StartDateTime;
                }
            }
            else
            {
                if (dtpStartDate.Checked)
                {
                    dti = VCalendar.TimeZoneToTimeZone(dtpStartDate.Value, sourceTZ, destTZ);
                    dtpStartDate.Value = dti.StartDateTime;
                }

                if (dtpEndDate.Checked)
                {
                    dti = VCalendar.TimeZoneToTimeZone(dtpEndDate.Value, sourceTZ, destTZ);
                    dtpEndDate.Value = dti.StartDateTime;
                }
            }

            ucFreeBusy.ApplyTimeZone(sourceTZ, destTZ);

            timeZoneIdx = cboTimeZone.SelectedIndex;
        }
Beispiel #9
0
        /// <summary>
        /// This method is used to return all recurring instances between the two specified date/times based on
        /// the current settings.
        /// </summary>
        /// <param name="fromDate">The minimum date/time on or after which instances should occur.  This will
        /// include an instance if it starts before the date/time but overlaps it when its duration is added to
        /// its start time.</param>
        /// <param name="toDate">The maximum date/time on or before which instances should occur.  This will
        /// include an instance if it starts on or before the specified date/time regardless of its duration.</param>
        /// <param name="inLocalTime">If true, the date/time parameters are assumed to be in local time and the
        /// returned date/times are expressed in local time.  If false, the date/time parameters are assumed to
        /// be in the time zone of the object and the returned date/times are expressed in the time zone of the
        /// object as specified by the <see cref="TimeZoneId"/> property.  If no time zone ID has been specified
        /// or it cannot be found, local time is used.</param>
        /// <returns>Returns a <see cref="DateTimeInstanceCollection"/> containing <see cref="DateTimeInstance" />
        /// objects that represent all instances found between the two specified date/times.  Instances may have
        /// a different duration if created from an <c>RDATE</c> property.</returns>
        /// <exception cref="ArgumentException">This is thrown if a start date has not been specified (it equals
        /// <c>DateTime.MinValue</c>) or the duration is negative.</exception>
        /// <seealso cref="AllInstances"/>
        /// <seealso cref="OccursOn"/>
        public DateTimeInstanceCollection InstancesBetween(DateTime fromDate, DateTime toDate, bool inLocalTime)
        {
            DateTimeCollection recurDates;
            Period             p;
            DateTime           endDate, tempDate1 = DateTime.MaxValue, tempDate2;
            int    idx, count;
            string timeZoneID = this.TimeZoneId;

            PeriodCollection periods   = new PeriodCollection();
            DateTime         startDate = this.StartDateTime.TimeZoneDateTime;
            Duration         dur       = this.InstanceDuration;

            if (startDate == DateTime.MinValue)
            {
                throw new ArgumentException(LR.GetString("ExNoComponentStartDate"));
            }

            if (dur.Ticks < 0)
            {
                throw new ArgumentException(LR.GetString("ExRONegativeDuration"));
            }

            // Convert fromDate and toDate to time zone time if inLocalTime is true.  Recurrences are always
            // resolved in the time of the object.
            if (inLocalTime && timeZoneID != null)
            {
                fromDate = VCalendar.LocalTimeToTimeZoneTime(fromDate, timeZoneID).StartDateTime;
                toDate   = VCalendar.LocalTimeToTimeZoneTime(toDate, timeZoneID).StartDateTime;
            }

            // There might be instances that overlap the requested range so we'll adjust the From date/time by
            // the duration to catch them.
            if (dur.Ticks > 1)
            {
                fromDate = fromDate.Add(new TimeSpan(0 - dur.Ticks + 1));
            }

            // As per the spec, the start date/time is always included in the set but only if it (or it's
            // duration) is within the requested range.  However, if it is recurring and the custom Exclude Start
            // property is set to true, it is not added.
            p = new Period(startDate, dur);

            if (((p.StartDateTime >= fromDate && p.StartDateTime <= toDate) || (p.EndDateTime >= fromDate &&
                                                                                p.EndDateTime <= toDate)) && (!this.IsRecurring || !this.ExcludeStartDateTime))
            {
                periods.Add(p);
            }

            // If it isn't recurring or starts after the requested end date, just return the collection as it is
            if (this.IsRecurring && startDate <= toDate)
            {
                // Expand each recurrence rule
                foreach (RRuleProperty rr in this.RecurrenceRules)
                {
                    // If used, RecurUntil is stored in Universal Time which is converted to local time.  If a
                    // time zone ID is specified, convert it to that time zone temporarily to make sure things
                    // are calculated correctly.
                    if (rr.Recurrence.MaximumOccurrences == 0 && timeZoneID != null)
                    {
                        tempDate1 = rr.Recurrence.RecurUntil;
                        rr.Recurrence.RecurUntil = VCalendar.LocalTimeToTimeZoneTime(tempDate1, timeZoneID).StartDateTime;
                    }

                    rr.Recurrence.StartDateTime = startDate;
                    recurDates = rr.Recurrence.InstancesBetween(fromDate, toDate);

                    if (rr.Recurrence.MaximumOccurrences == 0 && timeZoneID != null)
                    {
                        rr.Recurrence.RecurUntil = tempDate1;
                    }

                    foreach (DateTime dt in recurDates)
                    {
                        periods.Add(new Period(dt, dur));
                    }
                }

                // Add on recurrence dates within the range
                foreach (RDateProperty rd in this.RecurDates)
                {
                    if (rd.ValueLocation != ValLocValue.Period)
                    {
                        // If it's not a period, use the component's duration.  If it's only a date, assume it's
                        // the whole day.  The spec is not clear on this so I'm making a best guess.
                        if (rd.ValueLocation == ValLocValue.DateTime)
                        {
                            endDate = rd.TimeZoneDateTime.Add(dur.TimeSpan);
                        }
                        else
                        {
                            endDate = rd.TimeZoneDateTime.Add(new TimeSpan(TimeSpan.TicksPerDay));
                        }

                        if ((rd.TimeZoneDateTime >= fromDate && rd.TimeZoneDateTime <= toDate) ||
                            (endDate >= fromDate && endDate <= toDate))
                        {
                            periods.Add(new Period(rd.TimeZoneDateTime, endDate));
                        }
                    }
                    else
                    {
                        // As with Recurrence.RecurUntil, the period values are in Universal Time so convert them
                        // to the time zone time for proper comparison.
                        tempDate1 = rd.PeriodValue.StartDateTime;
                        tempDate2 = rd.PeriodValue.EndDateTime;

                        if (timeZoneID != null)
                        {
                            tempDate1 = VCalendar.LocalTimeToTimeZoneTime(tempDate1, timeZoneID).StartDateTime;
                        }

                        if (timeZoneID != null)
                        {
                            tempDate2 = VCalendar.LocalTimeToTimeZoneTime(tempDate2, timeZoneID).StartDateTime;
                        }

                        if ((tempDate1 >= fromDate && tempDate1 <= toDate) ||
                            (tempDate2 >= fromDate && tempDate2 <= toDate))
                        {
                            periods.Add(new Period(tempDate1, tempDate2));
                        }
                    }
                }

                // Expand exception rules and filter out those instances
                count = periods.Count;

                foreach (RRuleProperty er in this.ExceptionRules)
                {
                    // Same as above
                    if (er.Recurrence.MaximumOccurrences == 0 && timeZoneID != null)
                    {
                        tempDate1 = er.Recurrence.RecurUntil;
                        er.Recurrence.RecurUntil = VCalendar.LocalTimeToTimeZoneTime(tempDate1, timeZoneID).StartDateTime;
                    }

                    er.Recurrence.StartDateTime = startDate;
                    recurDates = er.Recurrence.InstancesBetween(fromDate, toDate);

                    if (er.Recurrence.MaximumOccurrences == 0 && timeZoneID != null)
                    {
                        er.Recurrence.RecurUntil = tempDate1;
                    }

                    foreach (DateTime dt in recurDates)
                    {
                        for (idx = 0; idx < count; idx++)
                        {
                            if (periods[idx].StartDateTime == dt)
                            {
                                periods.RemoveAt(idx);
                                idx--;
                                count--;
                            }
                        }
                    }
                }

                // Filter out any exception dates
                foreach (ExDateProperty ed in this.ExceptionDates)
                {
                    DateTime dt = ed.TimeZoneDateTime;

                    // If it's only a date, assume it's the whole day and remove all instances on that day
                    // regardless of the time.  The spec is not clear on this so I'm making a best guess.
                    if (ed.ValueLocation == ValLocValue.DateTime)
                    {
                        if (dt >= fromDate && dt <= toDate)
                        {
                            for (idx = 0; idx < count; idx++)
                            {
                                if (periods[idx].StartDateTime == dt)
                                {
                                    periods.RemoveAt(idx);
                                    idx--;
                                    count--;
                                }
                            }
                        }
                    }
                    else
                    if (dt >= fromDate.Date && dt <= toDate.Date)
                    {
                        for (idx = 0; idx < count; idx++)
                        {
                            if (periods[idx].StartDateTime.Date == dt)
                            {
                                periods.RemoveAt(idx);
                                idx--;
                                count--;
                            }
                        }
                    }
                }

                // Sort the periods and remove duplicates
                periods.Sort(true);

                for (idx = 1; idx < count; idx++)
                {
                    if (periods[idx] == periods[idx - 1])
                    {
                        periods.RemoveAt(idx);
                        idx--;
                        count--;
                    }
                }
            }

            // Now convert the periods to DateTimeInstances that include the necessary time zone information
            DateTimeInstanceCollection dtic = new DateTimeInstanceCollection();
            DateTimeInstance           dti, dtiEnd;

            // Always in local time if there is no time zone ID
            if (timeZoneID == null)
            {
                inLocalTime = true;
            }

            foreach (Period pd in periods)
            {
                if (inLocalTime)
                {
                    dti    = VCalendar.TimeZoneTimeToLocalTime(pd.StartDateTime, timeZoneID);
                    dtiEnd = VCalendar.TimeZoneTimeToLocalTime(pd.EndDateTime, timeZoneID);
                }
                else
                {
                    dti    = VCalendar.TimeZoneTimeInfo(pd.StartDateTime, timeZoneID);
                    dtiEnd = VCalendar.TimeZoneTimeInfo(pd.EndDateTime, timeZoneID);
                }

                dti.Duration                = pd.Duration;
                dti.EndDateTime             = dtiEnd.EndDateTime;
                dti.EndIsDaylightSavingTime = dtiEnd.EndIsDaylightSavingTime;
                dti.EndTimeZoneName         = dtiEnd.EndTimeZoneName;

                // If it already contains the entry and it is in DST, bump it forward an hour to account for the
                // time adjustment.  This will happen on hourly, minutely, and secondly recurrence patterns.  By
                // moving duplicates forward an hour, we retain the expected number of occurrences.
                if (!dtic.Contains(dti))
                {
                    dtic.Add(dti);
                }
                else
                if (dti.StartIsDaylightSavingTime)
                {
                    dti.StartDateTime = dti.StartDateTime.AddHours(1);
                    dti.EndDateTime   = dti.EndDateTime.AddHours(1);
                    dtic.Add(dti);
                }
            }

            return(dtic);     // And finally, we are done
        }