-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathrrule_compile.go
More file actions
67 lines (62 loc) · 1.67 KB
/
rrule_compile.go
File metadata and controls
67 lines (62 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package scheduler
import (
"fmt"
"math"
"strings"
"time"
rrule "github.com/teambition/rrule-go"
schedulepb "go.temporal.io/api/schedule/v1"
)
func scheduleRRuleDTStart(spec *schedulepb.ScheduleSpec, loc *time.Location) time.Time {
if spec.GetStartTime() != nil {
return spec.GetStartTime().AsTime().In(loc)
}
return time.Unix(0, 0).In(loc)
}
// compileRRuleStrings parses and compiles rrule string bodies (no "RRULE:" prefix) with a
// single DTSTART derived from start_time (or the Unix epoch in the schedule time zone).
func compileRRuleStrings(spec *schedulepb.ScheduleSpec, loc *time.Location) ([]*rrule.RRule, error) {
lines := spec.GetRrule()
if len(lines) == 0 {
return nil, nil
}
if len(lines) > maxRruleCount {
return nil, fmt.Errorf("too many rrule lines: max %d", maxRruleCount)
}
dt := scheduleRRuleDTStart(spec, loc)
out := make([]*rrule.RRule, 0, len(lines))
for i, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
return nil, fmt.Errorf("rrule at index %d is empty", i)
}
if len(line) > maxRruleStringLen {
return nil, fmt.Errorf("rrule at index %d is too long", i)
}
r, err := rrule.StrToRRule(line)
if err != nil {
return nil, err
}
r.DTStart(dt)
out = append(out, r)
}
return out, nil
}
// nextRRuleTime returns the earliest Unix second from all RRULEs strictly after t, or
// MaxInt64 if there is no occurrence.
func nextRRuleTime(rrs []*rrule.RRule, after time.Time) int64 {
var minTs int64 = math.MaxInt64
for _, r := range rrs {
if r == nil {
continue
}
next := r.After(after, false)
if next.IsZero() {
continue
}
if u := next.UTC().Unix(); u < minTs {
minTs = u
}
}
return minTs
}