@@ -34,12 +34,18 @@ var defaultParser = cron.NewParser(parserFormat)
34
34
// us_sched, _ := schedule.Weekly("CRON_TZ=US/Central 30 9 1-5")
35
35
// fmt.Println(sched.Next(time.Now()).Format(time.RFC3339))
36
36
// // Output: 2022-04-04T14:30:00Z
37
- func Weekly (spec string ) (* Schedule , error ) {
38
- if err := validateWeeklySpec (spec ); err != nil {
37
+ func Weekly (raw string ) (* Schedule , error ) {
38
+ if err := validateWeeklySpec (raw ); err != nil {
39
39
return nil , xerrors .Errorf ("validate weekly schedule: %w" , err )
40
40
}
41
41
42
- specSched , err := defaultParser .Parse (spec )
42
+ // If schedule does not specify a timezone, default to UTC. Otherwise,
43
+ // the library will default to time.Local which we want to avoid.
44
+ if ! strings .HasPrefix (raw , "CRON_TZ=" ) {
45
+ raw = "CRON_TZ=UTC " + raw
46
+ }
47
+
48
+ specSched , err := defaultParser .Parse (raw )
43
49
if err != nil {
44
50
return nil , xerrors .Errorf ("parse schedule: %w" , err )
45
51
}
@@ -49,9 +55,16 @@ func Weekly(spec string) (*Schedule, error) {
49
55
return nil , xerrors .Errorf ("expected *cron.SpecSchedule but got %T" , specSched )
50
56
}
51
57
58
+ // Strip the leading CRON_TZ prefix so we just store the cron string.
59
+ // The timezone info is available in SpecSchedule.
60
+ cronStr := raw
61
+ if strings .HasPrefix (raw , "CRON_TZ=" ) {
62
+ cronStr = strings .Join (strings .Fields (raw )[1 :], " " )
63
+ }
64
+
52
65
cronSched := & Schedule {
53
- sched : schedule ,
54
- spec : spec ,
66
+ sched : schedule ,
67
+ cronStr : cronStr ,
55
68
}
56
69
return cronSched , nil
57
70
}
@@ -61,12 +74,29 @@ func Weekly(spec string) (*Schedule, error) {
61
74
type Schedule struct {
62
75
sched * cron.SpecSchedule
63
76
// XXX: there isn't any nice way for robfig/cron to serialize
64
- spec string
77
+ cronStr string
65
78
}
66
79
67
80
// String serializes the schedule to its original human-friendly format.
81
+ // The leading CRON_TZ is maintained.
68
82
func (s Schedule ) String () string {
69
- return s .spec
83
+ var sb strings.Builder
84
+ _ , _ = sb .WriteString ("CRON_TZ=" )
85
+ _ , _ = sb .WriteString (s .sched .Location .String ())
86
+ _ , _ = sb .WriteString (" " )
87
+ _ , _ = sb .WriteString (s .cronStr )
88
+ return sb .String ()
89
+ }
90
+
91
+ // Timezone returns the timezone for the schedule.
92
+ func (s Schedule ) Timezone () string {
93
+ return s .sched .Location .String ()
94
+ }
95
+
96
+ // Cron returns the cron spec for the schedule with the leading CRON_TZ
97
+ // stripped, if present.
98
+ func (s Schedule ) Cron () string {
99
+ return s .cronStr
70
100
}
71
101
72
102
// Next returns the next time in the schedule relative to t.
0 commit comments