robfig / cron

a cron library for go
MIT License
13.14k stars 1.63k forks source link

How to schedule job to run on every 2nd thursday of month at 10:10 AM #518

Open maddalieswar opened 8 months ago

maddalieswar commented 8 months ago

How to schedule job to run on every 2nd thursday of month at 10:10 AM using cron expression or predefined functions.

I tried multiple ways but it did not work.Tried below cron expressions:

1 54 8 1-8 THU (This approach is to schedule job based on day of month) 1 54 8 * 4#2

Can someone please help.

janrnc commented 8 months ago

Hello @maddalieswar,

you could start from something like this. I didn't test it in detail, give it a proper review:

type schedule struct{}
func (s *schedule) Next(now time.Time) time.Time {
    dayOfMonth := secondThursday(now.Year(), now.Month())
    result := time.Date(now.Year(), now.Month(), dayOfMonth, 10, 10, 0, 0, now.Location())
    if result.Before(now) {
        nextMonth := result.AddDate(0, 1, 0)
        dayOfMonth = secondThursday(nextMonth.Year(), nextMonth.Month())
        result = time.Date(nextMonth.Year(), nextMonth.Month(), dayOfMonth, 10, 10, 0, 0, now.Location())
    }
    return result
}

func secondThursday(year int, month time.Month) int {
    count := 0
    daysOfMonth := daysIn(month, year)
    for day := 1; day <= daysOfMonth; day++ {
        date := time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
        if date.Weekday() == 4 {
            count += 1
        }
        if count >= 2 {
            return day
        }
    }
    panic("cannot find second thursday of month")
}

func daysIn(month time.Month, year int) int {
    return time.Date(year, month+1, 0, 0, 0, 0, 0, time.UTC).Day()
}