forked from DNSCrypt/dnscrypt-proxy
/
time_ranges.go
107 lines (97 loc) · 2.75 KB
/
time_ranges.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
package dnscrypt
import (
"fmt"
"strconv"
"strings"
"time"
)
type TimeRange struct {
after int
before int
}
type WeeklyRanges struct {
ranges [7][]TimeRange
}
type TimeRangeStr struct {
After string
Before string
}
type WeeklyRangesStr struct {
Sun, Mon, Tue, Wed, Thu, Fri, Sat []TimeRangeStr
}
func daySecsFromStr(str string) (int, error) {
parts := strings.Split(str, ":")
if len(parts) != 2 {
return -1, fmt.Errorf("Syntax error in a time expression: [%s]", str)
}
hours, err := strconv.Atoi(parts[0])
if err != nil || hours < 0 || hours > 23 {
return -1, fmt.Errorf("Syntax error in a time expression: [%s]", str)
}
minutes, err := strconv.Atoi(parts[1])
if err != nil || minutes < 0 || minutes > 59 {
return -1, fmt.Errorf("Syntax error in a time expression: [%s]", str)
}
return (hours*60 + minutes) * 60, nil
}
func parseTimeRanges(timeRangesStr []TimeRangeStr) ([]TimeRange, error) {
timeRanges := []TimeRange{}
for _, timeRangeStr := range timeRangesStr {
after, err := daySecsFromStr(timeRangeStr.After)
if err != nil {
return timeRanges, err
}
before, err := daySecsFromStr(timeRangeStr.Before)
if err != nil {
return timeRanges, err
}
if after == before {
after, before = -1, 86402
}
timeRanges = append(timeRanges, TimeRange{after: after, before: before})
}
return timeRanges, nil
}
func parseWeeklyRanges(weeklyRangesStr WeeklyRangesStr) (WeeklyRanges, error) {
weeklyRanges := WeeklyRanges{}
weeklyRangesStrX := [7][]TimeRangeStr{weeklyRangesStr.Sun, weeklyRangesStr.Mon, weeklyRangesStr.Tue, weeklyRangesStr.Wed, weeklyRangesStr.Thu, weeklyRangesStr.Fri, weeklyRangesStr.Sat}
for day, weeklyRangeStrX := range weeklyRangesStrX {
timeRanges, err := parseTimeRanges(weeklyRangeStrX)
if err != nil {
return weeklyRanges, err
}
weeklyRanges.ranges[day] = timeRanges
}
return weeklyRanges, nil
}
func ParseAllWeeklyRanges(allWeeklyRangesStr map[string]WeeklyRangesStr) (*map[string]WeeklyRanges, error) {
allWeeklyRanges := make(map[string]WeeklyRanges)
for weeklyRangesName, weeklyRangesStr := range allWeeklyRangesStr {
weeklyRanges, err := parseWeeklyRanges(weeklyRangesStr)
if err != nil {
return nil, err
}
allWeeklyRanges[weeklyRangesName] = weeklyRanges
}
return &allWeeklyRanges, nil
}
func (weeklyRanges *WeeklyRanges) Match() bool {
now := time.Now().Local()
day := now.Weekday()
weeklyRange := weeklyRanges.ranges[day]
if len(weeklyRange) == 0 {
return false
}
hour, min, _ := now.Clock()
nowX := (hour*60 + min) * 60
for _, timeRange := range weeklyRange {
if timeRange.after > timeRange.before {
if nowX >= timeRange.after || nowX <= timeRange.before {
return true
}
} else if nowX >= timeRange.after && nowX <= timeRange.before {
return true
}
}
return false
}