Exemple #1
0
        public void TestMask()
        {
            var calendar = new Calendar();

            calendar.Mask = 0;

            Assert.AreEqual(calendar.Monday, false);
            Assert.AreEqual(calendar.Tuesday, false);
            Assert.AreEqual(calendar.Wednesday, false);
            Assert.AreEqual(calendar.Thursday, false);
            Assert.AreEqual(calendar.Friday, false);
            Assert.AreEqual(calendar.Saturday, false);
            Assert.AreEqual(calendar.Sunday, false);

            calendar.Mask = 1;

            Assert.AreEqual(calendar.Monday, true);
            Assert.AreEqual(calendar.Tuesday, false);
            Assert.AreEqual(calendar.Wednesday, false);
            Assert.AreEqual(calendar.Thursday, false);
            Assert.AreEqual(calendar.Friday, false);
            Assert.AreEqual(calendar.Saturday, false);
            Assert.AreEqual(calendar.Sunday, false);

            calendar.Mask = 64;

            Assert.AreEqual(calendar.Monday, false);
            Assert.AreEqual(calendar.Tuesday, false);
            Assert.AreEqual(calendar.Wednesday, false);
            Assert.AreEqual(calendar.Thursday, false);
            Assert.AreEqual(calendar.Friday, false);
            Assert.AreEqual(calendar.Saturday, false);
            Assert.AreEqual(calendar.Sunday, true);

            calendar.Mask = 1+4+8+16;

            Assert.AreEqual(calendar.Monday, true);
            Assert.AreEqual(calendar.Tuesday, false);
            Assert.AreEqual(calendar.Wednesday, true);
            Assert.AreEqual(calendar.Thursday, true);
            Assert.AreEqual(calendar.Friday, true);
            Assert.AreEqual(calendar.Saturday, false);
            Assert.AreEqual(calendar.Sunday, false);

            calendar.Mask = 0;
            calendar.Monday = true;
            Assert.AreEqual(1, calendar.Mask);

            calendar.Mask = 0;
            calendar.Sunday = true;
            Assert.AreEqual(64, calendar.Mask);

            calendar.Mask = 0;
            calendar.Monday = true;
            calendar.Wednesday = true;
            calendar.Thursday = true;
            calendar.Friday = true;
            Assert.AreEqual(1+4+8+16, calendar.Mask);
        }
Exemple #2
0
 /// <summary>
 /// Copies the week pattern from the given calendar.
 /// </summary>
 public static void CopyWeekPatternFrom(this Calendar calendar, Calendar weekPatternSource)
 {
     calendar.Monday = weekPatternSource.Monday;
     calendar.Tuesday = weekPatternSource.Tuesday;
     calendar.Wednesday = weekPatternSource.Wednesday;
     calendar.Thursday = weekPatternSource.Thursday;
     calendar.Friday = weekPatternSource.Friday;
     calendar.Saturday = weekPatternSource.Saturday;
     calendar.Sunday = weekPatternSource.Sunday;
 }
Exemple #3
0
        /// <summary>
        /// Adds the given calendar day and returns one or more new calendar entities representing the new data.
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<Calendar> Add(this Calendar calendar, DateTime day)
        {
            if(calendar.CoversDate(day))
            { // no work needs to be done.
                return new Calendar[] { calendar };
            }

            // naively add another calendar entity representing one day.
            if ((calendar.EndDate - calendar.StartDate).Days <= 7 &&
                calendar.StartDate <= day &&
                calendar.EndDate >= day)
            {
                var newCalendar = new Calendar()
                {
                    EndDate = calendar.EndDate,
                    StartDate = calendar.StartDate,
                    Mask = calendar.Mask,
                    ServiceId = calendar.ServiceId
                };
                newCalendar.Set(day, true);
                return new Calendar[] { newCalendar };
            }
            return new Calendar[] { calendar, day.CreateCalendar(calendar.ServiceId) };
        }
Exemple #4
0
        public void TestTryMerge()
        {
            // two simple consequitive weeks.
            var calendar1 = new Calendar()
            {
                ServiceId = "0",
                Mask = 64,
                StartDate = new System.DateTime(2015, 11, 23),
                EndDate = new System.DateTime(2015, 11, 29)
            };
            var calendar2 = new Calendar()
            {
                ServiceId = "0",
                Mask = 64,
                StartDate = new System.DateTime(2015, 11, 30),
                EndDate = new System.DateTime(2015, 12, 06)
            };

            Calendar merge;
            Assert.IsTrue(calendar1.TryMerge(calendar2, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(64, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 29), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 06), merge.EndDate);

            Assert.IsTrue(calendar2.TryMerge(calendar1, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(64, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 29), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 06), merge.EndDate);

            // two calendars one completely overlapping the other.
            calendar1 = new Calendar()
            {
                ServiceId = "0",
                Mask = 64,
                StartDate = new System.DateTime(2015, 11, 23),
                EndDate = new System.DateTime(2015, 11, 29)
            };
            calendar2 = new Calendar()
            {
                ServiceId = "0",
                Mask = 64,
                StartDate = new System.DateTime(2015, 11, 23),
                EndDate = new System.DateTime(2015, 12, 06)
            };

            Assert.IsTrue(calendar1.TryMerge(calendar2, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(64, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 29), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 06), merge.EndDate);

            Assert.IsTrue(calendar2.TryMerge(calendar1, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(64, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 29), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 06), merge.EndDate);

            // two calendars one completely overlapping the other.
            calendar1 = new Calendar()
            {
                ServiceId = "0",
                Mask = 64,
                StartDate = new System.DateTime(2015, 11, 23),
                EndDate = new System.DateTime(2015, 11, 29)
            };
            calendar1.TrimDates();
            calendar2 = new Calendar()
            {
                ServiceId = "0",
                Mask = 64,
                StartDate = new System.DateTime(2015, 11, 23),
                EndDate = new System.DateTime(2015, 12, 06)
            };
            calendar2.TrimDates();

            Assert.IsTrue(calendar1.TryMerge(calendar2, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(64, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 29), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 06), merge.EndDate);

            Assert.IsTrue(calendar2.TryMerge(calendar1, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(64, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 29), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 06), merge.EndDate);

            // two calendars one completely overlapping the other.
            calendar1 = new Calendar()
            {
                ServiceId = "0",
                Mask = 64,
                StartDate = new System.DateTime(2015, 11, 23),
                EndDate = new System.DateTime(2015, 11, 29)
            };
            calendar1.TrimDates();
            calendar2 = new Calendar()
            {
                ServiceId = "0",
                Mask = 1+64,
                StartDate = new System.DateTime(2015, 11, 23),
                EndDate = new System.DateTime(2015, 12, 06)
            };
            calendar2.TrimDates();

            Assert.IsTrue(calendar1.TryMerge(calendar2, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(1+64, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 23), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 06), merge.EndDate);

            Assert.IsTrue(calendar2.TryMerge(calendar1, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(1+64, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 23), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 06), merge.EndDate);

            // two calendars with conflicting masks.
            calendar1 = new Calendar()
            {
                ServiceId = "0",
                Mask = 2+64,
                StartDate = new System.DateTime(2015, 11, 23),
                EndDate = new System.DateTime(2015, 11, 29)
            };
            calendar1.TrimDates();
            calendar2 = new Calendar()
            {
                ServiceId = "0",
                Mask = 1+64,
                StartDate = new System.DateTime(2015, 11, 30),
                EndDate = new System.DateTime(2015, 12, 06)
            };
            calendar2.TrimDates();

            Assert.IsFalse(calendar1.TryMerge(calendar2, out merge));
            Assert.IsFalse(calendar2.TryMerge(calendar1, out merge));

            // two calendars both spanning more than one week.
            calendar1 = new Calendar()
            {
                ServiceId = "0",
                Mask = 127,
                StartDate = new System.DateTime(2015, 11, 16),
                EndDate = new System.DateTime(2015, 11, 29)
            };
            calendar1.TrimDates();
            calendar2 = new Calendar()
            {
                ServiceId = "0",
                Mask = 127,
                StartDate = new System.DateTime(2015, 11, 30),
                EndDate = new System.DateTime(2015, 12, 13)
            };
            calendar2.TrimDates();

            Assert.IsTrue(calendar1.TryMerge(calendar2, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(127, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 16), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 13), merge.EndDate);

            Assert.IsTrue(calendar2.TryMerge(calendar1, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(127, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 16), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 13), merge.EndDate);

            // two calendars first one week with a few don't-case other more than a week.
            calendar1 = new Calendar()
            {
                ServiceId = "0",
                Mask = 64 + 32 + 16 + 8,
                StartDate = new System.DateTime(2015, 11, 26),
                EndDate = new System.DateTime(2015, 11, 29)
            };
            calendar1.TrimDates();
            calendar2 = new Calendar()
            {
                ServiceId = "0",
                Mask = 127,
                StartDate = new System.DateTime(2015, 11, 30),
                EndDate = new System.DateTime(2015, 12, 13)
            };
            calendar2.TrimDates();

            Assert.IsTrue(calendar1.TryMerge(calendar2, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(127, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 26), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 13), merge.EndDate);

            Assert.IsTrue(calendar2.TryMerge(calendar1, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(127, merge.Mask);
            Assert.AreEqual(new System.DateTime(2015, 11, 26), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2015, 12, 13), merge.EndDate);

            // two calendars first two weeks with a few don't-cares other the week right after.
            calendar1 = new Calendar()
            {
                ServiceId = "0",
                Mask = 127,
                StartDate = new System.DateTime(2016, 01, 01),
                EndDate = new System.DateTime(2016, 01, 10)
            };
            calendar1.TrimDates();
            calendar2 = new Calendar()
            {
                ServiceId = "0",
                Mask = 127,
                StartDate = new System.DateTime(2016, 01, 11),
                EndDate = new System.DateTime(2016, 01, 17)
            };
            calendar2.TrimDates();

            Assert.IsTrue(calendar1.TryMerge(calendar2, out merge));
            Assert.AreEqual("0", merge.ServiceId);
            Assert.AreEqual(127, merge.Mask);
            Assert.AreEqual(new System.DateTime(2016, 01, 01), merge.StartDate);
            Assert.AreEqual(new System.DateTime(2016, 01, 17), merge.EndDate);
        }
Exemple #5
0
        /// <summary>
        /// Tries to merge two calendars together.
        /// </summary>
        /// <returns></returns>
        public static bool TryMerge(this Calendar calendar, Calendar other, out Calendar merge)
        {
            if(calendar.ServiceId != other.ServiceId)
            {
                throw new InvalidOperationException("Cannot merge calendars with different service id's.");
            }

            var calendarMonday = calendar.StartDate.FirstDayOfWeek();
            var otherMonday = other.StartDate.FirstDayOfWeek();
            if(calendarMonday > otherMonday)
            { // switch the two, assume that calendar 'before' other.
                var temp = calendar;
                calendar = other;
                other = temp;

                calendarMonday = calendar.StartDate.FirstDayOfWeek();
                otherMonday = other.StartDate.FirstDayOfWeek();
            }

            var otherStartMonday = other.StartDate.FirstDayOfWeek();
            var calendarEndSunday = calendar.EndDate.LastDayOfWeek();
            if (calendarEndSunday.AddDays(1) != otherStartMonday &&
                calendarMonday != otherMonday)
            { // cannot merge, differ more than a week.
                merge = null;
                return false;
            }

            // check if masks match and merge.
            var mergedMask = new bool[7];
            for (var i = 0; i < 7; i++)
            {
                var calendarStatus = calendar.GetStatusFor(calendarMonday.AddDays(i));
                var otherStatus = other.GetStatusFor(otherMonday.AddDays(i));

                if (calendarStatus == null)
                {
                    mergedMask[i] = otherStatus == null ? false : otherStatus.Value;
                }
                else if (otherStatus == null)
                {
                    mergedMask[i] = calendarStatus == null ? false : calendarStatus.Value;
                }
                else if (otherStatus.Value != calendarStatus.Value)
                { // impossible to merge conflicting statuses.
                    merge = null;
                    return false;
                }
                else
                {
                    mergedMask[i] = calendarStatus.Value;
                }
            }

            merge = new Calendar()
            {
                StartDate = calendar.StartDate < other.StartDate ?  calendar.StartDate : other.StartDate,
                EndDate = other.EndDate > calendar.EndDate ? other.EndDate : calendar.EndDate,
                ServiceId = calendar.ServiceId,
                Monday = mergedMask[0],
                Tuesday = mergedMask[1],
                Wednesday = mergedMask[2],
                Thursday = mergedMask[3],
                Friday = mergedMask[4],
                Saturday = mergedMask[5],
                Sunday = mergedMask[6],
            };
            merge.TrimDates();
            return true;
        }
Exemple #6
0
        /// <summary>
        /// Subtracts the given calendar day and returns one or more new calendar entities representing the same data.
        /// </summary>
        public static IEnumerable<Calendar> Subtract(this Calendar calendar, DateTime day)
        {
            if (!calendar.CoversDate(day))
            { // no work needs to be done.
                return new Calendar[] { calendar };
            }

            var firstDayOfWeek = day.FirstDayOfWeek();
            var lastDayOfWeek = day.LastDayOfWeek();

            if(firstDayOfWeek <= calendar.StartDate &&
               lastDayOfWeek >= calendar.EndDate)
            { // yay! this is exceptional but let's take advantage of this.
                calendar[day.DayOfWeek] = false;
                return new Calendar[] { calendar };
            }

            // possibly split in two or three pieces.
            if(firstDayOfWeek <= calendar.StartDate)
            { // two pieces, a first week with the day substracted and the rest.
                var subtracted = new Calendar()
                {
                    StartDate = calendar.StartDate,
                    EndDate = lastDayOfWeek
                };
                subtracted.CopyWeekPatternFrom(calendar);
                subtracted[day.DayOfWeek] = false;

                var rest = new Calendar()
                {
                    StartDate = lastDayOfWeek.AddDays(1),
                    EndDate = calendar.EndDate
                };
                rest.CopyWeekPatternFrom(calendar);
                return new Calendar[] { subtracted, rest };
            }
            else if (lastDayOfWeek >= calendar.EndDate)
            { // two pieces, a last week with the day substracted and the rest.
                var rest = new Calendar()
                {
                    StartDate = calendar.StartDate,
                    EndDate = firstDayOfWeek.AddDays(-1)
                };
                rest.CopyWeekPatternFrom(calendar);

                var subtracted = new Calendar()
                {
                    StartDate = firstDayOfWeek,
                    EndDate = calendar.EndDate
                };
                subtracted.CopyWeekPatternFrom(calendar);
                subtracted[day.DayOfWeek] = false;
                return new Calendar[] { rest, subtracted };
            }
            else
            { // three pieces, a first period, a week with the day subtracted and a last period.
                var rest1 = new Calendar()
                {
                    StartDate = calendar.StartDate,
                    EndDate = firstDayOfWeek.AddDays(-1)
                };
                rest1.CopyWeekPatternFrom(calendar);

                var subtracted = new Calendar()
                {
                    StartDate = firstDayOfWeek,
                    EndDate = lastDayOfWeek
                };
                subtracted.CopyWeekPatternFrom(calendar);
                subtracted[day.DayOfWeek] = false;

                var rest2 = new Calendar()
                {
                    StartDate = lastDayOfWeek.AddDays(1),
                    EndDate = calendar.EndDate
                };
                rest2.CopyWeekPatternFrom(calendar);
                return new Calendar[] { rest1, subtracted, rest2 };
            }
        }
Exemple #7
0
 /// <summary>
 /// Creates a calendar entity for the day.
 /// </summary>
 /// <returns></returns>
 public static Calendar CreateCalendar(this DateTime day, string serviceId)
 {
     var calendar = new Calendar()
     {
         StartDate = day,
         EndDate = day,
         ServiceId = serviceId
     };
     calendar[day.DayOfWeek] = true;
     return calendar;
 }