fix: weekDayKeys formula breaks when Jan 4 falls on Sunday
The naive formula used (jan4.Weekday() - time.Monday) produces -1 when Jan 4 is a Sunday (Weekday()==0), shifting the computed Monday one week forward. 2026 is affected: Jan 4 is a Sunday, so every week key in 2026 was mapped to the wrong 7-day range, causing CloseWeek to look for closed_days on the wrong dates and finding nothing — resulting in worked_ms=0 and a full -Nh delta. Fix: use (weekday+6)%7 to get days-since-Monday (Mon=0…Sun=6), which is always non-negative. Adds table-driven TestWeekDayKeys covering 2024 (Thu), 2026 (Sun), and 2023 (Wed) to prevent regression.
This commit is contained in:
@@ -65,8 +65,11 @@ func weekDayKeys(weekKey string, tz *time.Location) ([]string, error) {
|
|||||||
// Find the Monday of that ISO week.
|
// Find the Monday of that ISO week.
|
||||||
// Jan 4 is always in week 1 of its year.
|
// Jan 4 is always in week 1 of its year.
|
||||||
jan4 := time.Date(year, time.January, 4, 0, 0, 0, 0, tz)
|
jan4 := time.Date(year, time.January, 4, 0, 0, 0, 0, tz)
|
||||||
|
// (weekday+6)%7 gives days-since-Monday (Mon=0 … Sun=6), avoiding the
|
||||||
|
// sign issue when Weekday()==0 (Sunday) with the naive subtraction.
|
||||||
|
daysSinceMonday := int(jan4.Weekday()+6) % 7
|
||||||
_, jan4Week := jan4.ISOWeek()
|
_, jan4Week := jan4.ISOWeek()
|
||||||
monday := jan4.AddDate(0, 0, -int(jan4.Weekday()-time.Monday)+(week-jan4Week)*7)
|
monday := jan4.AddDate(0, 0, -daysSinceMonday+(week-jan4Week)*7)
|
||||||
|
|
||||||
keys := make([]string, 7)
|
keys := make([]string, 7)
|
||||||
for i := 0; i < 7; i++ {
|
for i := 0; i < 7; i++ {
|
||||||
|
|||||||
@@ -34,18 +34,30 @@ func newFullServices(t *testing.T) (*service.EntryService, *service.DayService,
|
|||||||
|
|
||||||
func TestWeekDayKeys(t *testing.T) {
|
func TestWeekDayKeys(t *testing.T) {
|
||||||
tz, _ := time.LoadLocation("UTC")
|
tz, _ := time.LoadLocation("UTC")
|
||||||
keys, err := service.WeekDayKeysExported("2024-W03", tz)
|
|
||||||
if err != nil {
|
cases := []struct {
|
||||||
t.Fatal(err)
|
weekKey string
|
||||||
|
wantMon string
|
||||||
|
wantSun string
|
||||||
|
}{
|
||||||
|
{"2024-W03", "2024-01-15", "2024-01-21"}, // Jan 4 = Thursday
|
||||||
|
{"2026-W18", "2026-04-27", "2026-05-03"}, // Jan 4 = Sunday — was broken
|
||||||
|
{"2023-W01", "2023-01-02", "2023-01-08"}, // Jan 4 = Wednesday
|
||||||
}
|
}
|
||||||
if len(keys) != 7 {
|
for _, tc := range cases {
|
||||||
t.Fatalf("expected 7 keys, got %d", len(keys))
|
keys, err := service.WeekDayKeysExported(tc.weekKey, tz)
|
||||||
}
|
if err != nil {
|
||||||
if keys[0] != "2024-01-15" {
|
t.Fatalf("%s: %v", tc.weekKey, err)
|
||||||
t.Errorf("expected Monday 2024-01-15, got %s", keys[0])
|
}
|
||||||
}
|
if len(keys) != 7 {
|
||||||
if keys[6] != "2024-01-21" {
|
t.Fatalf("%s: expected 7 keys, got %d", tc.weekKey, len(keys))
|
||||||
t.Errorf("expected Sunday 2024-01-21, got %s", keys[6])
|
}
|
||||||
|
if keys[0] != tc.wantMon {
|
||||||
|
t.Errorf("%s: Monday want %s, got %s", tc.weekKey, tc.wantMon, keys[0])
|
||||||
|
}
|
||||||
|
if keys[6] != tc.wantSun {
|
||||||
|
t.Errorf("%s: Sunday want %s, got %s", tc.weekKey, tc.wantSun, keys[6])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user