-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrange.go
130 lines (101 loc) · 2.48 KB
/
range.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
123
124
125
126
127
128
129
130
package datetime
import (
"errors"
"fmt"
"github.com/gouef/validator"
"github.com/gouef/validator/constraints"
"regexp"
"time"
)
type Range struct {
from Value
to Value
start RangeStart
end RangeEnd
}
func NewRange(from, to string, start RangeStart, end RangeEnd) (*Range, error) {
_, err := FromString(from)
if from != "" && err != nil {
return nil, err
}
_, err = FromString(to)
if to != "" && err != nil {
return nil, err
}
return &Range{
from: Value(from),
to: Value(to),
start: start,
end: end,
}, nil
}
func NewRangeOptional(from, to string) (*Range, error) {
return NewRange(from, to, RangeStartOptional, RangeEndOptional)
}
func NewRangeStrict(from, to string) (*Range, error) {
return NewRange(from, to, RangeStartStrict, RangeEndStrict)
}
func NewRangeStartStrict(from, to string) (*Range, error) {
return NewRange(from, to, RangeStartStrict, RangeEndOptional)
}
func NewRangeStartOptional(from, to string) (*Range, error) {
return NewRange(from, to, RangeStartOptional, RangeEndStrict)
}
func RangeFromString(value string) (*Range, error) {
errs := validator.Validate(value, constraints.RegularExpression{Regexp: RangeRegexp})
if len(errs) != 0 {
return nil, errors.New(fmt.Sprintf("unsupported format of datetime range \"%s\"", value))
}
re := regexp.MustCompile(RangeRegexp)
match := re.FindStringSubmatch(value)
start := match[1]
from := match[2]
to := match[12]
end := match[22]
return NewRange(from, to, RangeStart(start), RangeEnd(end))
}
func (r *Range) Start() RangeStart {
return r.start
}
func (r *Range) End() RangeEnd {
return r.end
}
func (r *Range) From() ValueInterface {
return r.from
}
func (r *Range) To() ValueInterface {
return r.to
}
func (r *Range) String() string {
return fmt.Sprintf("%s%s, %s%s", r.Start(), r.From(), r.To(), r.End())
}
func (r *Range) Is(value any) bool {
date, err := r.format(value)
if err != nil {
return false
}
from, _ := FromString(string(r.from))
to, _ := FromString(string(r.to))
if from == nil && to == nil {
return false
}
if from == nil {
return date.Before(to)
}
if to == nil {
return date.After(from)
}
return date.Between(from, to)
}
func (r *Range) format(date any) (Interface, error) {
switch i := date.(type) {
case time.Time:
return New(i.Year(), int(i.Month()), i.Day(), i.Hour(), i.Minute(), i.Second())
case *DateTime:
return i, nil
case string:
return FromString(i)
default:
return nil, errors.New("unsupported format of datetime")
}
}