This repository has been archived by the owner on Oct 9, 2024. It is now read-only.
forked from evcc-io/evcc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
day.go
122 lines (100 loc) · 2.01 KB
/
day.go
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package fixed
import (
"errors"
"fmt"
"slices"
"strconv"
"strings"
)
//go:generate enumer -type Day
type Day int
const (
Sunday Day = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
var Week = []Day{Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}
var shortDays = map[string]Day{
// english
"sun": Sunday,
"mon": Monday,
"tue": Tuesday,
"wed": Wednesday,
"thu": Thursday,
"fri": Friday,
"sat": Saturday,
// german
"so": Sunday,
"mo": Monday,
"di": Tuesday,
"mi": Wednesday,
"do": Thursday,
"fr": Friday,
"sa": Saturday,
}
// ParseDay parses a single day
func ParseDay(s string) (Day, error) {
s = strings.ToLower(strings.TrimSpace(s))
// full string
if d, err := DayString(s); err == nil {
return d, nil
}
// short string
if d, ok := shortDays[s]; ok {
return d, nil
}
d, err := strconv.Atoi(s)
if d < 0 || d > 7 || err != nil {
return 0, fmt.Errorf("invalid day: %s", s)
}
return Day(d % 7), nil
}
// ParseDays converts a days string into a slice of individual days
// Days format:
//
// day[-day][, ...]
func ParseDays(s string) ([]Day, error) {
var res []Day
for _, segment := range strings.Split(s, ",") {
fromto := strings.SplitN(segment, "-", 2)
if len(fromto) == 0 {
return nil, fmt.Errorf("invalid day range: %s", segment)
}
fromToFrom := fromto[0]
// single empty segment
if len(fromto) == 1 && strings.TrimSpace(fromToFrom) == "" {
return slices.Clone(Week), nil
}
from, err := ParseDay(fromToFrom)
if err != nil {
return nil, err
}
res = append(res, Day(from%7))
if len(fromto) == 2 {
to, err := ParseDay(fromto[1])
if err != nil {
return nil, err
}
if to < from {
to += 7
}
for d := from + 1; d <= to; d++ {
res = append(res, d%7)
}
}
}
if len(res) > 7 {
return nil, errors.New("too many days")
}
sorted := make([]Day, len(res))
copy(sorted, res)
slices.Sort(sorted)
if len(slices.Compact(sorted)) < len(res) {
return nil, errors.New("duplicate days")
}
return res, nil
}