天天看點

Quartz.Net系列(九):Trigger之DailyTimeIntervalScheduleBuilder詳解

1.介紹

中文意義就是每日時間間隔計劃生成

2.API講解

(1)WithInterval、WithIntervalInHours、WithIntervalInMinutes、WithIntervalInSeconds

WithInterval:指定要生成觸發器的時間機關和間隔。

WithIntervalInHours:指定要生成觸發器的間隔按小時來

WithIntervalInMinutes:指定要生成觸發器的間隔按分鐘來

WithIntervalInSeconds:指定要生成觸發器的間隔按秒來

和前面的SimpleSceduleBuilder、CalendarIntervalScheduleBuilder一樣的

(2)OnDaysOfTheWeek、OnMondayThroughFriday、OnSaturdayAndSunday、OnEveryDay

OnDaysOfTheWeek:設定觸發器一周中的哪幾天

OnMondayThroughFriday:從星期一到星期五

OnSaturdayAndSunday:周六和周日

OnEveryDay:每天

每天10:00到23:10.00的每一分鐘執行一次

var trigger = TriggerBuilder.Create().WithDailyTimeIntervalSchedule(
                  w => w.OnEveryDay() //設定每天
                      .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(10, 00)) //設定每天開始于幾點
                      .EndingDailyAt(TimeOfDay.HourMinuteAndSecondOfDay(23, 10, 0)) //設定每日結束于幾點
                      .WithIntervalInMinutes(1)//間隔分鐘
                ).Build();      

一周當中的星期二和星期三每秒執行一次

List<DayOfWeek> dayOfWeeks = new List<DayOfWeek>();

            dayOfWeeks.Add(DayOfWeek.Wednesday);

            dayOfWeeks.Add(DayOfWeek.Tuesday);

            trigger = TriggerBuilder.Create().WithDailyTimeIntervalSchedule(
                 w=>w.OnDaysOfTheWeek(dayOfWeeks)//.OnDaysOfTheWeek(new DayOfWeek[2] { DayOfWeek.Wednesday,DayOfWeek.Tuesday})
                     .WithIntervalInSeconds(1)
                ).Build();      
Quartz.Net系列(九):Trigger之DailyTimeIntervalScheduleBuilder詳解

 源碼實作

/// <summary>
        /// Set the trigger to fire on the given days of the week.
        /// </summary>
        /// <param name="onDaysOfWeek">a Set containing the integers representing the days of the week, defined by <see cref="DayOfWeek.Sunday"/> - <see cref="DayOfWeek.Saturday"/>.
        /// </param>
        /// <returns>the updated DailyTimeIntervalScheduleBuilder</returns>
        public DailyTimeIntervalScheduleBuilder OnDaysOfTheWeek(IReadOnlyCollection<DayOfWeek> onDaysOfWeek)
        {
            if (onDaysOfWeek == null || onDaysOfWeek.Count == 0)
            {
                throw new ArgumentException("Days of week must be an non-empty set.");
            }

            foreach (DayOfWeek day in onDaysOfWeek)
            {
                if (!AllDaysOfTheWeek.Contains(day))
                {
                    throw new ArgumentException("Invalid value for day of week: " + day);
                }
            }

            daysOfWeek = new HashSet<DayOfWeek>(onDaysOfWeek);
            return this;
        }

        /// <summary>
        /// Set the trigger to fire on the given days of the week.
        /// </summary>
        /// <param name="onDaysOfWeek">a variable length list of week days representing the days of the week</param>
        /// <returns>the updated DailyTimeIntervalScheduleBuilder</returns>
        public DailyTimeIntervalScheduleBuilder OnDaysOfTheWeek(params DayOfWeek[] onDaysOfWeek)
        {
            return OnDaysOfTheWeek((IReadOnlyCollection<DayOfWeek>) onDaysOfWeek);
        }

        /// <summary>
        /// Set the trigger to fire on the days from Monday through Friday.
        /// </summary>
        /// <returns>the updated DailyTimeIntervalScheduleBuilder</returns>
        public DailyTimeIntervalScheduleBuilder OnMondayThroughFriday()
        {
            daysOfWeek = new HashSet<DayOfWeek>(MondayThroughFriday);
            return this;
        }

        /// <summary>
        /// Set the trigger to fire on the days Saturday and Sunday.
        /// </summary>
        /// <returns>the updated DailyTimeIntervalScheduleBuilder</returns>
        public DailyTimeIntervalScheduleBuilder OnSaturdayAndSunday()
        {
            daysOfWeek = new HashSet<DayOfWeek>(SaturdayAndSunday);
            return this;
        }

        /// <summary>
        /// Set the trigger to fire on all days of the week.
        /// </summary>
        /// <returns>the updated DailyTimeIntervalScheduleBuilder</returns>
        public DailyTimeIntervalScheduleBuilder OnEveryDay()
        {
            daysOfWeek = new HashSet<DayOfWeek>(AllDaysOfTheWeek);
            return this;
        }      

(3)StartingDailyAt、EndingDailyAt

StartingDailyAt:開始時間于

EndingDailyAt:結束時間于

源碼實作

/// <summary>
        /// The TimeOfDay for this trigger to start firing each day.
        /// </summary>
        /// <param name="timeOfDayUtc"></param>
        /// <returns>the updated DailyTimeIntervalScheduleBuilder</returns>
        public DailyTimeIntervalScheduleBuilder StartingDailyAt(TimeOfDay timeOfDayUtc)
        {
            startTimeOfDayUtc = timeOfDayUtc ?? throw new ArgumentException("Start time of day cannot be null!");
            return this;
        }

        /// <summary>
        /// The TimeOfDay for this trigger to end firing each day.
        /// </summary>
        /// <param name="timeOfDayUtc"></param>
        /// <returns>the updated DailyTimeIntervalScheduleBuilder</returns>
        public DailyTimeIntervalScheduleBuilder EndingDailyAt(TimeOfDay timeOfDayUtc)
        {
            endTimeOfDayUtc = timeOfDayUtc;
            return this;
        }      

(4)EndingDailyAfterCount

EndingDailyAfterCount:使用count、interval和StarTimeOfDay計算并設定EndTimeOfDay。

源碼實作

/// <summary>
        /// Calculate and set the EndTimeOfDay using count, interval and StarTimeOfDay. This means
        /// that these must be set before this method is call.
        /// </summary>
        /// <param name="count"></param>
        /// <returns>the updated DailyTimeIntervalScheduleBuilder</returns>
        public DailyTimeIntervalScheduleBuilder EndingDailyAfterCount(int count)
        {
            if (count <= 0)
            {
                throw new ArgumentException("Ending daily after count must be a positive number!");
            }

            if (startTimeOfDayUtc == null)
            {
                throw new ArgumentException("You must set the StartDailyAt() before calling this EndingDailyAfterCount()!");
            }

            DateTimeOffset today = SystemTime.UtcNow();
            DateTimeOffset startTimeOfDayDate = startTimeOfDayUtc.GetTimeOfDayForDate(today).Value;
            DateTimeOffset maxEndTimeOfDayDate = TimeOfDay.HourMinuteAndSecondOfDay(23, 59, 59).GetTimeOfDayForDate(today).Value;

            //apply proper offsets according to timezone
            TimeZoneInfo targetTimeZone = timeZone ?? TimeZoneInfo.Local;
            startTimeOfDayDate = new DateTimeOffset(startTimeOfDayDate.DateTime, TimeZoneUtil.GetUtcOffset(startTimeOfDayDate.DateTime, targetTimeZone));
            maxEndTimeOfDayDate = new DateTimeOffset(maxEndTimeOfDayDate.DateTime, TimeZoneUtil.GetUtcOffset(maxEndTimeOfDayDate.DateTime, targetTimeZone));

            TimeSpan remainingMillisInDay = maxEndTimeOfDayDate - startTimeOfDayDate;
            TimeSpan intervalInMillis;
            if (intervalUnit == IntervalUnit.Second)
            {
                intervalInMillis = TimeSpan.FromSeconds(interval);
            }
            else if (intervalUnit == IntervalUnit.Minute)
            {
                intervalInMillis = TimeSpan.FromMinutes(interval);
            }
            else if (intervalUnit == IntervalUnit.Hour)
            {
                intervalInMillis = TimeSpan.FromHours(interval);
            }
            else
            {
                throw new ArgumentException("The IntervalUnit: " + intervalUnit + " is invalid for this trigger.");
            }

            if (remainingMillisInDay < intervalInMillis)
            {
                throw new ArgumentException("The startTimeOfDay is too late with given Interval and IntervalUnit values.");
            }

            long maxNumOfCount = remainingMillisInDay.Ticks / intervalInMillis.Ticks;
            if (count > maxNumOfCount)
            {
                throw new ArgumentException("The given count " + count + " is too large! The max you can set is " + maxNumOfCount);
            }

            TimeSpan incrementInMillis = TimeSpan.FromTicks((count - 1) * intervalInMillis.Ticks);
            DateTimeOffset endTimeOfDayDate = startTimeOfDayDate.Add(incrementInMillis);

            if (endTimeOfDayDate > maxEndTimeOfDayDate)
            {
                throw new ArgumentException("The given count " + count + " is too large! The max you can set is " + maxNumOfCount);
            }

            DateTime cal = SystemTime.UtcNow().Date;
            cal = cal.Add(endTimeOfDayDate.TimeOfDay);
            endTimeOfDayUtc = TimeOfDay.HourMinuteAndSecondOfDay(cal.Hour, cal.Minute, cal.Second);
            return this;
        }