Skip to content

Commit 5300644

Browse files
committed
Merge branch 'pr/glaslos/6'
# Conflicts: # openhours_test.go
2 parents ef12c91 + f1c3600 commit 5300644

2 files changed

Lines changed: 54 additions & 15 deletions

File tree

openhours.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ func (o OpenHours) Match(t time.Time) bool {
3434
return i%2 == 1
3535
}
3636

37+
// matchIndex returns the index of the next open hour
3738
func (o OpenHours) matchIndex(t time.Time) int {
3839
i := 0
3940
for ; i < len(o); i++ {
@@ -47,17 +48,17 @@ func (o OpenHours) matchIndex(t time.Time) int {
4748
// NextDur returns true if t is in the open hours and the duration until it closes
4849
// else it returns false if t is in the closed hours and the duration until it opens
4950
func (o OpenHours) NextDur(t time.Time) (bool, time.Duration) {
50-
x := newDateFromTime(t)
51-
i := o.matchIndex(x)
52-
b := i%2 == 1
53-
if i == len(o) {
51+
current := newDateFromTime(t)
52+
i := o.matchIndex(current)
53+
isOpen := i%2 == 1 // uneven -> next time is a closing time
54+
if i == len(o) { // end of week, wrap around
5455
i = 0
5556
}
56-
oi := o[i]
57-
if x.After(oi) {
58-
oi = oi.AddDate(0, 0, 7)
57+
next := o[i]
58+
if current.After(next) { // we wrapped, set days to end of week
59+
next = next.AddDate(0, 0, 7)
5960
}
60-
return b, tzDiff(oi, x, t)
61+
return isOpen, tzDiff(next, current, t)
6162
}
6263

6364
// tzDiff calculate diff between a and b and add it to t, taking in account eventual tz changes
@@ -184,6 +185,9 @@ func simplifyTime(str string) (int, int, int) {
184185
if len(strs) == 3 {
185186
sec, _ = strconv.Atoi(strs[2])
186187
}
188+
if hour > 24 {
189+
hour = hour % 24
190+
}
187191
if hour > 24 || hour < 0 || min > 59 || min < 0 || sec > 59 || sec < 0 || (hour == 24 && min > 0 || hour == 24 && sec > 0) {
188192
return 0, 0, 0
189193
}
@@ -215,7 +219,11 @@ func new(str string, loc *time.Location) (OpenHours, error) {
215219
hourFrom, minFrom, secFrom := simplifyTime(times[0])
216220
hourTo, minTo, secTo := simplifyTime(times[1])
217221
for _, day := range days {
218-
o = append(o, newDate(day, hourFrom, minFrom, secFrom, 0, loc), newDate(day, hourTo, minTo, secTo, 0, loc))
222+
fromDate := newDate(day, hourFrom, minFrom, secFrom, 0, loc)
223+
if hourFrom > hourTo { // closing after midnight
224+
day++
225+
}
226+
o = append(o, fromDate, newDate(day, hourTo, minTo, secTo, 0, loc))
219227
}
220228
}
221229
}

openhours_test.go

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,20 @@ func Test_simplifyHour(t *testing.T) {
8585
{"00:-10", 0, 0, 0},
8686
{"24:01", 0, 0, 0},
8787
{"-50:99", 0, 0, 0},
88-
{"33:33:33", 0, 0, 0},
88+
{"33:33:33", 9, 33, 33}, // allow for 25:00:00 to be 1:00:00
89+
{"33:61:33", 0, 0, 0},
8990
}
9091
for _, tt := range tests {
9192
t.Run(tt.args, func(t *testing.T) {
9293
got, got1, got2 := simplifyTime(tt.args)
9394
if got != tt.want {
94-
t.Errorf("simplifyHour() got = %v, want %v", got, tt.want)
95+
t.Errorf("simplifyHour(%s) got = %v, want %v", tt.args, got, tt.want)
9596
}
9697
if got1 != tt.want1 {
97-
t.Errorf("simplifyHour() got1 = %v, want %v", got1, tt.want1)
98+
t.Errorf("simplifyHour(%s) got1 = %v, want %v", tt.args, got1, tt.want1)
9899
}
99100
if got2 != tt.want2 {
100-
t.Errorf("simplifyHour() got2 = %v, want %v", got2, tt.want2)
101+
t.Errorf("simplifyHour(%s) got2 = %v, want %v", tt.args, got2, tt.want2)
101102
}
102103
})
103104
}
@@ -225,8 +226,8 @@ func TestNew(t *testing.T) {
225226
{"empty ;", ";", l, []time.Time{newDate(0, 0, 0, 0, 0, l), newDate(7, 0, 0, 0, 0, l)}},
226227
{"all day ;", "su-sa 00:00-24:00;", l, []time.Time{newDate(0, 0, 0, 0, 0, l), newDate(7, 0, 0, 0, 0, l)}},
227228
{"empty and no tz", "", nil, []time.Time{newDate(0, 0, 0, 0, 0, time.UTC), newDate(7, 0, 0, 0, 0, time.UTC)}},
228-
{"order on same sentense", "mo,tu 10:00-11:00", nil, NewMust("tu,mo 10:00-11:00", nil)},
229-
{"order on different sentenses", "mo 10:00-11:00;tu 10:00-12:00", nil, NewMust("tu 10:00-12:00;mo 10:00-11:00", nil)},
229+
{"order on same sentence", "mo,tu 10:00-11:00", nil, NewMust("tu,mo 10:00-11:00", nil)},
230+
{"order on different sentences", "mo 10:00-11:00;tu 10:00-12:00", nil, NewMust("tu 10:00-12:00;mo 10:00-11:00", nil)},
230231
{"complex = simple", "su-sa 00:00-12:00,12:00-24:00", l, NewMust("", l)},
231232
{"complex = simple", "su-sa 00:00-12:00;su-sa 12:00-24:00", l, NewMust("", l)},
232233
{"time windows order does not matter anymore", "mo-su 00:00-24:00", l, NewMust("", l)},
@@ -387,3 +388,33 @@ func TestOpenHours_String(t *testing.T) {
387388
})
388389
}
389390
}
391+
392+
func TestOpenHours_ClosingAfterMidnight(t *testing.T) {
393+
o1 := NewMust("mo 22:00-02:00", l)
394+
o2 := NewMust("mo 22:00-26:00", l)
395+
tests := []struct {
396+
o OpenHours
397+
name string
398+
now time.Time
399+
want bool
400+
}{
401+
{o1, "before", time.Date(2019, 3, 4, 21, 0, 0, 0, l), false},
402+
{o1, "start", time.Date(2019, 3, 4, 22, 0, 0, 0, l), true},
403+
{o1, "between", time.Date(2019, 3, 4, 23, 0, 0, 0, l), true},
404+
{o1, "end", time.Date(2019, 3, 5, 2, 0, 0, 0, l), false},
405+
{o1, "after", time.Date(2019, 3, 5, 3, 0, 0, 0, l), false},
406+
// using the 26:00 = 02:00 next day notation
407+
{o2, "before", time.Date(2019, 3, 4, 21, 0, 0, 0, l), false},
408+
{o2, "start", time.Date(2019, 3, 4, 22, 0, 0, 0, l), true},
409+
{o2, "between", time.Date(2019, 3, 4, 23, 0, 0, 0, l), true},
410+
{o2, "end", time.Date(2019, 3, 5, 2, 0, 0, 0, l), false},
411+
{o2, "after", time.Date(2019, 3, 5, 3, 0, 0, 0, l), false},
412+
}
413+
for _, tt := range tests {
414+
t.Run(tt.name, func(t *testing.T) {
415+
if got, got1 := tt.o.NextDur(tt.now); got != tt.want {
416+
t.Errorf("OpenHours.NextDur().Open = %v, want %v, duration: %v", got, tt.want, got1)
417+
}
418+
})
419+
}
420+
}

0 commit comments

Comments
 (0)