A Go library for performing time arithmetic operations on cron expressions. Add or subtract minutes and hours from cron expressions with a simple, fluent API.
go get github.com/ryutaro-asada/cronmathConvert schedules between timezones:
// Convert UTC to JST (UTC+9)
jstSchedule := cronmath.New("0 3 * * *").Add(cronmath.Hours(9))
fmt.Println(jstSchedule.String()) // "0 12 * * *"
// Convert EST to UTC (EST is UTC-5)
utcSchedule := cronmath.New("0 10 * * *").Add(cronmath.Hours(5))
fmt.Println(utcSchedule.String()) // "0 15 * * *"
// Convert PST to EST (PST is UTC-8, EST is UTC-5)
estSchedule := cronmath.New("0 9 * * *").Add(cronmath.Hours(3))
fmt.Println(estSchedule.String()) // "0 12 * * *"Create staggered schedules to avoid resource contention:
baseTime := "0 2 * * *" // 2:00 AM
schedules := []struct {
name string
offset cronmath.Duration
}{
{"primary", 0},
{"secondary", cronmath.Minutes(15)},
{"tertiary", cronmath.Minutes(30)},
{"quaternary", cronmath.Hours(1)},
}
for _, s := range schedules {
schedule := cronmath.New(baseTime).Add(s.offset)
fmt.Printf("%s: %s\n", s.name, schedule.String())
}
// Output:
// primary: 0 2 * * *
// secondary: 15 2 * * *
// tertiary: 30 2 * * *
// quaternary: 0 3 * * *The library automatically handles transitions across midnight:
// Subtract time crossing midnight backward
result := cronmath.New("30 0 * * *").Sub(cronmath.Hours(1))
fmt.Println(result.String()) // "30 23 * * *"
// Add time crossing midnight forward
result = cronmath.New("30 23 * * *").Add(cronmath.Hours(2))
fmt.Println(result.String()) // "30 1 * * *"
// Complex boundary case
result = cronmath.New("45 23 * * *").
Add(cronmath.Hours(3)).
Add(cronmath.Minutes(30))
fmt.Println(result.String()) // "15 3 * * *"Different approaches for error handling:
// Method 1: Check error at the end
cm := cronmath.New("invalid cron")
result := cm.Add(cronmath.Hours(1))
if err := result.Error(); err != nil {
log.Printf("Error: %v", err)
}
// Method 2: Use Result() for combined return
result, err := cronmath.New("0 9 * * *").
Add(cronmath.Hours(2)).
Result()
if err != nil {
return fmt.Errorf("failed to calculate cron: %w", err)
}
// Method 3: Direct CronTime manipulation
cron, err := cronmath.ParseCron("0 9 * * *")
if err != nil {
return err
}
if err := cron.Add(cronmath.Hours(1)); err != nil {
return err
}This library supports standard 5-field cron expressions:
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday)
│ │ │ │ │
* * * * *
0 9 * * *- Every day at 9:00 AM30 14 * * 1-5- Weekdays at 2:30 PM0 0 1 * *- First day of every month at midnight15 10 * * 6,0- Weekends at 10:15 AM
- Only minute and hour fields can be modified - Day, month, and day of week fields remain unchanged
- Wildcards in time fields cannot be adjusted - Expressions like
* 9 * * *will return an error - No support for complex expressions - Ranges (
0-30), lists (15,30,45), and steps (*/5) are not supported in minute/hour fields - No validation of day/month combinations - The library doesn't validate if the resulting date is valid
Run tests:
go test ./...This project is licensed under the MIT License - see the LICENSE file for details.
- 📧 For questions and support, please open an issue
- 🐛 For bug reports, please include a minimal reproducible example
- 💡 For feature requests, please describe your use case