diff --git a/internal/time_range.go b/internal/time_range.go index e52bf55bb..683a42f62 100644 --- a/internal/time_range.go +++ b/internal/time_range.go @@ -78,15 +78,12 @@ func NewWeekRangeInLocation(startTime, endTime TimeOfDay, startDay, endDay time. return r, nil } -func (r *TimeRange) isInTimeRange(t time.Time) bool { - t = t.In(r.loc) - ts := NewTimeOfDay(t.Clock()).d - +func (r *TimeRange) isInWeekdays(day time.Weekday) bool { if len(r.weekdays) > 0 { found := false for _, weekday := range r.weekdays { - if t.Weekday() == weekday { + if day == weekday { found = true break } @@ -97,11 +94,34 @@ func (r *TimeRange) isInTimeRange(t time.Time) bool { } } + return true +} + +func (r *TimeRange) addWeekdayOffset(day time.Weekday, offset int) time.Weekday { + return (day + time.Weekday(offset)) % 7 +} + +func (r *TimeRange) isInTimeRange(t time.Time) bool { + t = t.In(r.loc) + ts := NewTimeOfDay(t.Clock()).d + if r.startTime.d < r.endTime.d { - return r.startTime.d <= ts && ts <= r.endTime.d + if r.isInWeekdays(t.Weekday()) { + return r.startTime.d <= ts && ts <= r.endTime.d + } + + return false + } + + if ts <= r.endTime.d { + return r.isInWeekdays(r.addWeekdayOffset(t.Weekday(), -1)) + } + + if ts >= r.startTime.d { + return r.isInWeekdays(t.Weekday()) } - return !(r.endTime.d < ts && ts < r.startTime.d) + return false } func (r *TimeRange) isInWeekRange(t time.Time) bool { diff --git a/internal/time_range_test.go b/internal/time_range_test.go index 55740b113..c9d6a494f 100644 --- a/internal/time_range_test.go +++ b/internal/time_range_test.go @@ -245,6 +245,33 @@ func TestTimeRangeIsInRange(t *testing.T) { now: time.Date(2016, time.August, 10, 2, 0, 0, 0, time.UTC), expectedInRange: false, }, + { + label: "18:59:00 Sunday, crossing midnight", + start: NewTimeOfDay(19, 0, 0), + end: NewTimeOfDay(6, 0, 0), + weekdays: []time.Weekday{time.Sunday}, + location: time.UTC, + now: time.Date(2006, time.December, 3, 18, 59, 0, 0, time.UTC), + expectedInRange: false, + }, + { + label: "5:59AM Monday, crossing midnight", + start: NewTimeOfDay(19, 0, 0), + end: NewTimeOfDay(6, 0, 0), + weekdays: []time.Weekday{time.Sunday}, + location: time.UTC, + now: time.Date(2006, time.December, 4, 5, 59, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "6:01AM Monday, crossing midnight", + start: NewTimeOfDay(19, 0, 0), + end: NewTimeOfDay(6, 0, 0), + weekdays: []time.Weekday{time.Sunday}, + location: time.UTC, + now: time.Date(2006, time.December, 4, 6, 1, 0, 0, time.UTC), + expectedInRange: false, + }, } for _, tc := range testcases {