105 lines
3.0 KiB
Go
105 lines
3.0 KiB
Go
package timeutil
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestPeriodOverlapUsesHalfOpenIntervals(t *testing.T) {
|
|
start := time.Date(2026, 5, 29, 6, 0, 0, 0, time.UTC)
|
|
left := Period{Start: start, End: start.Add(time.Hour)}
|
|
touching := Period{Start: start.Add(time.Hour), End: start.Add(2 * time.Hour)}
|
|
overlapping := Period{Start: start.Add(30 * time.Minute), End: start.Add(90 * time.Minute)}
|
|
|
|
if left.Overlaps(touching) {
|
|
t.Fatal("touching half-open periods overlap, want false")
|
|
}
|
|
if !left.Overlaps(overlapping) {
|
|
t.Fatal("overlapping periods do not overlap, want true")
|
|
}
|
|
}
|
|
|
|
func TestClockWindowHandlesOvernight(t *testing.T) {
|
|
location := time.FixedZone("Test", -5*60*60)
|
|
date := time.Date(2026, 5, 29, 12, 0, 0, 0, location)
|
|
start, _ := ParseClock("22:00")
|
|
end, _ := ParseClock("06:00")
|
|
|
|
window := ClockWindow(date, location, start, end)
|
|
if got := window.Start.Format("2006-01-02T15:04"); got != "2026-05-29T22:00" {
|
|
t.Fatalf("Start = %s, want 2026-05-29T22:00", got)
|
|
}
|
|
if got := window.End.Format("2006-01-02T15:04"); got != "2026-05-30T06:00" {
|
|
t.Fatalf("End = %s, want 2026-05-30T06:00", got)
|
|
}
|
|
}
|
|
|
|
func TestClockWindowUsesCivilTimeAcrossDSTTransitions(t *testing.T) {
|
|
location, err := LoadLocation("America/Chicago")
|
|
if err != nil {
|
|
t.Fatalf("LoadLocation() error = %v", err)
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
date time.Time
|
|
start string
|
|
end string
|
|
wantStart string
|
|
wantEnd string
|
|
}{
|
|
{
|
|
name: "spring-forward daytime",
|
|
date: time.Date(2026, time.March, 8, 12, 0, 0, 0, location),
|
|
start: "00:00",
|
|
end: "06:00",
|
|
wantStart: "2026-03-08T00:00:00-06:00",
|
|
wantEnd: "2026-03-08T06:00:00-05:00",
|
|
},
|
|
{
|
|
name: "fall-back daytime",
|
|
date: time.Date(2026, time.November, 1, 12, 0, 0, 0, location),
|
|
start: "00:00",
|
|
end: "06:00",
|
|
wantStart: "2026-11-01T00:00:00-05:00",
|
|
wantEnd: "2026-11-01T06:00:00-06:00",
|
|
},
|
|
{
|
|
name: "spring-forward overnight",
|
|
date: time.Date(2026, time.March, 8, 12, 0, 0, 0, location),
|
|
start: "22:00",
|
|
end: "06:00",
|
|
wantStart: "2026-03-08T22:00:00-05:00",
|
|
wantEnd: "2026-03-09T06:00:00-05:00",
|
|
},
|
|
{
|
|
name: "spring-forward end of day",
|
|
date: time.Date(2026, time.March, 8, 12, 0, 0, 0, location),
|
|
start: "18:00",
|
|
end: "24:00",
|
|
wantStart: "2026-03-08T18:00:00-05:00",
|
|
wantEnd: "2026-03-09T00:00:00-05:00",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
start, err := ParseClock(tt.start)
|
|
if err != nil {
|
|
t.Fatalf("ParseClock(%q) error = %v", tt.start, err)
|
|
}
|
|
end, err := ParseClock(tt.end)
|
|
if err != nil {
|
|
t.Fatalf("ParseClock(%q) error = %v", tt.end, err)
|
|
}
|
|
|
|
window := ClockWindow(tt.date, location, start, end)
|
|
if got := window.Start.Format(time.RFC3339); got != tt.wantStart {
|
|
t.Fatalf("Start = %s, want %s", got, tt.wantStart)
|
|
}
|
|
if got := window.End.Format(time.RFC3339); got != tt.wantEnd {
|
|
t.Fatalf("End = %s, want %s", got, tt.wantEnd)
|
|
}
|
|
})
|
|
}
|
|
}
|