CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/golang-github-com-go-co-op-gocron-v2

A Golang job scheduling library that lets you run Go functions at pre-determined intervals using cron expressions, fixed durations, daily, weekly, monthly, or one-time schedules with support for distributed deployments.

Overview
Eval results
Files

time-based-scheduling.mddocs/guides/advanced/

Time-Based Scheduling

Detailed guide to scheduling jobs at specific times.

Overview

Gocron supports scheduling jobs at specific times using:

  • DailyJob: Run at specific times each day
  • WeeklyJob: Run on specific days of the week
  • MonthlyJob: Run on specific days of the month
  • CronJob: Complex time expressions

Daily Scheduling

Basic Daily Job

Run once per day at specific time:

j, _ := s.NewJob(
    gocron.DailyJob(
        1, // Every 1 day
        gocron.NewAtTimes(
            gocron.NewAtTime(9, 0, 0), // 9:00:00 AM
        ),
    ),
    gocron.NewTask(dailyReport),
)

Multiple Times Per Day

Run at multiple times:

j, _ := s.NewJob(
    gocron.DailyJob(
        1,
        gocron.NewAtTimes(
            gocron.NewAtTime(9, 0, 0),  // 9 AM
            gocron.NewAtTime(12, 0, 0), // Noon
            gocron.NewAtTime(17, 0, 0), // 5 PM
        ),
    ),
    gocron.NewTask(statusCheck),
)

Every N Days

Run every N days:

j, _ := s.NewJob(
    gocron.DailyJob(
        3, // Every 3 days
        gocron.NewAtTimes(
            gocron.NewAtTime(0, 0, 0), // Midnight
        ),
    ),
    gocron.NewTask(weeklyReport),
)

Weekly Scheduling

Specific Day of Week

j, _ := s.NewJob(
    gocron.WeeklyJob(
        1, // Every week
        gocron.NewWeekdays(time.Monday),
        gocron.NewAtTimes(
            gocron.NewAtTime(9, 0, 0),
        ),
    ),
    gocron.NewTask(mondayMeeting),
)

Multiple Days

j, _ := s.NewJob(
    gocron.WeeklyJob(
        1,
        gocron.NewWeekdays(time.Monday, time.Wednesday, time.Friday),
        gocron.NewAtTimes(
            gocron.NewAtTime(10, 0, 0),
        ),
    ),
    gocron.NewTask(weekdayTask),
)

Weekdays Only

j, _ := s.NewJob(
    gocron.WeeklyJob(
        1,
        gocron.NewWeekdays(
            time.Monday,
            time.Tuesday,
            time.Wednesday,
            time.Thursday,
            time.Friday,
        ),
        gocron.NewAtTimes(
            gocron.NewAtTime(9, 0, 0),
        ),
    ),
    gocron.NewTask(businessDayTask),
)

Every N Weeks

j, _ := s.NewJob(
    gocron.WeeklyJob(
        2, // Every 2 weeks
        gocron.NewWeekdays(time.Monday),
        gocron.NewAtTimes(
            gocron.NewAtTime(14, 0, 0),
        ),
    ),
    gocron.NewTask(biweeklyReview),
)

Monthly Scheduling

Specific Day of Month

j, _ := s.NewJob(
    gocron.MonthlyJob(
        1, // Every month
        gocron.NewDaysOfTheMonth(1), // 1st of month
        gocron.NewAtTimes(
            gocron.NewAtTime(0, 0, 0),
        ),
    ),
    gocron.NewTask(monthlyBilling),
)

Multiple Days

j, _ := s.NewJob(
    gocron.MonthlyJob(
        1,
        gocron.NewDaysOfTheMonth(1, 15), // 1st and 15th
        gocron.NewAtTimes(
            gocron.NewAtTime(12, 0, 0),
        ),
    ),
    gocron.NewTask(semiMonthlyReport),
)

Last Day of Month

j, _ := s.NewJob(
    gocron.MonthlyJob(
        1,
        gocron.NewDaysOfTheMonth(-1), // Last day
        gocron.NewAtTimes(
            gocron.NewAtTime(23, 59, 0),
        ),
    ),
    gocron.NewTask(monthEndClosing),
)

Every N Months

j, _ := s.NewJob(
    gocron.MonthlyJob(
        3, // Every 3 months (quarterly)
        gocron.NewDaysOfTheMonth(1),
        gocron.NewAtTimes(
            gocron.NewAtTime(9, 0, 0),
        ),
    ),
    gocron.NewTask(quarterlyReport),
)

Cron Expressions

Basic Patterns

// Every minute
j, _ := s.NewJob(
    gocron.CronJob("* * * * *", false),
    gocron.NewTask(everyMinute),
)

// Every hour at minute 0
j, _ = s.NewJob(
    gocron.CronJob("0 * * * *", false),
    gocron.NewTask(hourly),
)

// Daily at midnight
j, _ = s.NewJob(
    gocron.CronJob("0 0 * * *", false),
    gocron.NewTask(daily),
)

// Weekly on Sunday at midnight
j, _ = s.NewJob(
    gocron.CronJob("0 0 * * 0", false),
    gocron.NewTask(weekly),
)

// Monthly on 1st at midnight
j, _ = s.NewJob(
    gocron.CronJob("0 0 1 * *", false),
    gocron.NewTask(monthly),
)

Advanced Patterns

// Every 15 minutes
j, _ := s.NewJob(
    gocron.CronJob("*/15 * * * *", false),
    gocron.NewTask(every15min),
)

// Business hours (9 AM - 5 PM, weekdays)
j, _ = s.NewJob(
    gocron.CronJob("0 9-17 * * 1-5", false),
    gocron.NewTask(businessHours),
)

// Last day of month
j, _ = s.NewJob(
    gocron.CronJob("0 0 L * *", false),
    gocron.NewTask(monthEnd),
)

// Every weekday at 9 AM
j, _ = s.NewJob(
    gocron.CronJob("0 9 * * 1-5", false),
    gocron.NewTask(weekdayMorning),
)

Cron with Timezone

j, _ := s.NewJob(
    gocron.CronJob("TZ=America/New_York 0 9 * * *", false),
    gocron.NewTask(eastCoastTask),
)

Timezone Handling

Scheduler-Level Timezone

All jobs use same timezone:

loc, _ := time.LoadLocation("America/Chicago")
s, _ := gocron.NewScheduler(
    gocron.WithLocation(loc),
)

// All jobs run in Chicago time
j1, _ := s.NewJob(
    gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0))),
    gocron.NewTask(task1),
)

j2, _ := s.NewJob(
    gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(17, 0, 0))),
    gocron.NewTask(task2),
)

Per-Job Timezone (Cron Only)

Different timezones per job:

// East Coast job
j1, _ := s.NewJob(
    gocron.CronJob("TZ=America/New_York 0 9 * * *", false),
    gocron.NewTask(eastCoastReport),
)

// West Coast job
j2, _ := s.NewJob(
    gocron.CronJob("TZ=America/Los_Angeles 0 9 * * *", false),
    gocron.NewTask(westCoastReport),
)

// UTC job
j3, _ := s.NewJob(
    gocron.CronJob("TZ=UTC 0 0 * * *", false),
    gocron.NewTask(globalReport),
)

DST Considerations

Daylight Saving Time transitions are handled automatically:

loc, _ := time.LoadLocation("America/New_York")
s, _ := gocron.NewScheduler(
    gocron.WithLocation(loc),
)

// Runs at 9 AM local time, accounting for DST
j, _ := s.NewJob(
    gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0))),
    gocron.NewTask(dailyTask),
)

Complex Scheduling Patterns

Business Days Only

j, _ := s.NewJob(
    gocron.CronJob("0 9 * * 1-5", false), // Mon-Fri at 9 AM
    gocron.NewTask(func() {
        // Additional holiday check
        if isHoliday(time.Now()) {
            return
        }
        doBusinessDayWork()
    }),
)

Conditional Execution

j, _ := s.NewJob(
    gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(0, 0, 0))),
    gocron.NewTask(func() {
        if shouldRun() {
            doWork()
        }
    }),
)

Time Windows

j, _ := s.NewJob(
    gocron.DurationJob(time.Minute),
    gocron.NewTask(func() {
        now := time.Now()
        if now.Hour() >= 9 && now.Hour() < 17 {
            doWorkDuringBusinessHours()
        }
    }),
)

Multi-Schedule Jobs

Run at different times on different days:

// Weekday schedule
j1, _ := s.NewJob(
    gocron.CronJob("0 9 * * 1-5", false),
    gocron.NewTask(weekdayMorning),
)

// Weekend schedule
j2, _ := s.NewJob(
    gocron.CronJob("0 10 * * 0,6", false),
    gocron.NewTask(weekendMorning),
)

Best Practices

1. Use Appropriate Granularity

// Good: Daily job for daily tasks
gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(0, 0, 0)))

// Bad: Cron checking date
gocron.CronJob("* * * * *", false) // Checks every minute

2. Consider Timezones

// Explicit timezone
loc, _ := time.LoadLocation("America/New_York")
s, _ := gocron.NewScheduler(gocron.WithLocation(loc))

3. Handle Edge Cases

j, _ := s.NewJob(
    gocron.MonthlyJob(
        1,
        gocron.NewDaysOfTheMonth(31), // Not all months have 31 days
        gocron.NewAtTimes(gocron.NewAtTime(0, 0, 0)),
    ),
    gocron.NewTask(monthEndTask),
)

4. Test Scheduling

// Log next run time to verify
j, _ := s.NewJob(
    gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(9, 0, 0))),
    gocron.NewTask(myTask),
)
log.Printf("Next run: %v", j.NextRun())

Examples by Use Case

Daily Reports

j, _ := s.NewJob(
    gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(8, 0, 0))),
    gocron.NewTask(generateDailyReport),
    gocron.WithName("daily-report"),
)

Weekly Maintenance

j, _ := s.NewJob(
    gocron.WeeklyJob(
        1,
        gocron.NewWeekdays(time.Sunday),
        gocron.NewAtTimes(gocron.NewAtTime(2, 0, 0)), // 2 AM Sunday
    ),
    gocron.NewTask(weeklyMaintenance),
    gocron.WithName("weekly-maintenance"),
)

Monthly Billing

j, _ := s.NewJob(
    gocron.MonthlyJob(
        1,
        gocron.NewDaysOfTheMonth(1),
        gocron.NewAtTimes(gocron.NewAtTime(0, 0, 0)),
    ),
    gocron.NewTask(processBilling),
    gocron.WithName("monthly-billing"),
)

Business Hours Monitoring

j, _ := s.NewJob(
    gocron.CronJob("*/5 9-17 * * 1-5", false), // Every 5min, 9-5, Mon-Fri
    gocron.NewTask(monitorServices),
    gocron.WithName("business-hours-monitor"),
)

See Also

  • API: Time-Based Jobs - API reference
  • API: Cron Jobs - Cron expressions
  • Advanced Scheduling Guide - Overview

Install with Tessl CLI

npx tessl i tessl/golang-github-com-go-co-op-gocron-v2@2.19.1

docs

index.md

tile.json