Exemplo n.º 1
0
        ///-------------------------------------------------------------------------------------------------
        /// <summary>	Adds a yearly day of week reverse event. </summary>
        ///
        /// <remarks>
        ///     Selects events yearly events that occur on a certain day of the week, and week going
        ///     reverse from the end of the month. Example: Memorial day is on the last Monday of May.
        /// </remarks>
        ///
        /// <exception cref="ArgumentNullException">
        ///     Thrown when eventName is null or empty.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///     Thrown when eventName is not unique or startDate > endDate.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     Thrown when month is out of range [1...12] or when day is out of range for the given
        ///     month.
        /// </exception>
        ///
        /// <param name="eventName">    Name of the event, must be unique. </param>
        /// <param name="dayOff">	    True if is a day off (is a workday). </param>
        /// <param name="month">	    The month. </param>
        /// <param name="weeksReverse">	Weeks reverse from the end of the month. </param>
        /// <param name="dayOfWeek">    The day of week. </param>
        /// <param name="startDate">    (Optional) The date start, DateTime.MinValue if null. </param>
        /// <param name="endDate">	    (Optional) The date end, DateTime.MaxValue if null. </param>
        ///
        /// <example>
        ///     <code>
        ///     // Labor Day is the last Monday in May (US), usually the 4 week but not always.
        ///     CalendarDateTime.AddYearlyDayOfWeekReverseEvent("Labor Day", true, 1, DayOfWeek.Monday);
        ///     </code>
        /// </example>
        ///-------------------------------------------------------------------------------------------------
        public static void AddYearlyDayOfWeekReverseEvent([CanBeNull] string eventName, bool dayOff, int month, int weeksReverse, DayOfWeek dayOfWeek, DateTime?startDate = null, DateTime?endDate = null)
        {
            if (string.IsNullOrEmpty(eventName))
            {
                throw new ArgumentNullException(nameof(eventName), ErrorMessageCannotBeNullOrEmpty(nameof(eventName)));
            }

            if (ContainsEventKey(eventName))
            {
                throw new ArgumentException(ErrorMessageKeyAlreadyAdded(nameof(eventName), eventName), nameof(eventName));
            }

            if (1 > month || month > 12)
            {
                throw new ArgumentOutOfRangeException(nameof(month), ErrorMessageMinMaxOutOfRange(month, nameof(month), 1, 12));
            }

            if (weeksReverse < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(weeksReverse), ErrorMessageZeroOrNegative(nameof(weeksReverse), weeksReverse));
            }

            var dateRange = new MinMaxSwapDate(startDate, endDate);

            YearlyEventsDictionary.Add(eventName, new YearlyDayOfWeekReverseEvent(dayOff, month, dayOfWeek, weeksReverse, dateRange.Min, dateRange.Max));
        }
Exemplo n.º 2
0
        ///-------------------------------------------------------------------------------------------------
        /// <summary>	Adds a yearly date event. </summary>
        ///
        /// <remarks>
        ///     Selects yearly event on certain day of the month. If true, saturdayBack will shift
        ///     celebration to Friday. If true, sundayForward will shift the celebration forward. New
        ///     Years day is often shifted around the weekends.
        /// </remarks>
        ///
        /// <exception cref="ArgumentNullException">
        ///     Thrown when eventName is null or empty.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///     Thrown when eventName is not unique or startDate > endDate.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     Thrown when month is out of range [1...12] or when day is out of range for the given
        ///     month.
        /// </exception>
        ///
        /// <param name="eventName">		Name of the event, must be unique. </param>
        /// <param name="dayOff">			True if is a day off (is a workday). </param>
        /// <param name="month">			The month. </param>
        /// <param name="day">				The day. </param>
        /// <param name="saturdayBack">     True to shift back to Friday if on Saturday. </param>
        /// <param name="sundayForward">	True to shift forward to Monday if on Sunday. </param>
        /// <param name="startDate">		(Optional) The start date. </param>
        /// <param name="endDate">			(Optional) The end date. </param>
        ///
        /// <example>
        ///     <code>
        ///     // New Year's day, Jan 1, if on Saturday do not shift, if on Sunday then celebrate on Monday.
        ///     CalendarDateTime("New Years Day", true, 1, 1, false, true);
        ///     </code>
        /// </example>
        ///-------------------------------------------------------------------------------------------------
        public static void AddYearlyDateEvent([CanBeNull] string eventName, bool dayOff, int month, int day, bool saturdayBack, bool sundayForward, DateTime?startDate = null, DateTime?endDate = null)
        {
            if (string.IsNullOrEmpty(eventName))
            {
                throw new ArgumentNullException(nameof(eventName), ErrorMessageCannotBeNullOrEmpty(nameof(eventName)));
            }

            if (ContainsEventKey(eventName))
            {
                throw new ArgumentException(ErrorMessageKeyAlreadyAdded(nameof(eventName), eventName), eventName);
            }

            if (month < 1 || 12 < month)
            {
                throw new ArgumentOutOfRangeException(nameof(month), ErrorMessageMinMaxOutOfRange(month, nameof(month), 1, 12));
            }

            if (day < 1 || day > MaxDaysInMonthEstimated(month))
            {
                throw new ArgumentOutOfRangeException(nameof(day), ErrorMessageMinMaxOutOfRange(day, nameof(day), 1, MaxDaysInMonthEstimated(month)));
            }

            var dateRange = new MinMaxSwapDate(startDate, endDate);

            YearlyEventsDictionary.Add(eventName, new YearlyMonthDatedEvent(dayOff, month, day, saturdayBack, sundayForward, dateRange.Min, dateRange.Max));
        }
Exemplo n.º 3
0
        ///-------------------------------------------------------------------------------------------------
        /// <summary>	Adds a yearly calculated event. </summary>
        ///
        /// <remarks>
        ///     Selects events what are mathematically derived, Easter Sunday and Good Friday.
        /// </remarks>
        ///
        /// <exception cref="ArgumentNullException">	Thrown when eventName is null or empty. </exception>
        /// <exception cref="ArgumentException">
        ///     Thrown when eventName is not either "EasterSunday" or "GoodFriday" or startDate >
        ///     endDate.
        /// </exception>
        ///
        /// <param name="eventName">	Name of the event, must be unique. </param>
        /// <param name="dayOff">       True if is a day off (is a workday). </param>
        /// <param name="startDate">	(Optional) The date start, DateTime.MinValue if null. </param>
        /// <param name="endDate">      (Optional) The date end, DateTime.MaxValue if null. </param>
        ///
        /// <example>
        ///     <code>
        ///     // Note: Properties ending in "Text" (CalculatedEventsText.EasterSunday) are provided as convenience and to improve robustness.
        ///     CalendarDateTime.AddYearlyCalculatedEvent(CalculatedEventsText.EasterSunday, true);
        ///     CalendarDateTime.AddYearlyCalculatedEvent(CalculatedEventsText.GoodFriday, true);
        ///     // Test:
        ///     var easterDate2018 = new DateTime(2018, 4, 1);
        ///     var result = easterDate2018.EventsOnDate(false, true);
        ///     // [0] = "Easter Sunday"
        ///     </code>
        /// </example>
        ///-------------------------------------------------------------------------------------------------
        public static void AddYearlyCalculatedEvent([CanBeNull] string eventName, bool dayOff, DateTime?startDate = null, DateTime?endDate = null)
        {
            if (string.IsNullOrEmpty(eventName))
            {
                throw new ArgumentNullException(nameof(eventName), ErrorMessageCannotBeNullOrEmpty(nameof(eventName)));
            }

            if (ContainsEventKey(eventName))
            {
                throw new ArgumentException(ErrorMessageKeyAlreadyAdded(nameof(eventName), eventName), nameof(eventName));
            }

            var dateRange = new MinMaxSwapDate(startDate, endDate);

            if (eventName == CalculatedEventsText.GoodFriday)
            {
                YearlyEventsDictionary.Add(CalculatedEventsText.GoodFriday, new YearlyCalculatedEvent(dayOff, GoodFridayDate, dateRange.Min, dateRange.Max));
            }
            else if (eventName == CalculatedEventsText.EasterSunday)
            {
                YearlyEventsDictionary.Add(CalculatedEventsText.EasterSunday, new YearlyCalculatedEvent(dayOff, EasterSundayDate, dateRange.Min, dateRange.Max));
            }
            else
            {
                throw new ArgumentException(ErrorMessageEasterSundayGoodFriday(nameof(eventName), eventName));
            }
        }
Exemplo n.º 4
0
        ///-------------------------------------------------------------------------------------------------
        /// <summary>	A DateTime extension method that returns list of events on date. </summary>
        ///
        /// <param name="date">			    The date. </param>
        /// <param name="includeWorkdays">	True to include, false to include workday events. </param>
        /// <param name="includeDaysOff">   True to disable, false to include days off events. </param>
        ///
        /// <returns>	An ImmutableArray&lt;string&gt; </returns>
        ///
        /// <example>
        ///     <code>
        ///     CalendarDateTime.AddYearlyDateEvent("myBirthday", true, 5, 20, false, false);
        ///     var aDate = new DateTime(2018, 5, 20, 5, 30, 0);
        ///     var events = aDate.EventsOnDate(true, true);
        ///     // events = [0] = "myBirthday"
        ///     </code>
        /// </example>
        ///-------------------------------------------------------------------------------------------------
        public static ImmutableArray <string> EventsOnDate(this DateTime date, bool includeWorkdays, bool includeDaysOff)
        {
            date = date.Date;
            var events = new List <string>();

            var yearlyEvents = YearlyEventsDictionary
                               .Where(v => date.IsBetweenEqual(v.Value.DateStart, v.Value.DateEnd) &&
                                      (v.Value.DayOff && includeDaysOff || v.Value.WorkDay && includeWorkdays) &&
                                      v.Value.Date(date.Year) == date)
                               .Select(k => k.Key);

            var monthlyEvents = MonthlyEventsDictionary
                                .Where(v => date.IsBetweenEqual(v.Value.DateStart, v.Value.DateEnd) &&
                                       (v.Value.DayOff && includeDaysOff || v.Value.WorkDay && includeWorkdays) &&
                                       v.Value.Date(date.Year, date.Month) == date)
                                .Select(k => k.Key);

            var weeklyEvents = WeeklyEventsDictionary
                               .Where(v => date.IsBetweenEqual(v.Value.DateStart, v.Value.DateEnd) &&
                                      (v.Value.DayOff && includeDaysOff || v.Value.WorkDay && includeWorkdays) &&
                                      v.Value.IsEventDay(date))
                               .Select(k => k.Key);

            var dateEvents = DateEventsDictionary
                             .Where(v => (v.Value.DayOff && includeDaysOff || v.Value.WorkDay && includeWorkdays) &&
                                    v.Value.Date == date)
                             .Select(k => k.Key);

            events.AddRange(yearlyEvents);
            events.AddRange(monthlyEvents);
            events.AddRange(weeklyEvents);
            events.AddRange(dateEvents);
            return(events.ToImmutableArray());
        }
Exemplo n.º 5
0
        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///     A DateTime extension method that query if 'date' is day off. The days off is configured
        ///     using the Add-calendar event methods.
        /// </summary>
        ///
        /// <param name="date">	The date. </param>
        ///
        /// <returns>	True if day off, false if not. </returns>
        ///
        /// <example>
        ///     <code>
        ///     // LINQ example.
        ///     var starting = new DateTime(2018, 1, 1);
        ///     var ending = new DateTime(2018, 12, 31);
        ///     var allDates = Enumerable.Range(0, 1 + ending.Subtract(starting).Days).Select(i=&gt; starting.AddDays(i));
        ///
        ///     CalendarDateTime.AddYearlyDateEvent("theDate", true, 6, 10, false, false);
        ///     var result = allDates.Where(d =&gt; d.IsDayOff());
        ///     // result = [0] = {6/10/2018 12:00:00 AM}
        ///     </code>
        /// </example>
        ///-------------------------------------------------------------------------------------------------
        public static bool IsDayOff(this DateTime date)
        {
            date = date.Date;
            var p = YearlyEventsDictionary.Any(v => v.Value.DayOff && v.Value.Date(date.Year) == date);
            var m = MonthlyEventsDictionary.Any(v => v.Value.DayOff && v.Value.Date(date.Year, date.Month) == date);
            var w = WeeklyEventsDictionary.Any(v => v.Value.DayOff && v.Value.IsEventDay(date));
            var a = DateEventsDictionary.Any(v => v.Value.DayOff && v.Value.Date == date);

            return(p || m || w || a);
        }