The results of a ITextToSchedule.Parse. You can register the given schedule with methods defined in the class.
        /// <summary>
        /// Parses the specified text into a schedule object with the given time zone.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <param name="timeZone">The time zone.</param>
        /// <returns></returns>
        public TextToScheduleResults Parse(string text, TimeZoneInfo timeZone)
        {
            if (text == null)
                return null;

            var expressions = Prepare(text);
            TextToScheduleResults results = new TextToScheduleResults();

            foreach (var cron in expressions)
            {
                results.Add(
                    TriggerBuilder.Create()
                    .WithCronSchedule(cron, sb => sb.InTimeZone(timeZone)));
            }

            return results;
        }
Example #2
0
        /// <summary>
        /// Parses the specified text into a schedule object with the given time zone.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <param name="timeZone">The time zone.</param>
        /// <returns></returns>
        public TextToScheduleResults Parse(string text, TimeZoneInfo timeZone)
        {
            if (text == null)
            {
                return(null);
            }

            var expressions = Prepare(text);
            TextToScheduleResults results = new TextToScheduleResults();

            foreach (var cron in expressions)
            {
                results.Add(
                    TriggerBuilder.Create()
                    .WithCronSchedule(cron, sb => sb.InTimeZone(timeZone)));
            }

            return(results);
        }
        /// <summary>
        /// Parses the specified text into a schedule object with the given time zone.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <param name="timeZone">The time zone.</param>
        /// <returns></returns>
        public TextToScheduleResults Parse(string text, TimeZoneInfo timeZone)
        {
            text = GrammarHelper.Normalize(text);

            TextToScheduleResults results = new TextToScheduleResults();
            bool matched = false;

            if (ExecuteMatch(Grammar.Expression1, text, timeZone, results, Expression1Handler))
            {
                matched = true;
            }
            else if (ExecuteMatch(Grammar.Expression2, text, timeZone, results, Expression2Handler))
            {
                matched = true;
            }
            else if (ExecuteMatch(Grammar.Expression3, text, timeZone, results, Expression3Handler))
            {
                matched = true;
            }
            else if (ExecuteMatch(Grammar.Expression4, text, timeZone, results, Expression4Handler))
            {
                matched = true;
            }
            else if (ExecuteMatch(Grammar.Expression5, text, timeZone, results, Expression5Handler))
            {
                matched = true;
            }


            if (matched)
            {
                return(results);
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        /// Parses the specified text into a schedule object with the given time zone.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <param name="timeZone">The time zone.</param>
        /// <returns></returns>
        public TextToScheduleResults Parse(string text, TimeZoneInfo timeZone)
        {
            text = GrammarHelper.Normalize(text);

            TextToScheduleResults results = new TextToScheduleResults();
            bool matched = false;

            if (ExecuteMatch(Grammar.Expression1, text, timeZone, results, Expression1Handler))
            {
                matched = true;
            }
            else if (ExecuteMatch(Grammar.Expression2, text, timeZone, results, Expression2Handler))
            {
                matched = true;
            }
            else if (ExecuteMatch(Grammar.Expression3, text, timeZone, results, Expression3Handler))
            {
                matched = true;
            }
            else if (ExecuteMatch(Grammar.Expression4, text, timeZone, results, Expression4Handler))
            {
                matched = true;
            }
            else if (ExecuteMatch(Grammar.Expression5, text, timeZone, results, Expression5Handler))
            {
                matched = true;
            }


            if (matched)
            {
                return results;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Method that matches an expression, and if it does will run the associated method
        /// </summary>
        /// <param name="expression">The expression.</param>
        /// <param name="input">The input.</param>
        /// <param name="results">The results.</param>
        /// <param name="matchFunction">The match function to run if it matches.</param>
        /// <returns></returns>
        private static bool ExecuteMatch(string expression, string input, TimeZoneInfo timeZone, TextToScheduleResults results, Action<NameValueCollection, TimeZoneInfo, TextToScheduleResults> matchFunction)
        {
            expression = "^" + expression + "$";

            var dic = RegexHelper.GetNamedMatches(input, expression);

            if (dic != null)
            {
                matchFunction(dic, timeZone, results);
                return true;
            }

            return false;
        }
        /// <summary>
        /// Handles with a given text matches the Expression5 field.
        /// </summary>
        /// <param name="nameValueCollection">A collection of values from the named capture groups.</param>
        /// <param name="results">The results.</param>
        private void Expression5Handler(NameValueCollection nameValueCollection, TimeZoneInfo timeZone, TextToScheduleResults results)
        {
            var days = nameValueCollection.GetValues("DAY");
            var months = nameValueCollection.GetValues("MONTH");
            var timesToFire = nameValueCollection.GetValues("TIME");

            var dayValues = days.Select(day => GrammarHelper.GetDayValue(day))
                .Select(day => GetDayCronValue(day).ToList());

            List<string> cronExpressions = new List<string>();
            
            string cron_day = "*";
            string cron_month = "*";

            if (days != null)
            {
                var targetDays = days.Select(x => GrammarHelper.GetDayValue(x));
                var targetDayCron = targetDays.Select(x => GetDayCronValue(x));
                cron_day = string.Join(",", targetDayCron);
            }

            if (months != null)
            {
                var targetMonths = GrammarHelper.GetMonthValues(months);
                var targetMonthsCron = targetMonths.Select(x => GetMonthCronValue(x));
                cron_month = string.Join(",", targetMonthsCron);                    
            }

            if (timesToFire == null) // if times are not specified assume midnight
                timesToFire = new string[] { "00:00" };

            foreach (var item in timesToFire)
            {
                var time = GrammarHelper.GetTimeFromTimeString(item).Value;

                string cron_sec = time.Second.ToString();
                string cron_min = time.Minute.ToString();
                string cron_hour = time.Hour.ToString();

                string cronString = string.Format("{0} {1} {2} {3} {4} ?",
                    cron_sec, cron_min, cron_hour, cron_day, cron_month);
                
                cronExpressions.Add(cronString);
            }

            foreach (var cron in cronExpressions)
            {
                var triggerBuilder = TriggerBuilder.Create();

                IScheduleBuilder schedule = CreateScheduleWithCron(cron, timeZone);
                triggerBuilder.WithSchedule(schedule);

                results.Add(triggerBuilder);
            }
        }
        /// <summary>
        /// Handles with a given text matches the Expression4 field.
        /// </summary>
        /// <param name="nameValueCollection">A collection of values from the named capture groups.</param>
        /// <param name="results">The results.</param>
        private void Expression4Handler(NameValueCollection nameValueCollection, TimeZoneInfo timeZone, TextToScheduleResults results)
        {
            // every [n] (days|weeks|months|years) (from [date]) (at [time])

            string amountString = nameValueCollection["AMOUNT"];
            string intervalString = nameValueCollection["INTERVALUNIT"];

            var dateSpec = nameValueCollection["DATESPEC"];
            var dayOfWeekSpecs = nameValueCollection.GetValues("DAYOFWEEK");
            var timesToFire = nameValueCollection.GetValues("TIME");

            DateTime? triggerStartTime = null;

            if (dayOfWeekSpecs != null && GrammarHelper.GetIntervalUnitValueFromString(intervalString) != IntervalUnit.Week)
            {
                throw new Exception("You should only specify a day of the week, when you are using the \"week\" time interval.");
            }

            if (timesToFire == null) // if times are not specified assume midnight
                timesToFire = new string[] { "00:00" };

            foreach (var timeString in timesToFire)
            {
                if (dateSpec != null || timeString != null)
                    triggerStartTime = GrammarHelper.GetDateTimeFromDateSpecAndTime(dateSpec, timeString);

                if (dayOfWeekSpecs != null)
                {
                    var dayOfWeeks = GrammarHelper.GetDayOfWeekValues(dayOfWeekSpecs);
                    foreach (var dayOfWeek in dayOfWeeks)
                    {
                        if (triggerStartTime == null)
                            triggerStartTime = SystemTime.Now().DateTime;

                        DateTime dowTriggerStartTime = triggerStartTime.Value;
                        //seek
                        dowTriggerStartTime = SeekForwardToNextDayOfWeek(dowTriggerStartTime, dayOfWeek);

                        TriggerBuilder triggerBuilder = TriggerBuilder.Create();
                        triggerBuilder.WithSchedule(CreateScheduleWithAmountAndIntervalUnit(amountString, intervalString, timeZone));
                        triggerBuilder.StartAt(new DateTimeOffset(dowTriggerStartTime, timeZone.GetUtcOffset(dowTriggerStartTime)));

                        results.Add(triggerBuilder, null);
                    }
                }
                else
                {
                    TriggerBuilder triggerBuilder = TriggerBuilder.Create();
                    triggerBuilder.WithSchedule(CreateScheduleWithAmountAndIntervalUnit(amountString, intervalString, timeZone));

                    //start on from time
                    if (triggerStartTime != null)
                        triggerBuilder.StartAt(new DateTimeOffset(triggerStartTime.Value, timeZone.GetUtcOffset(triggerStartTime.Value)));

                    results.Add(triggerBuilder, null);
                }
            }
        }
        /// <summary>
        /// Handles with a given text matches the Expression3 field.
        /// </summary>
        /// <param name="nameValueCollection">A collection of values from the named capture groups.</param>
        /// <param name="results">The results.</param>
        private void Expression3Handler(NameValueCollection nameValueCollection, TimeZoneInfo timeZone, TextToScheduleResults results)
        {
            var timesToFire = nameValueCollection.GetValues("TIME");

            var dateSpec = nameValueCollection["DATESPEC"];
            var monthString = nameValueCollection["MONTH"];
            var dayString = nameValueCollection["DAY"];
            var yearString = nameValueCollection["YEAR"];

            //init cron values
            List<string> cronExpressions = new List<string>();

            if (timesToFire == null) // if times are not specified assume midnight
                timesToFire = new string[] { "00:00" };

            foreach (var time in timesToFire)
            {
                DateTime date = DateTime.Today; //default date to today

                if (time != null)
                {
                    date = GrammarHelper.GetTimeFromTimeString(time).Value;
                }

                string cron_sec = date.Second.ToString();
                string cron_min = date.Minute.ToString();
                string cron_hour = date.Hour.ToString();
                string cron_day = "*";
                string cron_month = "*";
                string cron_dayofWeek = "?";
                string cron_year = null;

                cron_month = GetMonthCronValue(GrammarHelper.GetMonthValue(monthString));

                if (dayString != null)
                    cron_day = GetDayCronValue(GrammarHelper.GetDayValue(dayString));
                else
                    cron_day = GetDayCronValue(1);

                if (yearString != null)
                    cron_year = GetYearCronValue(GrammarHelper.GetYearValue(yearString));


                //build cron string
                string cronString = null;

                if (cron_year != null)
                    cronString = string.Format(string.Join(" ", new string[] { cron_sec, cron_min, cron_hour, cron_day, cron_month, cron_dayofWeek, cron_year }));
                else
                    cronString = string.Format(string.Join(" ", new string[] { cron_sec, cron_min, cron_hour, cron_day, cron_month, cron_dayofWeek }));

                //add cron string
                cronExpressions.Add(cronString);
            }

            foreach (var cron in cronExpressions)
            {
                var triggerBuilder = TriggerBuilder.Create();

                IScheduleBuilder schedule = CreateScheduleWithCron(cron, timeZone);
                triggerBuilder.WithSchedule(schedule);

                results.Add(triggerBuilder);
            }
        }
        /// <summary>
        /// Handles with a given text matches the Expression2 field.
        /// </summary>
        /// <param name="nameValueCollection">A collection of values from the named capture groups.</param>
        /// <param name="results">The results.</param>
        private void Expression2Handler(NameValueCollection nameValueCollection, TimeZoneInfo timeZone, TextToScheduleResults results)
        {
            var timesToFire = nameValueCollection.GetValues("TIME");

            var dayOfWeekSpecs = nameValueCollection.GetValues("DAYOFWEEK");
            var monthSpecs = nameValueCollection.GetValues("MONTH");

            var ordinals = nameValueCollection.GetValues("ORDINAL");

            //init cron values
            List<string> cronExpressions = new List<string>();


            if (timesToFire == null) // if times are not specified assume midnight
                timesToFire = new string[] { "00:00" };

            foreach (var time in timesToFire)
            {
                DateTime date = DateTime.Today; //default date to today

                if (time != null)
                {
                    date = GrammarHelper.GetTimeFromTimeString(time).Value;
                }

                string cron_sec = date.Second.ToString();
                string cron_min = date.Minute.ToString();
                string cron_hour = date.Hour.ToString();
                string cron_day = "?";
                string cron_month = "*";
                string cron_dayofWeek = "*";

                if (monthSpecs != null)
                {
                    var months = GrammarHelper.GetMonthValues(monthSpecs);
                    cron_month = string.Join(",", months.Select(mon => GetMonthCronValue(mon)));
                }

                if (dayOfWeekSpecs != null)
                {
                    var dows = GrammarHelper.GetDayOfWeekValues(dayOfWeekSpecs);
                    cron_dayofWeek = string.Join(",", dows.Select(x => GetDayOfWeekCronValue(x)));
                }

                if (ordinals != null)
                {
                    if (dayOfWeekSpecs != null)
                    {
                        //combine ordinals and dayOfWeeks
                        var combined =
                            from a in GrammarHelper.GetOrdinalValues(ordinals)
                            from b in GrammarHelper.GetDayOfWeekValues(dayOfWeekSpecs)
                            select new { Ordinal = a, DayOfWeek = b };

                        foreach (var item in combined)
                        {
                            cron_dayofWeek = GetDayOfWeekCronValue(item.DayOfWeek);
                            cron_dayofWeek += GetOrdinalCronValue(item.Ordinal);

                            string cronString = string.Format(string.Join(" ", new string[] { cron_sec, cron_min, cron_hour, cron_day, cron_month, cron_dayofWeek }));
                            cronExpressions.Add(cronString);
                        }
                    }

                    if (dayOfWeekSpecs == null) //"day" was specified as DOW, handle special case
                    {
                        //handle special cases
                        cron_dayofWeek = "?";

                        foreach (var o in GrammarHelper.GetOrdinalValues(ordinals))
                        {
                            cron_day = GetOrdinalCronValue(o).Replace("#", "");
                            string cronString = string.Format(string.Join(" ", new string[] { cron_sec, cron_min, cron_hour, cron_day, cron_month, cron_dayofWeek }));
                            cronExpressions.Add(cronString);
                        }
                    }
                }
                else //no ordinal was specified
                {
                    string cronString = string.Format(string.Join(" ", new string[] { cron_sec, cron_min, cron_hour, cron_day, cron_month, cron_dayofWeek }));
                    cronExpressions.Add(cronString);
                }
            }

            foreach (var cron in cronExpressions)
            {
                var triggerBuilder = TriggerBuilder.Create();

                IScheduleBuilder schedule = CreateScheduleWithCron(cron, timeZone);
                triggerBuilder.WithSchedule(schedule);

                results.Add(triggerBuilder);
            }
        }
        /// <summary>
        /// Handles with a given text matches the Expression1 field.
        /// </summary>
        /// <param name="nameValueCollection">A collection of values from the named capture groups.</param>
        /// <param name="results">The results.</param>
        private void Expression1Handler(NameValueCollection nameValueCollection, TimeZoneInfo timeZone, TextToScheduleResults results)
        {
            var amountString = nameValueCollection["AMOUNT"];
            var intervalUnitString = nameValueCollection["INTERVALUNIT"];
            var startDateString = nameValueCollection["DATESPEC"];

            var time = nameValueCollection["TIME"];
            var fromTime = nameValueCollection["FROMTIME"];
            var toTime = nameValueCollection["TOTIME"];

            var dayOfWeekSpecs = nameValueCollection.GetValues("DAYOFWEEK");
            var monthSpecs = nameValueCollection.GetValues("MONTH");

            DateTime? triggerStartTime = null;

            ICalendar calendar = null;

            //DAY OF WEEK SPECS
            if (dayOfWeekSpecs != null)
            {
                calendar = BuildCalendarOnDayOfWeek(calendar, dayOfWeekSpecs, timeZone);
            }

            //MONTH SPECS
            if (monthSpecs != null)
            {
                calendar = BuildCalendarOnMonths(calendar, monthSpecs, timeZone);
            }


            //TIME (single or range)

            //check for ranged time
            if (fromTime != null && toTime != null)
            {
                calendar = BuildCalendarOnTimeRange(calendar, fromTime, toTime, timeZone);

                //set the start date as the from time
                DateTime? fromTimeStartDate = GrammarHelper.GetTimeFromTimeString(fromTime);
                triggerStartTime = fromTimeStartDate;
            }
            //is regular time, process as single time provided
            else if (time != null)
            {
                DateTime? timeStartDate = GrammarHelper.GetTimeFromTimeString(time);
                triggerStartTime = timeStartDate;
            }

            //BUILD TRIGGER
            TriggerBuilder triggerBuilder = TriggerBuilder.Create();

            //set schedule
            triggerBuilder.WithSchedule(CreateScheduleWithAmountAndIntervalUnit(amountString, intervalUnitString, timeZone));


            //start on from time
            if (triggerStartTime != null)
                triggerBuilder.StartAt(new DateTimeOffset(triggerStartTime.Value, timeZone.GetUtcOffset(triggerStartTime.Value)));

            results.Add(triggerBuilder, calendar);
        }
        /// <summary>
        /// Method that matches an expression, and if it does will run the associated method
        /// </summary>
        /// <param name="expression">The expression.</param>
        /// <param name="input">The input.</param>
        /// <param name="results">The results.</param>
        /// <param name="matchFunction">The match function to run if it matches.</param>
        /// <returns></returns>
        private static bool ExecuteMatch(string expression, string input, TimeZoneInfo timeZone, TextToScheduleResults results, Action <NameValueCollection, TimeZoneInfo, TextToScheduleResults> matchFunction)
        {
            expression = "^" + expression + "$";

            var dic = RegexHelper.GetNamedMatches(input, expression);

            if (dic != null)
            {
                matchFunction(dic, timeZone, results);
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Handles with a given text matches the Expression5 field.
        /// </summary>
        /// <param name="nameValueCollection">A collection of values from the named capture groups.</param>
        /// <param name="results">The results.</param>
        private void Expression5Handler(NameValueCollection nameValueCollection, TimeZoneInfo timeZone, TextToScheduleResults results)
        {
            var days        = nameValueCollection.GetValues("DAY");
            var months      = nameValueCollection.GetValues("MONTH");
            var timesToFire = nameValueCollection.GetValues("TIME");

            var dayValues = days.Select(day => GrammarHelper.GetDayValue(day))
                            .Select(day => GetDayCronValue(day).ToList());

            List <string> cronExpressions = new List <string>();

            string cron_day   = "*";
            string cron_month = "*";

            if (days != null)
            {
                var targetDays    = days.Select(x => GrammarHelper.GetDayValue(x));
                var targetDayCron = targetDays.Select(x => GetDayCronValue(x));
                cron_day = string.Join(",", targetDayCron);
            }

            if (months != null)
            {
                var targetMonths     = GrammarHelper.GetMonthValues(months);
                var targetMonthsCron = targetMonths.Select(x => GetMonthCronValue(x));
                cron_month = string.Join(",", targetMonthsCron);
            }

            if (timesToFire == null) // if times are not specified assume midnight
            {
                timesToFire = new string[] { "00:00" }
            }
            ;

            foreach (var item in timesToFire)
            {
                var time = GrammarHelper.GetTimeFromTimeString(item).Value;

                string cron_sec  = time.Second.ToString();
                string cron_min  = time.Minute.ToString();
                string cron_hour = time.Hour.ToString();

                string cronString = string.Format("{0} {1} {2} {3} {4} ?",
                                                  cron_sec, cron_min, cron_hour, cron_day, cron_month);

                cronExpressions.Add(cronString);
            }

            foreach (var cron in cronExpressions)
            {
                var triggerBuilder = TriggerBuilder.Create();

                IScheduleBuilder schedule = CreateScheduleWithCron(cron, timeZone);
                triggerBuilder.WithSchedule(schedule);

                results.Add(triggerBuilder);
            }
        }
        /// <summary>
        /// Handles with a given text matches the Expression4 field.
        /// </summary>
        /// <param name="nameValueCollection">A collection of values from the named capture groups.</param>
        /// <param name="results">The results.</param>
        private void Expression4Handler(NameValueCollection nameValueCollection, TimeZoneInfo timeZone, TextToScheduleResults results)
        {
            // every [n] (days|weeks|months|years) (from [date]) (at [time])

            string amountString   = nameValueCollection["AMOUNT"];
            string intervalString = nameValueCollection["INTERVALUNIT"];

            var dateSpec       = nameValueCollection["DATESPEC"];
            var dayOfWeekSpecs = nameValueCollection.GetValues("DAYOFWEEK");
            var timesToFire    = nameValueCollection.GetValues("TIME");

            DateTime?triggerStartTime = null;

            if (dayOfWeekSpecs != null && GrammarHelper.GetIntervalUnitValueFromString(intervalString) != IntervalUnit.Week)
            {
                throw new Exception("You should only specify a day of the week, when you are using the \"week\" time interval.");
            }

            if (timesToFire == null) // if times are not specified assume midnight
            {
                timesToFire = new string[] { "00:00" }
            }
            ;

            foreach (var timeString in timesToFire)
            {
                if (dateSpec != null || timeString != null)
                {
                    triggerStartTime = GrammarHelper.GetDateTimeFromDateSpecAndTime(dateSpec, timeString);
                }

                if (dayOfWeekSpecs != null)
                {
                    var dayOfWeeks = GrammarHelper.GetDayOfWeekValues(dayOfWeekSpecs);
                    foreach (var dayOfWeek in dayOfWeeks)
                    {
                        if (triggerStartTime == null)
                        {
                            triggerStartTime = SystemTime.Now().DateTime;
                        }

                        DateTime dowTriggerStartTime = triggerStartTime.Value;
                        //seek
                        dowTriggerStartTime = SeekForwardToNextDayOfWeek(dowTriggerStartTime, dayOfWeek);

                        TriggerBuilder triggerBuilder = TriggerBuilder.Create();
                        triggerBuilder.WithSchedule(CreateScheduleWithAmountAndIntervalUnit(amountString, intervalString, timeZone));
                        triggerBuilder.StartAt(new DateTimeOffset(dowTriggerStartTime, timeZone.GetUtcOffset(dowTriggerStartTime)));

                        results.Add(triggerBuilder, null);
                    }
                }
                else
                {
                    TriggerBuilder triggerBuilder = TriggerBuilder.Create();
                    triggerBuilder.WithSchedule(CreateScheduleWithAmountAndIntervalUnit(amountString, intervalString, timeZone));

                    //start on from time
                    if (triggerStartTime != null)
                    {
                        triggerBuilder.StartAt(new DateTimeOffset(triggerStartTime.Value, timeZone.GetUtcOffset(triggerStartTime.Value)));
                    }

                    results.Add(triggerBuilder, null);
                }
            }
        }
        /// <summary>
        /// Handles with a given text matches the Expression3 field.
        /// </summary>
        /// <param name="nameValueCollection">A collection of values from the named capture groups.</param>
        /// <param name="results">The results.</param>
        private void Expression3Handler(NameValueCollection nameValueCollection, TimeZoneInfo timeZone, TextToScheduleResults results)
        {
            var timesToFire = nameValueCollection.GetValues("TIME");

            var dateSpec    = nameValueCollection["DATESPEC"];
            var monthString = nameValueCollection["MONTH"];
            var dayString   = nameValueCollection["DAY"];
            var yearString  = nameValueCollection["YEAR"];

            //init cron values
            List <string> cronExpressions = new List <string>();

            if (timesToFire == null) // if times are not specified assume midnight
            {
                timesToFire = new string[] { "00:00" }
            }
            ;

            foreach (var time in timesToFire)
            {
                DateTime date = DateTime.Today; //default date to today

                if (time != null)
                {
                    date = GrammarHelper.GetTimeFromTimeString(time).Value;
                }

                string cron_sec       = date.Second.ToString();
                string cron_min       = date.Minute.ToString();
                string cron_hour      = date.Hour.ToString();
                string cron_day       = "*";
                string cron_month     = "*";
                string cron_dayofWeek = "?";
                string cron_year      = null;

                cron_month = GetMonthCronValue(GrammarHelper.GetMonthValue(monthString));

                if (dayString != null)
                {
                    cron_day = GetDayCronValue(GrammarHelper.GetDayValue(dayString));
                }
                else
                {
                    cron_day = GetDayCronValue(1);
                }

                if (yearString != null)
                {
                    cron_year = GetYearCronValue(GrammarHelper.GetYearValue(yearString));
                }


                //build cron string
                string cronString = null;

                if (cron_year != null)
                {
                    cronString = string.Format(string.Join(" ", new string[] { cron_sec, cron_min, cron_hour, cron_day, cron_month, cron_dayofWeek, cron_year }));
                }
                else
                {
                    cronString = string.Format(string.Join(" ", new string[] { cron_sec, cron_min, cron_hour, cron_day, cron_month, cron_dayofWeek }));
                }

                //add cron string
                cronExpressions.Add(cronString);
            }

            foreach (var cron in cronExpressions)
            {
                var triggerBuilder = TriggerBuilder.Create();

                IScheduleBuilder schedule = CreateScheduleWithCron(cron, timeZone);
                triggerBuilder.WithSchedule(schedule);

                results.Add(triggerBuilder);
            }
        }
        /// <summary>
        /// Handles with a given text matches the Expression2 field.
        /// </summary>
        /// <param name="nameValueCollection">A collection of values from the named capture groups.</param>
        /// <param name="results">The results.</param>
        private void Expression2Handler(NameValueCollection nameValueCollection, TimeZoneInfo timeZone, TextToScheduleResults results)
        {
            var timesToFire = nameValueCollection.GetValues("TIME");

            var dayOfWeekSpecs = nameValueCollection.GetValues("DAYOFWEEK");
            var monthSpecs     = nameValueCollection.GetValues("MONTH");

            var ordinals = nameValueCollection.GetValues("ORDINAL");

            //init cron values
            List <string> cronExpressions = new List <string>();


            if (timesToFire == null) // if times are not specified assume midnight
            {
                timesToFire = new string[] { "00:00" }
            }
            ;

            foreach (var time in timesToFire)
            {
                DateTime date = DateTime.Today; //default date to today

                if (time != null)
                {
                    date = GrammarHelper.GetTimeFromTimeString(time).Value;
                }

                string cron_sec       = date.Second.ToString();
                string cron_min       = date.Minute.ToString();
                string cron_hour      = date.Hour.ToString();
                string cron_day       = "?";
                string cron_month     = "*";
                string cron_dayofWeek = "*";

                if (monthSpecs != null)
                {
                    var months = GrammarHelper.GetMonthValues(monthSpecs);
                    cron_month = string.Join(",", months.Select(mon => GetMonthCronValue(mon)));
                }

                if (dayOfWeekSpecs != null)
                {
                    var dows = GrammarHelper.GetDayOfWeekValues(dayOfWeekSpecs);
                    cron_dayofWeek = string.Join(",", dows.Select(x => GetDayOfWeekCronValue(x)));
                }

                if (ordinals != null)
                {
                    if (dayOfWeekSpecs != null)
                    {
                        //combine ordinals and dayOfWeeks
                        var combined =
                            from a in GrammarHelper.GetOrdinalValues(ordinals)
                            from b in GrammarHelper.GetDayOfWeekValues(dayOfWeekSpecs)
                            select new { Ordinal = a, DayOfWeek = b };

                        foreach (var item in combined)
                        {
                            cron_dayofWeek  = GetDayOfWeekCronValue(item.DayOfWeek);
                            cron_dayofWeek += GetOrdinalCronValue(item.Ordinal);

                            string cronString = string.Format(string.Join(" ", new string[] { cron_sec, cron_min, cron_hour, cron_day, cron_month, cron_dayofWeek }));
                            cronExpressions.Add(cronString);
                        }
                    }

                    if (dayOfWeekSpecs == null) //"day" was specified as DOW, handle special case
                    {
                        //handle special cases
                        cron_dayofWeek = "?";

                        foreach (var o in GrammarHelper.GetOrdinalValues(ordinals))
                        {
                            cron_day = GetOrdinalCronValue(o).Replace("#", "");
                            string cronString = string.Format(string.Join(" ", new string[] { cron_sec, cron_min, cron_hour, cron_day, cron_month, cron_dayofWeek }));
                            cronExpressions.Add(cronString);
                        }
                    }
                }
                else //no ordinal was specified
                {
                    string cronString = string.Format(string.Join(" ", new string[] { cron_sec, cron_min, cron_hour, cron_day, cron_month, cron_dayofWeek }));
                    cronExpressions.Add(cronString);
                }
            }

            foreach (var cron in cronExpressions)
            {
                var triggerBuilder = TriggerBuilder.Create();

                IScheduleBuilder schedule = CreateScheduleWithCron(cron, timeZone);
                triggerBuilder.WithSchedule(schedule);

                results.Add(triggerBuilder);
            }
        }
        /// <summary>
        /// Handles with a given text matches the Expression1 field.
        /// </summary>
        /// <param name="nameValueCollection">A collection of values from the named capture groups.</param>
        /// <param name="results">The results.</param>
        private void Expression1Handler(NameValueCollection nameValueCollection, TimeZoneInfo timeZone, TextToScheduleResults results)
        {
            var amountString       = nameValueCollection["AMOUNT"];
            var intervalUnitString = nameValueCollection["INTERVALUNIT"];
            var startDateString    = nameValueCollection["DATESPEC"];

            var time     = nameValueCollection["TIME"];
            var fromTime = nameValueCollection["FROMTIME"];
            var toTime   = nameValueCollection["TOTIME"];

            var dayOfWeekSpecs = nameValueCollection.GetValues("DAYOFWEEK");
            var monthSpecs     = nameValueCollection.GetValues("MONTH");

            DateTime?triggerStartTime = null;

            ICalendar calendar = null;

            //DAY OF WEEK SPECS
            if (dayOfWeekSpecs != null)
            {
                calendar = BuildCalendarOnDayOfWeek(calendar, dayOfWeekSpecs, timeZone);
            }

            //MONTH SPECS
            if (monthSpecs != null)
            {
                calendar = BuildCalendarOnMonths(calendar, monthSpecs, timeZone);
            }


            //TIME (single or range)

            //check for ranged time
            if (fromTime != null && toTime != null)
            {
                calendar = BuildCalendarOnTimeRange(calendar, fromTime, toTime, timeZone);

                //set the start date as the from time
                DateTime?fromTimeStartDate = GrammarHelper.GetTimeFromTimeString(fromTime);
                triggerStartTime = fromTimeStartDate;
            }
            //is regular time, process as single time provided
            else if (time != null)
            {
                DateTime?timeStartDate = GrammarHelper.GetTimeFromTimeString(time);
                triggerStartTime = timeStartDate;
            }

            //BUILD TRIGGER
            TriggerBuilder triggerBuilder = TriggerBuilder.Create();

            //set schedule
            triggerBuilder.WithSchedule(CreateScheduleWithAmountAndIntervalUnit(amountString, intervalUnitString, timeZone));


            //start on from time
            if (triggerStartTime != null)
            {
                triggerBuilder.StartAt(new DateTimeOffset(triggerStartTime.Value, timeZone.GetUtcOffset(triggerStartTime.Value)));
            }

            results.Add(triggerBuilder, calendar);
        }