curl2info/trie_year.go
2018-12-05 14:51:36 +08:00

274 lines
4.4 KiB
Go

package curl2info
import (
"time"
)
var defaultTime = time.Now()
type SecondNode int
type MinuteNode struct {
}
func NewMinuteNode() *MinuteNode {
return &MinuteNode{}
}
type HourNode struct {
Minute [60]*MinuteNode
}
func (hour *HourNode) CreateMinute(nminute int) {
min := &MinuteNode{}
hour.Minute[nminute] = min
}
func newHourNode() *HourNode {
return &HourNode{}
}
type DayNode struct {
IsClear bool
Week time.Weekday
Hour [24]*HourNode
}
func (day *DayNode) CreateHour(nhour int) {
hour := &HourNode{}
day.Hour[nhour] = hour
}
func newDayNode(curday *time.Time) *DayNode {
day := &DayNode{}
week := curday.Weekday()
day.Week = week
day.IsClear = true
return day
}
type MonthNode struct {
MaxDay int
First *time.Time
Day [32]*DayNode
}
func (month *MonthNode) CreateDay(nday int) {
day := month.First.AddDate(0, 0, nday-1)
month.Day[nday] = newDayNode(&day)
}
func newMonthNode(year, month int) *MonthNode {
Month := &MonthNode{}
First := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.Local)
Month.First = &First
Month.MaxDay = Month.First.AddDate(0, 1, -1).Day()
return Month
}
type TrieYear struct {
Year int
Month [13]*MonthNode
}
// CheckYear 跨年判断
func (ty *TrieYear) CheckYear() bool {
year := time.Now().Year()
return ty.Year == year
}
func (ty *TrieYear) clearHour() {
for _, month := range ty.Month {
if month != nil {
for _, day := range month.Day {
if day != nil {
for i := 0; i <= 23; i++ {
day.Hour[i] = nil
day.IsClear = true
}
}
}
}
}
}
func newTrieYear() *TrieYear {
ty := TrieYear{}
ty.Year = time.Now().Year()
return &ty
}
// GetPlanTime 获取计划表
func (ty *TrieYear) GetPlanTime(cron *Crontab, aftertime time.Time, count uint) []time.Time {
now := aftertime
nmonth := int(now.Month())
nday := now.Day()
nhour := now.Hour()
nminute := now.Minute()
var result []time.Time
for i := 1; i <= 12; i++ {
if i < nmonth {
continue
}
month := ty.Month[i]
if month != nil {
for j := 1; j <= 31; j++ {
if nmonth == i {
if j < nday {
continue
}
}
day := month.Day[j]
if day != nil {
if day.IsClear {
insertHour(cron, day)
}
for k := 0; k <= 23; k++ {
if nmonth == i && nday == j {
if k < nhour {
continue
}
}
hour := day.Hour[k]
if hour != nil {
for n := 0; n <= 59; n++ {
if nmonth == i && nday == j && nhour == k {
if n < nminute {
continue
}
}
min := hour.Minute[n]
if min != nil {
curTime := time.Date(ty.Year, time.Month(i), j, k, n, 0, 0, time.Local)
result = append(result, curTime)
count--
if count <= 0 {
ty.clearHour()
return result
}
}
}
}
}
}
}
}
}
ty.clearHour()
return result
}
// FromCrontab 从Crontab生成树
func (ty *TrieYear) FromCrontab(cron *Crontab) {
// 月的填充
for _, month := range cron.Month {
left := month.left
right := month.right
for i := left; i <= right; i += month.per {
curMonth := newMonthNode(ty.Year, i)
ty.Month[i] = curMonth
// 天的填充
insertDay(cron, curMonth)
}
}
}
func filterDay(cron *Crontab, curday *DayNode) bool {
for _, w := range cron.Week {
if w.isAll {
return false
}
for n := w.left; n <= w.right; n += w.per {
if n == int(curday.Week) {
return false
}
}
}
return true
}
func insertDay(cron *Crontab, curMonth *MonthNode) {
for _, day := range cron.Day {
left := day.left
if left < 0 {
left += curMonth.MaxDay + 1
}
right := day.right
if right < 0 {
right += curMonth.MaxDay + 1
}
for j := left; j <= right; j += day.per {
curMonth.CreateDay(j)
curDay := curMonth.Day[j]
if filterDay(cron, curDay) {
curMonth.Day[j] = nil
} else {
// insertHour(cron, curDay)
}
}
}
}
func insertHour(cron *Crontab, curDay *DayNode) {
curDay.IsClear = false
// 时的填充
for _, hour := range cron.Hour {
left := hour.left
right := hour.right
for k := left; k <= right; k += hour.per {
curDay.CreateHour(k)
curHour := curDay.Hour[k]
insertMinute(cron, curHour)
}
}
}
func insertMinute(cron *Crontab, curHour *HourNode) {
for _, min := range cron.Min {
left := min.left
right := min.right
for l := left; l <= right; l += min.per {
curHour.CreateMinute(l)
}
}
}