周期时间计算方法

package main

import (
	"fmt"
	"sort"
	"strconv"
	"strings"
	"time"
)

const (
	FORMAT_DATETIME = "2006-01-02 15:04:05"
	FORMAT_DURATION = "15h04m05s"
)

// the frequency an event recurs
type RecurrenceWeekday string

// the frequency an event recurs
type RecurrenceFrequency string

const (
	SecondRecurrenceFrequency RecurrenceFrequency = "SECONDLY"
	MinuteRecurrenceFrequency                     = "MINUTELY"
	HourRecurrenceFrequency                       = "HOURLY"
	DayRecurrenceFrequency                        = "DAILY"
	WeekRecurrenceFrequency                       = "WEEKLY"
	MonthRecurrenceFrequency                      = "MONTHLY"
	YearRecurrenceFrequency                       = "YEARLY"
)

const (
	MondayRecurrenceWeekday    RecurrenceWeekday = "MO"
	TuesdayRecurrenceWeekday                     = "TU"
	WednesdayRecurrenceWeekday                   = "WE"
	ThursdayRecurrenceWeekday                    = "TH"
	FridayRecurrenceWeekday                      = "FR"
	SaturdayRecurrenceWeekday                    = "SA"
	SundayRecurrenceWeekday                      = "SU"
)

func Date(year int, month time.Month, monthWeek int, weekDay time.Weekday, hour, minute, sec int, loc *time.Location) time.Time {
	monthFstDayTime := time.Date(year, month, 1, hour, minute, sec, 0, loc) //一号
	week := monthFstDayTime.Weekday()
	var monthDay int = 1
	if week != time.Sunday { // 算出第一个星期天到底是几号
		monthDay = 1 + int(time.Sunday) - int(week)
		//monthDay = int(week) - 7
	}
	if week == time.Sunday {
		monthDay = -6
	}
	monthDay = monthDay + (monthWeek * 7) + int(weekDay)
	return time.Date(year, month, monthDay, hour, minute, sec, 0, loc)
}

func WeekdayInt(s string) time.Weekday {
	var r time.Weekday
	switch RecurrenceWeekday(s) {
	case SundayRecurrenceWeekday:
		r = time.Sunday
	case MondayRecurrenceWeekday:
		r = time.Monday
	case TuesdayRecurrenceWeekday:
		r = time.Tuesday
	case WednesdayRecurrenceWeekday:
		r = time.Wednesday
	case ThursdayRecurrenceWeekday:
		r = time.Thursday
	case FridayRecurrenceWeekday:
		r = time.Friday
	case SaturdayRecurrenceWeekday:
		r = time.Saturday
	}
	return r
}
func WeekdayString(weekday time.Weekday) RecurrenceWeekday {
	var r RecurrenceWeekday
	switch weekday {
	case time.Sunday:
		r = SundayRecurrenceWeekday
	case time.Monday:
		r = MondayRecurrenceWeekday
	case time.Tuesday:
		r = TuesdayRecurrenceWeekday
	case time.Wednesday:
		r = WednesdayRecurrenceWeekday
	case time.Thursday:
		r = ThursdayRecurrenceWeekday
	case time.Friday:
		r = FridayRecurrenceWeekday
	case time.Saturday:
		return SaturdayRecurrenceWeekday
	}
	return r
}

type TRecurrenceInfo struct {
	EventId           uint64 `json:"-"`
	Frequency         string `json:"frequency,omitempty"`     // daily, weekly, monthly, yearly
	Interval          int64  `json:"interval,omitempty"`      // 每几天(1-365)/周(1-52)/月(1-12)/年(1-10)
	ByDay             string `json:"byday,omitempty"`         // 星期几(SU,MO,TU,WE,TH,FR,SA), CSV格式字符串, 所以存在可能为多个
	ByMonth           string `json:"bymonth,omitempty"`       // 几月(1-12)
	ByMonthDay        string `json:"bymonthday,omitempty"`    // 几号(1-31)
	BySetPos          string `json:"bysetpos,omitempty"`      // 第几周(1-5)
	RecurrenceCount   int64  `json:"repeatcount,omitempty"`   // 循环次数(2-100)
	RecurrenceEndDate int64  `json:"repeatenddate,omitempty"` // 时间戳(秒)
}

const (
	DayDuration   = int64(time.Hour) * 24
	WeekDuration  = int64(time.Hour) * 24 * 7
	MonthDuration = int64(time.Hour) * 24 * 30
	YearDuration  = int64(time.Hour) * 24 * 365
)

//周期会议的第一场时间
func (rule *TRecurrenceInfo) GetFstTime(start, end, length int64, loc *time.Location) (fstStart, fstEnd time.Time) {
	startTime := time.Unix(start, 0).In(loc)
	eneTime := time.Unix(end, 0).In(loc)
	switch strings.ToUpper(rule.Frequency) {
	case DayRecurrenceFrequency:
		fstStart = startTime
		fstEnd = eneTime
	case WeekRecurrenceFrequency:
		if len(rule.ByDay) > 0 {
			dayWeekInts := rule.convertDayList()
			fstWeekDay := time.Weekday(dayWeekInts[0])
			startWeekDay := startTime.Weekday()
			if startWeekDay == fstWeekDay {
				fstStart = startTime
				fstEnd = fstStart.Add(time.Duration(int64(time.Hour) * length))
			} else {
				deleduration := int64(7-startWeekDay+fstWeekDay) * DayDuration
				fstStart = startTime.Add(time.Duration(deleduration))
				fstEnd = fstStart.Add(time.Duration(int64(time.Hour) * length))
			}

		}
	case MonthRecurrenceFrequency:
		year, month, _ := startTime.Date()
		hour, minute, sec := startTime.Clock()
		if len(rule.ByMonthDay) > 0 {
			monthDayList := strings.Split(rule.ByMonthDay, ",")
			fstMonthDay := 1
			if len(monthDayList) > 0 {
				fstMonthDay = int(ToInt64(monthDayList[0], 1))
			}
			fstStart = time.Date(year, month, fstMonthDay, hour, minute, sec, 0, loc)
			if fstStart.Unix() < start {
				fstStart = time.Date(year, month+1, fstMonthDay, hour, minute, sec, 0, loc)
			}
			fstEnd = fstStart.Add(time.Duration(int64(time.Hour) * length))
		}
		if len(rule.BySetPos) > 0 && len(rule.ByDay) > 0 {
			fstWeekDay := WeekdayInt(rule.ByDay)
			fstStart = Date(year, month, int(ToInt64(rule.BySetPos, 0)),
				fstWeekDay, hour, minute, sec, loc)
			if fstStart.Unix() < start {
				fstStart = Date(year, month+1, int(ToInt64(rule.BySetPos, 0)),
					fstWeekDay, hour, minute, sec, loc)
			}
			fstEnd = fstStart.Add(time.Duration(int64(time.Hour) * length))
		}
	case YearRecurrenceFrequency:
		year, month, _ := startTime.Date()
		hour, minute, sec := startTime.Clock()
		month = time.Month(ToInt64(rule.ByMonth, 1))
		if len(rule.ByMonthDay) > 0 {
			fstStart = time.Date(year, month, int(ToInt64(rule.ByMonthDay, 1)), hour, minute, sec, 0, loc)
			if fstStart.Unix() < start {
				fstStart = time.Date(year+1, month, int(ToInt64(rule.ByMonthDay, 1)), hour, minute, sec, 0, loc)
			}
			fstEnd = fstStart.Add(time.Duration(int64(time.Hour) * length))
		}
		if len(rule.BySetPos) > 0 && len(rule.ByDay) > 0 {
			fstWeekDay := WeekdayInt(rule.ByDay)
			fstStart = Date(year, month, int(ToInt64(rule.BySetPos, 0)),
				fstWeekDay, hour, minute, sec, loc)
			if fstStart.Unix() < start {
				fstStart = Date(year+1, month, int(ToInt64(rule.BySetPos, 0)),
					fstWeekDay, hour, minute, sec, loc)
			}
			fstEnd = fstStart.Add(time.Duration(int64(time.Hour) * length))
		}
	}
	return
}

//利用迭代的方式做
//@index 表示第几个周期
//@fstStartTime 周期第一场的时间
//@fstEndTime 周期第一场的结束时间
func (rule *TRecurrenceInfo) GetRecurrenceSingleTime2(index, fstStartTime, fstEndTime, now int64, loc *time.Location) (start, end time.Time) {
	if index < 0 {
		return
	}

	// 处理周期会议
	var deltaDuration int64 = 0
	if rule.RecurrenceCount > 0 {
		if index >= rule.RecurrenceCount {
			return
		}
	}

	if now <= fstStartTime {
		return
	}

	start = time.Unix(fstStartTime, 0).In(loc)
	end = time.Unix(fstEndTime, 0).In(loc)

	interval := rule.Interval
	switch strings.ToUpper(rule.Frequency) {
	case DayRecurrenceFrequency:
		deltaDuration = index * interval * DayDuration
		start = start.Add(time.Duration(deltaDuration))
		end = end.Add(time.Duration(deltaDuration))
		if now > end.Unix() {
			index++
			return rule.GetRecurrenceSingleTime2(index, fstStartTime, fstEndTime, now, loc)
		}
	case WeekRecurrenceFrequency:
		dayList := strings.Split(rule.ByDay, ",")
		dayLen := int64(len(dayList))
		if dayLen > 1 {
			dayWeekInts := rule.convertDayList()
			offset := dayWeekInts[len(dayWeekInts)-1] - dayWeekInts[0]
			//计算这个周期里的第一天的开始与最后一天时间结束时间
			fstDayStartTime, _, _, lastDayEndTime := rule.singleCycleWeekTime(index, interval, offset, start, end)
			fmt.Println("recurrenceSingleStartTime:", fstDayStartTime, "recurrenceSingleEndTime:", lastDayEndTime, "offset:", offset, "now:", time.Unix(now, 0).In(loc))
			//如果当前时间大于某个周期的最后一天的时间,则递归,继续计算下个周期的时间
			if now > lastDayEndTime.Unix() {
				index++
				return rule.GetRecurrenceSingleTime2(index, fstStartTime, fstEndTime, now, loc)
			}
			//否则,在这个周期里查找最近的一天的时间
			if now < lastDayEndTime.Unix() {
				nowTime := time.Unix(now, 0).In(loc)
				nowWeekDay := nowTime.Weekday()
				if nowWeekDay == 0 {
					nowWeekDay = 7
				}
                //否则的话,就取下个周期中,比当前时间所在天最近的一天
				for _, dayWeekInt := range dayWeekInts {
					if nowWeekDay <= time.Weekday(dayWeekInt) {
						offset = dayWeekInt - dayWeekInts[0]
						break
					}
				}
				if now < fstDayStartTime.Unix() {
					offset = 0
				}
				_, _, start, end = rule.singleCycleWeekTime(index, interval, offset, start, end)
				fmt.Println("************************")
				fmt.Println("start:", start, "end:", end)
				return
			}
			break
		}

		_, _, start, end = rule.singleCycleWeekTime(index, interval, 0, start, end)
		if now > end.Unix() {
			index++
			return rule.GetRecurrenceSingleTime2(index, fstStartTime, fstEndTime, now, loc)
		}

	case MonthRecurrenceFrequency:
		if rule.BySetPos == "" {
			dayList := strings.Split(rule.ByMonthDay, ",")
			dayLen := int64(len(dayList))
			var offset int64
			if dayLen > 0 {
				offset = ToInt64(dayList[dayLen-1], 0) - ToInt64(dayList[0], 0)
			}
			fstDayStartTime, _, _, lastDayEndTime := rule.singleCycleMonthTime(index, interval, offset, rule.BySetPos, start, end)
			fmt.Println("recurrenceSingleStartTime:", fstDayStartTime, "recurrenceSingleEndTime:", lastDayEndTime, "offset:", offset)
			if now > lastDayEndTime.Unix() {
				index++
				return rule.GetRecurrenceSingleTime2(index, fstStartTime, fstEndTime, now, loc)
			}
			//查找大于当前时间且在周期规则内的时间
			if now < lastDayEndTime.Unix() {
				nowTime := time.Unix(now, 0).In(loc)
				_, _, nowDayInt := nowTime.Date()
				//当前时间比下一个周期的开始时间早,则去下一个周期的开始时间
				if now < fstDayStartTime.Unix() {
					offset = 0
				}
				//否则的话,就取下个周期中,比当前时间所在天最近的一天
				for _, dayInt := range dayList {
					if int64(nowDayInt) <= ToInt64(dayInt, 0) {
						offset = ToInt64(dayInt, 0) - ToInt64(dayList[0], 0)
						break
					}
				}
				_, _, start, end = rule.singleCycleMonthTime(index, interval, offset, rule.BySetPos, start, end)
				fmt.Println("month")
				fmt.Println("start:", start, "end:", end)
				return
			}
		} else {
			_, _, start, end = rule.singleCycleMonthTime(index, interval, 0, rule.BySetPos, start, end)
			if now > end.Unix() {
				index++
				return rule.GetRecurrenceSingleTime2(index, fstStartTime, fstEndTime, now, loc)
			}
		}

	case YearRecurrenceFrequency:
		if rule.BySetPos == "" {
			nextYearTime := start.AddDate(int(index*interval), 0, 0)
			deltaDuration = int64(nextYearTime.Sub(start))
			start = start.Add(time.Duration(deltaDuration))
			end = end.Add(time.Duration(deltaDuration))
		} else {
			bySetPos := ToInt64(rule.BySetPos, 1)
			year, month, _ := start.Date()
			hour, minute, sec := start.Clock()
			start = Date(year+int(index*interval), month, int(bySetPos),
				WeekdayInt(rule.ByDay), hour, minute, sec, start.Location())

			year, month, _ = end.Date()
			hour, minute, sec = end.Clock()
			end = Date(year+int(index*interval), month, int(bySetPos),
				WeekdayInt(rule.ByDay), hour, minute, sec, end.Location())
		}
		if now > end.Unix() {
			index++
			return rule.GetRecurrenceSingleTime2(index, fstStartTime, fstEndTime, now, loc)
		}
	}
	return
}

//返回某个周期的会议的开始、结束时间
//这种case:每周礼拜一、二、五周期会议,会返回第一天的开始、结束(比如:礼拜一)和最后一天的开始、结束时间(比如:礼拜五)
//@index表示第几个周期
//@interval表示周期间隔
//@offset表示某个周期里,最后一天与第一天的时间间隔。比如,这种case:周五和周一的时间间隔
//@fstStart表示周期会议第一场开始时间
//@fstEnd表示周期会议第一场结束时间
//@fstDayStartTime表示某个周期里,第一天的开始时间
//@fstDayEndTime表示某个周期里,第一天的结束时间
//@start某个周期里固定某天的会议开始时间,当offset=0时,等于fstDayStartTime
//@end某个周期里固定某天的会议结束时间,当offset=0时,等于fstDayEndTime
func (rule *TRecurrenceInfo) singleCycleWeekTime(index, interval int64, offset int, fstStart, fstEnd time.Time) (fstDayStartTime, fstDayEndTime, start, end time.Time) {
	deltaDuration := index * interval * WeekDuration
	fstDayStartTime = fstStart.Add(time.Duration(deltaDuration))
	fstDayEndTime = fstEnd.Add(time.Duration(deltaDuration))
	deltaDuration += int64(offset) * DayDuration
	start = fstStart.Add(time.Duration(deltaDuration))
	end = fstEnd.Add(time.Duration(deltaDuration))
	return
}

//返回某个周期的会议的开始、结束时间
//这种case:每月2、3、4、5号周期会议,会返回第一天的开始、结束(比如:2号)和最后一天的开始、结束时间(比如:5号)
//@index表示第几个周期
//@offset表示某个周期里,最后一天与第一天的时间间隔。比如,这种case:周五和周一的时间间隔
//@fstStart表示周期会议第一场开始时间
//@fstEnd表示周期会议第一场结束时间
//@fstDayStartTime表示某个周期里,第一天的开始时间
//@fstDayEndTime表示某个周期里,第一天的结束时间
//@start某个周期里固定某天的会议开始时间,当offset=0时,等于fstDayStartTime
//@end某个周期里固定某天的会议结束时间,当offset=0时,等于fstDayEndTime
func (rule *TRecurrenceInfo) singleCycleMonthTime(index, interval, offset int64, setPos string, fstStart, fstEnd time.Time) (fstDayStartTime, fstDayEndTime, start, end time.Time) {
	nextMonthTime := start.AddDate(0, int(index*interval), 0)
	deltaDuration := int64(nextMonthTime.Sub(start))
	fstDayStartTime = fstStart.Add(time.Duration(deltaDuration))
	fstDayEndTime = fstEnd.Add(time.Duration(deltaDuration))
	deltaDuration += int64(offset) * DayDuration
	start = fstStart.Add(time.Duration(deltaDuration))
	end = fstEnd.Add(time.Duration(deltaDuration))
	if len(setPos) != 0 {
		bySetPos := ToInt64(rule.BySetPos, 1)
		year, month, _ := fstStart.Date()
		hour, minute, sec := fstStart.Clock()
		start = Date(year, month+time.Month(index*interval), int(bySetPos),
			WeekdayInt(rule.ByDay), hour, minute, sec, start.Location())
		fstDayEndTime = start

		year, month, _ = fstEnd.Date()
		hour, minute, sec = fstEnd.Clock()
		end = Date(year, month+time.Month(index*interval), int(bySetPos),
			WeekdayInt(rule.ByDay), hour, minute, sec, end.Location())
		fstDayEndTime = end
	}
	return
}

func (rule *TRecurrenceInfo) convertDayList() []int {
	dayList := strings.Split(rule.ByDay, ",")
	dayWeekInts := make([]int, 0)
	for _, day := range dayList {
		dayWeekInt := int(WeekdayInt(day))
		if dayWeekInt == 0 {
			dayWeekInt = 7
		}
		dayWeekInts = append(dayWeekInts, dayWeekInt)
	}
	sort.Ints(dayWeekInts)
	return dayWeekInts
}

//落在周期规则时间里这一天和第一天所在周几相隔的天数
func getDuration(dayList []string, recentWeekDayInt int64) int64 {
	firstWeekDayInt := int64(WeekdayInt(dayList[0]))
	return recentWeekDayInt - firstWeekDayInt
}

func ToInt64(v interface{}, defaultVal int64) int64 {
	if v == nil {
		return defaultVal
	}

	switch v.(type) {
	case bool:
		if v.(bool) {
			return 1
		}
		return 0
	case string:
		i, err := strconv.ParseInt(v.(string), 10, 64)
		if err != nil {
			return defaultVal
		}
		return i
	case uint64:
		return int64(v.(uint64))
	case int64:
		return int64(v.(int64))
	case int:
		return int64(v.(int))
	case int32:
		return int64(v.(int32))
	case uint32:
		return int64(v.(uint32))
	case float64:
		return int64(v.(float64))
	case int8:
		return int64(v.(int8))
	case uint8:
		return int64(v.(uint8))
	}
	return defaultVal
}

func main() {
	rule := &TRecurrenceInfo{
		Frequency:         "daily",
		Interval:          1,
		RecurrenceEndDate: 0,
	}
	rule = &TRecurrenceInfo{
		Frequency:         "daily",
		Interval:          2,
		RecurrenceEndDate: 0,
	}
	rule = &TRecurrenceInfo{
		Frequency:         "weekly",
		Interval:          1,
		ByDay:             "MO,TU,WE,TH,FR",
		RecurrenceEndDate: 0,
	}
	rule = &TRecurrenceInfo{
		Frequency:         "weekly",
		Interval:          1,
		ByDay:             "MO,WE,FR",
		RecurrenceEndDate: 0,
	}
	rule = &TRecurrenceInfo{
		Frequency:         "weekly",
		Interval:          2,
		ByDay:             "MO,WE,FR",
		RecurrenceEndDate: 0,
	}
	rule = &TRecurrenceInfo{
		Frequency:         "weekly",
		Interval:          2,
		ByDay:             "MO,WE,FR",
		RecurrenceEndDate: 0,
	}
	nowStr := "2022-08-09 10:00:00"
	startStr := "2022-08-01 10:00:00"
	endStr := "2022-08-01 11:00:00"
	now, _ := time.Parse(FORMAT_DATETIME, nowStr)
	start, _ := time.Parse(FORMAT_DATETIME, startStr)
	end, _ := time.Parse(FORMAT_DATETIME, endStr)
	fmt.Println("now:", now.Unix(), "start:", start.Unix())
	s, e := rule.GetRecurrenceSingleTime2(0, start.Unix(), end.Unix(), now.Unix(), time.Local)
	fmt.Println("【周N周后M+天每几周星期几】递归的方式获取周期单场时间:start,end", s, e)
	rule = &TRecurrenceInfo{
		Frequency:         "weekly",
		Interval:          2,
		ByDay:             "MO",
		RecurrenceEndDate: 0,
	}
	nowStr = "2022-08-09 10:00:00"
	startStr = "2022-08-01 10:00:00"
	endStr = "2022-08-01 11:00:00"
	now, _ = time.Parse(FORMAT_DATETIME, nowStr)
	start, _ = time.Parse(FORMAT_DATETIME, startStr)
	end, _ = time.Parse(FORMAT_DATETIME, endStr)
	fmt.Println("now:", now.Unix(), "start:", start.Unix())
	s, e = rule.GetRecurrenceSingleTime2(0, start.Unix(), end.Unix(), now.Unix(), time.Local)
	fmt.Println("【周】递归的方式获取周期单场时间:start,end", s, e)
	rule = &TRecurrenceInfo{
		Frequency:         "monthly",
		Interval:          1,
		ByMonthDay:        "1,2,3,4,5,8,18",
		RecurrenceEndDate: 0,
	}
	nowStr = "2022-08-09 10:00:00"
	startStr = "2022-08-01 10:00:00"
	endStr = "2022-08-01 11:00:00"
	now, _ = time.Parse(FORMAT_DATETIME, nowStr)
	start, _ = time.Parse(FORMAT_DATETIME, startStr)
	end, _ = time.Parse(FORMAT_DATETIME, endStr)
	s, e = rule.GetRecurrenceSingleTime2(0, start.Unix(), end.Unix(), now.Unix(), time.Local)
	fmt.Println("【月每几月的几号】递归的方式获取周期单场时间:start,end", s, e)

	rule = &TRecurrenceInfo{
		Frequency:         "monthly",
		Interval:          1,
		ByDay:             "MO",
		BySetPos:          "2",
		RecurrenceEndDate: 0,
	}
	nowStr = "2022-08-09 10:00:00"
	startStr = "2022-08-08 10:00:00"
	endStr = "2022-08-08 11:00:00"
	now, _ = time.Parse(FORMAT_DATETIME, nowStr)
	start, _ = time.Parse(FORMAT_DATETIME, startStr)
	end, _ = time.Parse(FORMAT_DATETIME, endStr)
	s, e = rule.GetRecurrenceSingleTime2(0, start.Unix(), end.Unix(), now.Unix(), time.Local)
	fmt.Println("【月每几月的第几个星期几】递归的方式获取周期单场时间:start,end", s, e)
	// recentDay, recentWeekDayInt, recentDayInt := recentDay(now.Unix(), []string{"MO", "WE", "FR"}, time.Local)
	// fmt.Println("**************")
	// fmt.Println(recentDay, recentWeekDayInt, recentDayInt)
	getFstTime()
}

func getFstTime() {
	rule := &TRecurrenceInfo{
		Frequency:         "daily",
		Interval:          2,
		RecurrenceEndDate: 0,
	}
	startStr := "2022-08-11 10:00:00"
	endStr := "2022-08-11 11:00:00"
	start, _ := time.Parse(FORMAT_DATETIME, startStr)
	end, _ := time.Parse(FORMAT_DATETIME, endStr)
	fstStart, fstEnd := rule.GetFstTime(start.Unix(), end.Unix(), 1, time.Local)
	fmt.Println("【每两天】", fstStart, fstEnd)
	rule = &TRecurrenceInfo{
		Frequency:         "weekly",
		Interval:          1,
		ByDay:             "MO,TU,WE,TH,FR",
		RecurrenceEndDate: 0,
	}
	fstStart, fstEnd = rule.GetFstTime(start.Unix(), end.Unix(), 1, time.Local)
	fmt.Println("【每周一二三四五】", fstStart, fstEnd)
	rule = &TRecurrenceInfo{
		Frequency:         "weekly",
		Interval:          1,
		ByDay:             "TH",
		RecurrenceEndDate: 0,
	}
	fstStart, fstEnd = rule.GetFstTime(start.Unix(), end.Unix(), 1, time.Local)
	fmt.Println("【每周四】", fstStart, fstEnd)
	rule = &TRecurrenceInfo{
		Frequency:         "monthly",
		Interval:          1,
		ByMonthDay:        "1,2,3,4,5,8,18",
		RecurrenceEndDate: 0,
	}
	fstStart, fstEnd = rule.GetFstTime(start.Unix(), end.Unix(), 1, time.Local)
	fmt.Println("【月每几月的几号】", fstStart, fstEnd)
	rule = &TRecurrenceInfo{
		Frequency:         "monthly",
		Interval:          1,
		ByDay:             "MO",
		BySetPos:          "2",
		RecurrenceEndDate: 0,
	}
	fstStart, fstEnd = rule.GetFstTime(start.Unix(), end.Unix(), 1, time.Local)
	fmt.Println("【月每几月的第几个星期几】", fstStart, fstEnd)
	rule = &TRecurrenceInfo{
		Frequency:         "yearly",
		Interval:          1,
		ByMonth:           "1",
		ByMonthDay:        "1",
		RecurrenceEndDate: 0,
	}
	fstStart, fstEnd = rule.GetFstTime(start.Unix(), end.Unix(), 1, time.Local)
	fmt.Println("【每年第一个月1号】", fstStart, fstEnd)
	rule = &TRecurrenceInfo{
		Frequency:         "yearly",
		Interval:          1,
		ByMonth:           "1",
		BySetPos:          "1",
		ByDay:             "MO",
		RecurrenceEndDate: 0,
	}
	fstStart, fstEnd = rule.GetFstTime(start.Unix(), end.Unix(), 1, time.Local)
	fmt.Println("【每年第一个月第一周礼拜一】", fstStart, fstEnd)
}

你可能感兴趣的:(Go,golang)