Expose cron expression fields
This commit is contained in:
		
							parent
							
								
									88b0669f7d
								
							
						
					
					
						commit
						02e4e6fd45
					
				
							
								
								
									
										74
									
								
								cronexpr.go
								
								
								
								
							
							
						
						
									
										74
									
								
								cronexpr.go
								
								
								
								
							| 
						 | 
				
			
			@ -26,22 +26,22 @@ import (
 | 
			
		|||
// A Expression represents a specific cron time expression as defined at
 | 
			
		||||
// <https://github.com/gorhill/cronexpr#implementation>
 | 
			
		||||
type Expression struct {
 | 
			
		||||
	expression             string
 | 
			
		||||
	secondList             []int
 | 
			
		||||
	minuteList             []int
 | 
			
		||||
	hourList               []int
 | 
			
		||||
	daysOfMonth            map[int]bool
 | 
			
		||||
	workdaysOfMonth        map[int]bool
 | 
			
		||||
	lastDayOfMonth         bool
 | 
			
		||||
	lastWorkdayOfMonth     bool
 | 
			
		||||
	daysOfMonthRestricted  bool
 | 
			
		||||
	actualDaysOfMonthList  []int
 | 
			
		||||
	monthList              []int
 | 
			
		||||
	daysOfWeek             map[int]bool
 | 
			
		||||
	specificWeekDaysOfWeek map[int]bool
 | 
			
		||||
	lastWeekDaysOfWeek     map[int]bool
 | 
			
		||||
	daysOfWeekRestricted   bool
 | 
			
		||||
	yearList               []int
 | 
			
		||||
	Expression             string
 | 
			
		||||
	SecondList             []int
 | 
			
		||||
	MinuteList             []int
 | 
			
		||||
	HourList               []int
 | 
			
		||||
	DaysOfMonth            map[int]bool
 | 
			
		||||
	WorkdaysOfMonth        map[int]bool
 | 
			
		||||
	LastDayOfMonth         bool
 | 
			
		||||
	LastWorkdayOfMonth     bool
 | 
			
		||||
	DaysOfMonthRestricted  bool
 | 
			
		||||
	ActualDaysOfMonthList  []int
 | 
			
		||||
	MonthList              []int
 | 
			
		||||
	DaysOfWeek             map[int]bool
 | 
			
		||||
	SpecificWeekDaysOfWeek map[int]bool
 | 
			
		||||
	LastWeekDaysOfWeek     map[int]bool
 | 
			
		||||
	DaysOfWeekRestricted   bool
 | 
			
		||||
	YearList               []int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
| 
						 | 
				
			
			@ -93,7 +93,7 @@ func Parse(cronLine string) (*Expression, error) {
 | 
			
		|||
		}
 | 
			
		||||
		field += 1
 | 
			
		||||
	} else {
 | 
			
		||||
		expr.secondList = []int{0}
 | 
			
		||||
		expr.SecondList = []int{0}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// minute field
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +138,7 @@ func Parse(cronLine string) (*Expression, error) {
 | 
			
		|||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		expr.yearList = yearDescriptor.defaultList
 | 
			
		||||
		expr.YearList = yearDescriptor.defaultList
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &expr, nil
 | 
			
		||||
| 
						 | 
				
			
			@ -172,59 +172,59 @@ func (expr *Expression) Next(fromTime time.Time) time.Time {
 | 
			
		|||
 | 
			
		||||
	// year
 | 
			
		||||
	v := fromTime.Year()
 | 
			
		||||
	i := sort.SearchInts(expr.yearList, v)
 | 
			
		||||
	if i == len(expr.yearList) {
 | 
			
		||||
	i := sort.SearchInts(expr.YearList, v)
 | 
			
		||||
	if i == len(expr.YearList) {
 | 
			
		||||
		return time.Time{}
 | 
			
		||||
	}
 | 
			
		||||
	if v != expr.yearList[i] {
 | 
			
		||||
	if v != expr.YearList[i] {
 | 
			
		||||
		return expr.nextYear(fromTime)
 | 
			
		||||
	}
 | 
			
		||||
	// month
 | 
			
		||||
	v = int(fromTime.Month())
 | 
			
		||||
	i = sort.SearchInts(expr.monthList, v)
 | 
			
		||||
	if i == len(expr.monthList) {
 | 
			
		||||
	i = sort.SearchInts(expr.MonthList, v)
 | 
			
		||||
	if i == len(expr.MonthList) {
 | 
			
		||||
		return expr.nextYear(fromTime)
 | 
			
		||||
	}
 | 
			
		||||
	if v != expr.monthList[i] {
 | 
			
		||||
	if v != expr.MonthList[i] {
 | 
			
		||||
		return expr.nextMonth(fromTime)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	expr.actualDaysOfMonthList = expr.calculateActualDaysOfMonth(fromTime.Year(), int(fromTime.Month()))
 | 
			
		||||
	if len(expr.actualDaysOfMonthList) == 0 {
 | 
			
		||||
	expr.ActualDaysOfMonthList = expr.calculateActualDaysOfMonth(fromTime.Year(), int(fromTime.Month()))
 | 
			
		||||
	if len(expr.ActualDaysOfMonthList) == 0 {
 | 
			
		||||
		return expr.nextMonth(fromTime)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// day of month
 | 
			
		||||
	v = fromTime.Day()
 | 
			
		||||
	i = sort.SearchInts(expr.actualDaysOfMonthList, v)
 | 
			
		||||
	if i == len(expr.actualDaysOfMonthList) {
 | 
			
		||||
	i = sort.SearchInts(expr.ActualDaysOfMonthList, v)
 | 
			
		||||
	if i == len(expr.ActualDaysOfMonthList) {
 | 
			
		||||
		return expr.nextMonth(fromTime)
 | 
			
		||||
	}
 | 
			
		||||
	if v != expr.actualDaysOfMonthList[i] {
 | 
			
		||||
	if v != expr.ActualDaysOfMonthList[i] {
 | 
			
		||||
		return expr.nextDayOfMonth(fromTime)
 | 
			
		||||
	}
 | 
			
		||||
	// hour
 | 
			
		||||
	v = fromTime.Hour()
 | 
			
		||||
	i = sort.SearchInts(expr.hourList, v)
 | 
			
		||||
	if i == len(expr.hourList) {
 | 
			
		||||
	i = sort.SearchInts(expr.HourList, v)
 | 
			
		||||
	if i == len(expr.HourList) {
 | 
			
		||||
		return expr.nextDayOfMonth(fromTime)
 | 
			
		||||
	}
 | 
			
		||||
	if v != expr.hourList[i] {
 | 
			
		||||
	if v != expr.HourList[i] {
 | 
			
		||||
		return expr.nextHour(fromTime)
 | 
			
		||||
	}
 | 
			
		||||
	// minute
 | 
			
		||||
	v = fromTime.Minute()
 | 
			
		||||
	i = sort.SearchInts(expr.minuteList, v)
 | 
			
		||||
	if i == len(expr.minuteList) {
 | 
			
		||||
	i = sort.SearchInts(expr.MinuteList, v)
 | 
			
		||||
	if i == len(expr.MinuteList) {
 | 
			
		||||
		return expr.nextHour(fromTime)
 | 
			
		||||
	}
 | 
			
		||||
	if v != expr.minuteList[i] {
 | 
			
		||||
	if v != expr.MinuteList[i] {
 | 
			
		||||
		return expr.nextMinute(fromTime)
 | 
			
		||||
	}
 | 
			
		||||
	// second
 | 
			
		||||
	v = fromTime.Second()
 | 
			
		||||
	i = sort.SearchInts(expr.secondList, v)
 | 
			
		||||
	if i == len(expr.secondList) {
 | 
			
		||||
	i = sort.SearchInts(expr.SecondList, v)
 | 
			
		||||
	if i == len(expr.SecondList) {
 | 
			
		||||
		return expr.nextMinute(fromTime)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										112
									
								
								cronexpr_next.go
								
								
								
								
							
							
						
						
									
										112
									
								
								cronexpr_next.go
								
								
								
								
							| 
						 | 
				
			
			@ -36,30 +36,30 @@ var dowNormalizedOffsets = [][]int{
 | 
			
		|||
func (expr *Expression) nextYear(t time.Time) time.Time {
 | 
			
		||||
	// Find index at which item in list is greater or equal to
 | 
			
		||||
	// candidate year
 | 
			
		||||
	i := sort.SearchInts(expr.yearList, t.Year()+1)
 | 
			
		||||
	if i == len(expr.yearList) {
 | 
			
		||||
	i := sort.SearchInts(expr.YearList, t.Year()+1)
 | 
			
		||||
	if i == len(expr.YearList) {
 | 
			
		||||
		return time.Time{}
 | 
			
		||||
	}
 | 
			
		||||
	// Year changed, need to recalculate actual days of month
 | 
			
		||||
	expr.actualDaysOfMonthList = expr.calculateActualDaysOfMonth(expr.yearList[i], expr.monthList[0])
 | 
			
		||||
	if len(expr.actualDaysOfMonthList) == 0 {
 | 
			
		||||
	expr.ActualDaysOfMonthList = expr.calculateActualDaysOfMonth(expr.YearList[i], expr.MonthList[0])
 | 
			
		||||
	if len(expr.ActualDaysOfMonthList) == 0 {
 | 
			
		||||
		return expr.nextMonth(time.Date(
 | 
			
		||||
			expr.yearList[i],
 | 
			
		||||
			time.Month(expr.monthList[0]),
 | 
			
		||||
			expr.YearList[i],
 | 
			
		||||
			time.Month(expr.MonthList[0]),
 | 
			
		||||
			1,
 | 
			
		||||
			expr.hourList[0],
 | 
			
		||||
			expr.minuteList[0],
 | 
			
		||||
			expr.secondList[0],
 | 
			
		||||
			expr.HourList[0],
 | 
			
		||||
			expr.MinuteList[0],
 | 
			
		||||
			expr.SecondList[0],
 | 
			
		||||
			0,
 | 
			
		||||
			t.Location()))
 | 
			
		||||
	}
 | 
			
		||||
	return time.Date(
 | 
			
		||||
		expr.yearList[i],
 | 
			
		||||
		time.Month(expr.monthList[0]),
 | 
			
		||||
		expr.actualDaysOfMonthList[0],
 | 
			
		||||
		expr.hourList[0],
 | 
			
		||||
		expr.minuteList[0],
 | 
			
		||||
		expr.secondList[0],
 | 
			
		||||
		expr.YearList[i],
 | 
			
		||||
		time.Month(expr.MonthList[0]),
 | 
			
		||||
		expr.ActualDaysOfMonthList[0],
 | 
			
		||||
		expr.HourList[0],
 | 
			
		||||
		expr.MinuteList[0],
 | 
			
		||||
		expr.SecondList[0],
 | 
			
		||||
		0,
 | 
			
		||||
		t.Location())
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -69,31 +69,31 @@ func (expr *Expression) nextYear(t time.Time) time.Time {
 | 
			
		|||
func (expr *Expression) nextMonth(t time.Time) time.Time {
 | 
			
		||||
	// Find index at which item in list is greater or equal to
 | 
			
		||||
	// candidate month
 | 
			
		||||
	i := sort.SearchInts(expr.monthList, int(t.Month())+1)
 | 
			
		||||
	if i == len(expr.monthList) {
 | 
			
		||||
	i := sort.SearchInts(expr.MonthList, int(t.Month())+1)
 | 
			
		||||
	if i == len(expr.MonthList) {
 | 
			
		||||
		return expr.nextYear(t)
 | 
			
		||||
	}
 | 
			
		||||
	// Month changed, need to recalculate actual days of month
 | 
			
		||||
	expr.actualDaysOfMonthList = expr.calculateActualDaysOfMonth(t.Year(), expr.monthList[i])
 | 
			
		||||
	if len(expr.actualDaysOfMonthList) == 0 {
 | 
			
		||||
	expr.ActualDaysOfMonthList = expr.calculateActualDaysOfMonth(t.Year(), expr.MonthList[i])
 | 
			
		||||
	if len(expr.ActualDaysOfMonthList) == 0 {
 | 
			
		||||
		return expr.nextMonth(time.Date(
 | 
			
		||||
			t.Year(),
 | 
			
		||||
			time.Month(expr.monthList[i]),
 | 
			
		||||
			time.Month(expr.MonthList[i]),
 | 
			
		||||
			1,
 | 
			
		||||
			expr.hourList[0],
 | 
			
		||||
			expr.minuteList[0],
 | 
			
		||||
			expr.secondList[0],
 | 
			
		||||
			expr.HourList[0],
 | 
			
		||||
			expr.MinuteList[0],
 | 
			
		||||
			expr.SecondList[0],
 | 
			
		||||
			0,
 | 
			
		||||
			t.Location()))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return time.Date(
 | 
			
		||||
		t.Year(),
 | 
			
		||||
		time.Month(expr.monthList[i]),
 | 
			
		||||
		expr.actualDaysOfMonthList[0],
 | 
			
		||||
		expr.hourList[0],
 | 
			
		||||
		expr.minuteList[0],
 | 
			
		||||
		expr.secondList[0],
 | 
			
		||||
		time.Month(expr.MonthList[i]),
 | 
			
		||||
		expr.ActualDaysOfMonthList[0],
 | 
			
		||||
		expr.HourList[0],
 | 
			
		||||
		expr.MinuteList[0],
 | 
			
		||||
		expr.SecondList[0],
 | 
			
		||||
		0,
 | 
			
		||||
		t.Location())
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -103,18 +103,18 @@ func (expr *Expression) nextMonth(t time.Time) time.Time {
 | 
			
		|||
func (expr *Expression) nextDayOfMonth(t time.Time) time.Time {
 | 
			
		||||
	// Find index at which item in list is greater or equal to
 | 
			
		||||
	// candidate day of month
 | 
			
		||||
	i := sort.SearchInts(expr.actualDaysOfMonthList, t.Day()+1)
 | 
			
		||||
	if i == len(expr.actualDaysOfMonthList) {
 | 
			
		||||
	i := sort.SearchInts(expr.ActualDaysOfMonthList, t.Day()+1)
 | 
			
		||||
	if i == len(expr.ActualDaysOfMonthList) {
 | 
			
		||||
		return expr.nextMonth(t)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return time.Date(
 | 
			
		||||
		t.Year(),
 | 
			
		||||
		t.Month(),
 | 
			
		||||
		expr.actualDaysOfMonthList[i],
 | 
			
		||||
		expr.hourList[0],
 | 
			
		||||
		expr.minuteList[0],
 | 
			
		||||
		expr.secondList[0],
 | 
			
		||||
		expr.ActualDaysOfMonthList[i],
 | 
			
		||||
		expr.HourList[0],
 | 
			
		||||
		expr.MinuteList[0],
 | 
			
		||||
		expr.SecondList[0],
 | 
			
		||||
		0,
 | 
			
		||||
		t.Location())
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -124,8 +124,8 @@ func (expr *Expression) nextDayOfMonth(t time.Time) time.Time {
 | 
			
		|||
func (expr *Expression) nextHour(t time.Time) time.Time {
 | 
			
		||||
	// Find index at which item in list is greater or equal to
 | 
			
		||||
	// candidate hour
 | 
			
		||||
	i := sort.SearchInts(expr.hourList, t.Hour()+1)
 | 
			
		||||
	if i == len(expr.hourList) {
 | 
			
		||||
	i := sort.SearchInts(expr.HourList, t.Hour()+1)
 | 
			
		||||
	if i == len(expr.HourList) {
 | 
			
		||||
		return expr.nextDayOfMonth(t)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -133,9 +133,9 @@ func (expr *Expression) nextHour(t time.Time) time.Time {
 | 
			
		|||
		t.Year(),
 | 
			
		||||
		t.Month(),
 | 
			
		||||
		t.Day(),
 | 
			
		||||
		expr.hourList[i],
 | 
			
		||||
		expr.minuteList[0],
 | 
			
		||||
		expr.secondList[0],
 | 
			
		||||
		expr.HourList[i],
 | 
			
		||||
		expr.MinuteList[0],
 | 
			
		||||
		expr.SecondList[0],
 | 
			
		||||
		0,
 | 
			
		||||
		t.Location())
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -145,8 +145,8 @@ func (expr *Expression) nextHour(t time.Time) time.Time {
 | 
			
		|||
func (expr *Expression) nextMinute(t time.Time) time.Time {
 | 
			
		||||
	// Find index at which item in list is greater or equal to
 | 
			
		||||
	// candidate minute
 | 
			
		||||
	i := sort.SearchInts(expr.minuteList, t.Minute()+1)
 | 
			
		||||
	if i == len(expr.minuteList) {
 | 
			
		||||
	i := sort.SearchInts(expr.MinuteList, t.Minute()+1)
 | 
			
		||||
	if i == len(expr.MinuteList) {
 | 
			
		||||
		return expr.nextHour(t)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -155,8 +155,8 @@ func (expr *Expression) nextMinute(t time.Time) time.Time {
 | 
			
		|||
		t.Month(),
 | 
			
		||||
		t.Day(),
 | 
			
		||||
		t.Hour(),
 | 
			
		||||
		expr.minuteList[i],
 | 
			
		||||
		expr.secondList[0],
 | 
			
		||||
		expr.MinuteList[i],
 | 
			
		||||
		expr.SecondList[0],
 | 
			
		||||
		0,
 | 
			
		||||
		t.Location())
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -169,8 +169,8 @@ func (expr *Expression) nextSecond(t time.Time) time.Time {
 | 
			
		|||
 | 
			
		||||
	// Find index at which item in list is greater or equal to
 | 
			
		||||
	// candidate second
 | 
			
		||||
	i := sort.SearchInts(expr.secondList, t.Second()+1)
 | 
			
		||||
	if i == len(expr.secondList) {
 | 
			
		||||
	i := sort.SearchInts(expr.SecondList, t.Second()+1)
 | 
			
		||||
	if i == len(expr.SecondList) {
 | 
			
		||||
		return expr.nextMinute(t)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -180,7 +180,7 @@ func (expr *Expression) nextSecond(t time.Time) time.Time {
 | 
			
		|||
		t.Day(),
 | 
			
		||||
		t.Hour(),
 | 
			
		||||
		t.Minute(),
 | 
			
		||||
		expr.secondList[i],
 | 
			
		||||
		expr.SecondList[i],
 | 
			
		||||
		0,
 | 
			
		||||
		t.Location())
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -199,22 +199,22 @@ func (expr *Expression) calculateActualDaysOfMonth(year, month int) []int {
 | 
			
		|||
	//  "either field matches the current time"
 | 
			
		||||
 | 
			
		||||
	// If both fields are not restricted, all days of the month are a hit
 | 
			
		||||
	if expr.daysOfMonthRestricted == false && expr.daysOfWeekRestricted == false {
 | 
			
		||||
	if expr.DaysOfMonthRestricted == false && expr.DaysOfWeekRestricted == false {
 | 
			
		||||
		return genericDefaultList[1 : lastDayOfMonth.Day()+1]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// day-of-month != `*`
 | 
			
		||||
	if expr.daysOfMonthRestricted {
 | 
			
		||||
	if expr.DaysOfMonthRestricted {
 | 
			
		||||
		// Last day of month
 | 
			
		||||
		if expr.lastDayOfMonth {
 | 
			
		||||
		if expr.LastDayOfMonth {
 | 
			
		||||
			actualDaysOfMonthMap[lastDayOfMonth.Day()] = true
 | 
			
		||||
		}
 | 
			
		||||
		// Last work day of month
 | 
			
		||||
		if expr.lastWorkdayOfMonth {
 | 
			
		||||
		if expr.LastWorkdayOfMonth {
 | 
			
		||||
			actualDaysOfMonthMap[workdayOfMonth(lastDayOfMonth, lastDayOfMonth)] = true
 | 
			
		||||
		}
 | 
			
		||||
		// Days of month
 | 
			
		||||
		for v := range expr.daysOfMonth {
 | 
			
		||||
		for v := range expr.DaysOfMonth {
 | 
			
		||||
			// Ignore days beyond end of month
 | 
			
		||||
			if v <= lastDayOfMonth.Day() {
 | 
			
		||||
				actualDaysOfMonthMap[v] = true
 | 
			
		||||
| 
						 | 
				
			
			@ -222,7 +222,7 @@ func (expr *Expression) calculateActualDaysOfMonth(year, month int) []int {
 | 
			
		|||
		}
 | 
			
		||||
		// Work days of month
 | 
			
		||||
		// As per Wikipedia: month boundaries are not crossed.
 | 
			
		||||
		for v := range expr.workdaysOfMonth {
 | 
			
		||||
		for v := range expr.WorkdaysOfMonth {
 | 
			
		||||
			// Ignore days beyond end of month
 | 
			
		||||
			if v <= lastDayOfMonth.Day() {
 | 
			
		||||
				actualDaysOfMonthMap[workdayOfMonth(firstDayOfMonth.AddDate(0, 0, v-1), lastDayOfMonth)] = true
 | 
			
		||||
| 
						 | 
				
			
			@ -231,13 +231,13 @@ func (expr *Expression) calculateActualDaysOfMonth(year, month int) []int {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// day-of-week != `*`
 | 
			
		||||
	if expr.daysOfWeekRestricted {
 | 
			
		||||
	if expr.DaysOfWeekRestricted {
 | 
			
		||||
		// How far first sunday is from first day of month
 | 
			
		||||
		offset := 7 - int(firstDayOfMonth.Weekday())
 | 
			
		||||
		// days of week
 | 
			
		||||
		//  offset : (7 - day_of_week_of_1st_day_of_month)
 | 
			
		||||
		//  target : 1 + (7 * week_of_month) + (offset + day_of_week) % 7
 | 
			
		||||
		for v := range expr.daysOfWeek {
 | 
			
		||||
		for v := range expr.DaysOfWeek {
 | 
			
		||||
			w := dowNormalizedOffsets[(offset+v)%7]
 | 
			
		||||
			actualDaysOfMonthMap[w[0]] = true
 | 
			
		||||
			actualDaysOfMonthMap[w[1]] = true
 | 
			
		||||
| 
						 | 
				
			
			@ -250,7 +250,7 @@ func (expr *Expression) calculateActualDaysOfMonth(year, month int) []int {
 | 
			
		|||
		// days of week of specific week in the month
 | 
			
		||||
		//  offset : (7 - day_of_week_of_1st_day_of_month)
 | 
			
		||||
		//  target : 1 + (7 * week_of_month) + (offset + day_of_week) % 7
 | 
			
		||||
		for v := range expr.specificWeekDaysOfWeek {
 | 
			
		||||
		for v := range expr.SpecificWeekDaysOfWeek {
 | 
			
		||||
			v = 1 + 7*(v/7) + (offset+v)%7
 | 
			
		||||
			if v <= lastDayOfMonth.Day() {
 | 
			
		||||
				actualDaysOfMonthMap[v] = true
 | 
			
		||||
| 
						 | 
				
			
			@ -259,7 +259,7 @@ func (expr *Expression) calculateActualDaysOfMonth(year, month int) []int {
 | 
			
		|||
		// Last days of week of the month
 | 
			
		||||
		lastWeekOrigin := firstDayOfMonth.AddDate(0, 1, -7)
 | 
			
		||||
		offset = 7 - int(lastWeekOrigin.Weekday())
 | 
			
		||||
		for v := range expr.lastWeekDaysOfWeek {
 | 
			
		||||
		for v := range expr.LastWeekDaysOfWeek {
 | 
			
		||||
			v = lastWeekOrigin.Day() + (offset+v)%7
 | 
			
		||||
			if v <= lastDayOfMonth.Day() {
 | 
			
		||||
				actualDaysOfMonthMap[v] = true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -212,7 +212,7 @@ var cronNormalizer = strings.NewReplacer(
 | 
			
		|||
 | 
			
		||||
func (expr *Expression) secondFieldHandler(s string) error {
 | 
			
		||||
	var err error
 | 
			
		||||
	expr.secondList, err = genericFieldHandler(s, secondDescriptor)
 | 
			
		||||
	expr.SecondList, err = genericFieldHandler(s, secondDescriptor)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -220,7 +220,7 @@ func (expr *Expression) secondFieldHandler(s string) error {
 | 
			
		|||
 | 
			
		||||
func (expr *Expression) minuteFieldHandler(s string) error {
 | 
			
		||||
	var err error
 | 
			
		||||
	expr.minuteList, err = genericFieldHandler(s, minuteDescriptor)
 | 
			
		||||
	expr.MinuteList, err = genericFieldHandler(s, minuteDescriptor)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -228,7 +228,7 @@ func (expr *Expression) minuteFieldHandler(s string) error {
 | 
			
		|||
 | 
			
		||||
func (expr *Expression) hourFieldHandler(s string) error {
 | 
			
		||||
	var err error
 | 
			
		||||
	expr.hourList, err = genericFieldHandler(s, hourDescriptor)
 | 
			
		||||
	expr.HourList, err = genericFieldHandler(s, hourDescriptor)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -236,7 +236,7 @@ func (expr *Expression) hourFieldHandler(s string) error {
 | 
			
		|||
 | 
			
		||||
func (expr *Expression) monthFieldHandler(s string) error {
 | 
			
		||||
	var err error
 | 
			
		||||
	expr.monthList, err = genericFieldHandler(s, monthDescriptor)
 | 
			
		||||
	expr.MonthList, err = genericFieldHandler(s, monthDescriptor)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -244,7 +244,7 @@ func (expr *Expression) monthFieldHandler(s string) error {
 | 
			
		|||
 | 
			
		||||
func (expr *Expression) yearFieldHandler(s string) error {
 | 
			
		||||
	var err error
 | 
			
		||||
	expr.yearList, err = genericFieldHandler(s, yearDescriptor)
 | 
			
		||||
	expr.YearList, err = genericFieldHandler(s, yearDescriptor)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -288,10 +288,10 @@ func genericFieldHandler(s string, desc fieldDescriptor) ([]int, error) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (expr *Expression) dowFieldHandler(s string) error {
 | 
			
		||||
	expr.daysOfWeekRestricted = true
 | 
			
		||||
	expr.daysOfWeek = make(map[int]bool)
 | 
			
		||||
	expr.lastWeekDaysOfWeek = make(map[int]bool)
 | 
			
		||||
	expr.specificWeekDaysOfWeek = make(map[int]bool)
 | 
			
		||||
	expr.DaysOfWeekRestricted = true
 | 
			
		||||
	expr.DaysOfWeek = make(map[int]bool)
 | 
			
		||||
	expr.LastWeekDaysOfWeek = make(map[int]bool)
 | 
			
		||||
	expr.SpecificWeekDaysOfWeek = make(map[int]bool)
 | 
			
		||||
 | 
			
		||||
	directives, err := genericFieldParse(s, dowDescriptor)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -306,34 +306,34 @@ func (expr *Expression) dowFieldHandler(s string) error {
 | 
			
		|||
			// `5L`
 | 
			
		||||
			pairs := makeLayoutRegexp(layoutDowOfLastWeek, dowDescriptor.valuePattern).FindStringSubmatchIndex(snormal)
 | 
			
		||||
			if len(pairs) > 0 {
 | 
			
		||||
				populateOne(expr.lastWeekDaysOfWeek, dowDescriptor.atoi(snormal[pairs[2]:pairs[3]]))
 | 
			
		||||
				populateOne(expr.LastWeekDaysOfWeek, dowDescriptor.atoi(snormal[pairs[2]:pairs[3]]))
 | 
			
		||||
			} else {
 | 
			
		||||
				// `5#3`
 | 
			
		||||
				pairs := makeLayoutRegexp(layoutDowOfSpecificWeek, dowDescriptor.valuePattern).FindStringSubmatchIndex(snormal)
 | 
			
		||||
				if len(pairs) > 0 {
 | 
			
		||||
					populateOne(expr.specificWeekDaysOfWeek, (dowDescriptor.atoi(snormal[pairs[4]:pairs[5]])-1)*7+(dowDescriptor.atoi(snormal[pairs[2]:pairs[3]])%7))
 | 
			
		||||
					populateOne(expr.SpecificWeekDaysOfWeek, (dowDescriptor.atoi(snormal[pairs[4]:pairs[5]])-1)*7+(dowDescriptor.atoi(snormal[pairs[2]:pairs[3]])%7))
 | 
			
		||||
				} else {
 | 
			
		||||
					return fmt.Errorf("syntax error in day-of-week field: '%s'", sdirective)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		case one:
 | 
			
		||||
			populateOne(expr.daysOfWeek, directive.first)
 | 
			
		||||
			populateOne(expr.DaysOfWeek, directive.first)
 | 
			
		||||
		case span:
 | 
			
		||||
			populateMany(expr.daysOfWeek, directive.first, directive.last, directive.step)
 | 
			
		||||
			populateMany(expr.DaysOfWeek, directive.first, directive.last, directive.step)
 | 
			
		||||
		case all:
 | 
			
		||||
			populateMany(expr.daysOfWeek, directive.first, directive.last, directive.step)
 | 
			
		||||
			expr.daysOfWeekRestricted = false
 | 
			
		||||
			populateMany(expr.DaysOfWeek, directive.first, directive.last, directive.step)
 | 
			
		||||
			expr.DaysOfWeekRestricted = false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (expr *Expression) domFieldHandler(s string) error {
 | 
			
		||||
	expr.daysOfMonthRestricted = true
 | 
			
		||||
	expr.lastDayOfMonth = false
 | 
			
		||||
	expr.lastWorkdayOfMonth = false
 | 
			
		||||
	expr.daysOfMonth = make(map[int]bool)     // days of month map
 | 
			
		||||
	expr.workdaysOfMonth = make(map[int]bool) // work days of month map
 | 
			
		||||
	expr.DaysOfMonthRestricted = true
 | 
			
		||||
	expr.LastDayOfMonth = false
 | 
			
		||||
	expr.LastWorkdayOfMonth = false
 | 
			
		||||
	expr.DaysOfMonth = make(map[int]bool)     // days of month map
 | 
			
		||||
	expr.WorkdaysOfMonth = make(map[int]bool) // work days of month map
 | 
			
		||||
 | 
			
		||||
	directives, err := genericFieldParse(s, domDescriptor)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -347,28 +347,28 @@ func (expr *Expression) domFieldHandler(s string) error {
 | 
			
		|||
			snormal := strings.ToLower(sdirective)
 | 
			
		||||
			// `L`
 | 
			
		||||
			if makeLayoutRegexp(layoutLastDom, domDescriptor.valuePattern).MatchString(snormal) {
 | 
			
		||||
				expr.lastDayOfMonth = true
 | 
			
		||||
				expr.LastDayOfMonth = true
 | 
			
		||||
			} else {
 | 
			
		||||
				// `LW`
 | 
			
		||||
				if makeLayoutRegexp(layoutLastWorkdom, domDescriptor.valuePattern).MatchString(snormal) {
 | 
			
		||||
					expr.lastWorkdayOfMonth = true
 | 
			
		||||
					expr.LastWorkdayOfMonth = true
 | 
			
		||||
				} else {
 | 
			
		||||
					// `15W`
 | 
			
		||||
					pairs := makeLayoutRegexp(layoutWorkdom, domDescriptor.valuePattern).FindStringSubmatchIndex(snormal)
 | 
			
		||||
					if len(pairs) > 0 {
 | 
			
		||||
						populateOne(expr.workdaysOfMonth, domDescriptor.atoi(snormal[pairs[2]:pairs[3]]))
 | 
			
		||||
						populateOne(expr.WorkdaysOfMonth, domDescriptor.atoi(snormal[pairs[2]:pairs[3]]))
 | 
			
		||||
					} else {
 | 
			
		||||
						return fmt.Errorf("syntax error in day-of-month field: '%s'", sdirective)
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		case one:
 | 
			
		||||
			populateOne(expr.daysOfMonth, directive.first)
 | 
			
		||||
			populateOne(expr.DaysOfMonth, directive.first)
 | 
			
		||||
		case span:
 | 
			
		||||
			populateMany(expr.daysOfMonth, directive.first, directive.last, directive.step)
 | 
			
		||||
			populateMany(expr.DaysOfMonth, directive.first, directive.last, directive.step)
 | 
			
		||||
		case all:
 | 
			
		||||
			populateMany(expr.daysOfMonth, directive.first, directive.last, directive.step)
 | 
			
		||||
			expr.daysOfMonthRestricted = false
 | 
			
		||||
			populateMany(expr.DaysOfMonth, directive.first, directive.last, directive.step)
 | 
			
		||||
			expr.DaysOfMonthRestricted = false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue