A powerful Go cron expression parser and task scheduler that supports standard cron syntax, second-level precision, timezone control, and custom clock mechanisms.
Forked from robfig/cron
- Standard Cron Syntax - Default support for standard 5-field cron expressions (minute, hour, day, month, weekday); optional second field support
- Predefined Schedules - Support for convenient expressions like @hourly, @daily, @weekly, @monthly, @yearly
- Fixed Intervals - Fixed time interval scheduling using @every syntax
- Timezone Support - Global and per-task timezone configuration
- Dynamic Management - Add, remove, and view tasks at runtime
- Thread-Safe - All operations are carefully designed to ensure concurrency safety
- Multiple Clocks - Support for default system clock, simulated clock, and custom clocks
Free control of time through the Clock interface, supporting:
- DefaultClock - Uses system clock (default)
- FakeClock - Simulated clock for unit testing
- Custom Implementation - Such as passing in NTP precise network time
go get github.com/banbox/cron/v3Requires Go 1.11 or higher (using Go Modules).
package main
import (
"fmt""github.com/banbox/cron/v3"
)
funcmain() {
c:=cron.New()
// Execute at the 30th minute of every hourc.AddFunc("30 * * * *", func() {
fmt.Println("Executes once per hour")
})
// Start the schedulerc.Start()
// Block main programselect {}
}// Support for second-level precisionc:=cron.New(cron.WithSeconds())
// Execute every secondc.AddFunc("* * * * * *", func() {
fmt.Println("Executes every second")
})
// @hourly, @daily, @weekly, @monthly, @yearlyc.AddFunc("@hourly", func() { fmt.Println("Every hour") })
// Execute every 1 hour 30 minutesc.AddFunc("@every 1h30m", func() {
fmt.Println("Executes every 90 minutes")
})
c.Start()import"time"// Global timezone settingloc, _:=time.LoadLocation("Asia/Shanghai")
c:=cron.New(cron.WithClock(cron.NewDefaultClock(loc)))
// Specify timezone for individual taskc.AddFunc("CRON_TZ=Asia/Tokyo 0 6 * * *", func() {
fmt.Println("Executes at 6 AM Tokyo time every day")
})
c.Start()c:=cron.New()
// Add task and get IDid, _:=c.AddFunc("@every 1m", func() {
fmt.Println("Task executing")
})
c.Start()
// View all tasksfor_, entry:=rangec.Entries() {
fmt.Printf("Task %d: Next execution time %v\n", entry.ID, entry.Next)
}
// Remove taskc.Remove(id)
// Stop schedulerctx:=c.Stop()
<-ctx.Done() // Wait for all running tasks to completetypeMyJobstruct {
Namestring
}
func (jMyJob) Run() {
fmt.Printf("Executing task: %s\n", j.Name)
}
c:=cron.New()
c.AddJob("@every 1m", MyJob{Name: "Data Sync"})
c.Start()funcTestMultipleExecutions(t*testing.T) {
startTime:=time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
fakeClock:=cron.NewFakeClock(time.UTC, startTime)
c:=cron.New(cron.WithClock(fakeClock), cron.WithSeconds())
count:=0c.AddFunc("0 0 * * * *", func() { count++ })
c.Start()
deferc.Stop()
// Advance 24 hours, should execute 24 timesc.RunTo(startTime.Add(24*time.Hour))
ifcount!=24 {
t.Errorf("Expected 24 executions, got %d", count)
}
}cron has built-in bntp support, allowing you to use NTP as a time source (standard network time) to ensure tasks are triggered accurately at the correct network time.
package main
import (
"fmt""time""github.com/banbox/cron/v3""github.com/banbox/bntp"
)
funcmain() {
// Create cron scheduler using ntp time sourceloc, _:=time.LoadLocation("Asia/Shanghai")
ntpClock:=NewNtpClock(loc, bntp.LangGlobal)
c:=cron.New(cron.WithClock(ntpClock))
// Add taskc.AddFunc("* * * * *", func() {
realTime:=bntp.UTCStamp()
sysTime:=time.Now().UnixMilli()
fmt.Println("system: %d, real: %d", sysTime, realTime)
})
c.Start()
// Block main programselect {}
}You can also use other custom time sources, but you need to implement the Clock interface. You can refer to NtpClock as an example.
Then use the cron.WithClock() option to pass in your custom time source.
30 * * * * At the 30th minute of every hour
0 0 * * * Every day at midnight
0 0 1 * * First day of every month at midnight
0 0 * * 0 Every Sunday at midnight
*/15 * * * * Every 15 minutes
0 9-17 * * * Every hour from 9 AM to 5 PM
MIT License