oficina / calendar Public

Clone
git clone https://amadan.net/oficina/calendar

Plain git — no account needed to clone.

Download

Download this file

1package calendar
2
3import "time"
4
5var firstCivilDay = civilDay(time.Date(0, 1, 1, 0, 0, 0, 0, time.UTC))
6var lastCivilDay = civilDay(time.Date(9999, 12, 31, 0, 0, 0, 0, time.UTC))
7
8func civilDay(t time.Time) int64 { return civil(t).Unix() / 86400 }
9func inDateHorizon(t time.Time) bool { return t.Year() >= 0 && t.Year() <= 9999 }
10
11func candidateOnDay(day int64, proto time.Time, loc *time.Location) (time.Time, stepState) {
12 if day < firstCivilDay || day > lastCivilDay {
13 return time.Time{}, stepIncomplete
14 }
15 candidate := onDate(time.Unix(day*86400, 0).UTC(), proto, loc)
16 if !inDateHorizon(candidate) {
17 return time.Time{}, stepIncomplete
18 }
19 return candidate, stepCandidate
20}
21
22func validExpansionRule(r Rule) bool {
23 if r.Count < 0 || r.Count > 0 && r.HasUntil {
24 return false
25 }
26 if r.HasUntil && !inDateHorizon(r.Until) {
27 return false
28 }
29 if r.Freq == "" {
30 return len(r.ByDay) == 0 && r.Ordinal == 0 && r.MonthDay == 0
31 }
32 if r.Interval < 1 {
33 return false
34 }
35 switch r.Freq {
36 case FreqWeekly:
37 if r.WeekStart < time.Sunday || r.WeekStart > time.Saturday || r.MonthDay != 0 || r.Ordinal != 0 {
38 return false
39 }
40 for _, day := range r.ByDay {
41 if day < time.Sunday || day > time.Saturday {
42 return false
43 }
44 }
45 case FreqMonthly:
46 if len(r.ByDay) != 0 || r.MonthDay < 0 || r.MonthDay > 31 || r.Ordinal != 0 && (r.MonthDay != 0 || r.OrdinalDay < time.Sunday || r.OrdinalDay > time.Saturday) {
47 return false
48 }
49 case FreqDaily, FreqYearly:
50 if len(r.ByDay) != 0 || r.MonthDay != 0 || r.Ordinal != 0 {
51 return false
52 }
53 default:
54 return false
55 }
56 return true
57}
58