Fix dashboard date bucketing
This commit is contained in:
parent
d7f507916f
commit
4877da1d74
@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func PeriodWindows(eventTime time.Time, statZone *time.Location) []PeriodWindow {
|
||||
localDate := startOfDay(eventTime.In(statZone))
|
||||
localDate := startOfDay(wallClockInLocation(eventTime, statZone))
|
||||
dayEnd := localDate.AddDate(0, 0, 1)
|
||||
|
||||
weekday := int(localDate.Weekday())
|
||||
@ -59,8 +59,8 @@ func SamePeriod(left time.Time, right time.Time, window PeriodWindow, statZone *
|
||||
if window.Type == PeriodAll {
|
||||
return true
|
||||
}
|
||||
leftLocal := left.In(statZone)
|
||||
rightLocal := right.In(statZone)
|
||||
leftLocal := wallClockInLocation(left, statZone)
|
||||
rightLocal := wallClockInLocation(right, statZone)
|
||||
switch window.Type {
|
||||
case PeriodDay:
|
||||
return startOfDay(leftLocal).Equal(startOfDay(rightLocal))
|
||||
@ -76,7 +76,7 @@ func SamePeriod(left time.Time, right time.Time, window PeriodWindow, statZone *
|
||||
}
|
||||
|
||||
func DailyDate(eventTime time.Time, storageZone *time.Location) time.Time {
|
||||
return startOfDay(eventTime.In(storageZone))
|
||||
return startOfDay(wallClockInLocation(eventTime, storageZone))
|
||||
}
|
||||
|
||||
func DateNumber(day time.Time) int {
|
||||
@ -93,3 +93,15 @@ func startOfDay(value time.Time) time.Time {
|
||||
year, month, date := value.Date()
|
||||
return time.Date(year, month, date, 0, 0, 0, 0, value.Location())
|
||||
}
|
||||
|
||||
func wallClockInLocation(value time.Time, location *time.Location) time.Time {
|
||||
if value.IsZero() {
|
||||
return value
|
||||
}
|
||||
if location == nil {
|
||||
location = time.UTC
|
||||
}
|
||||
year, month, day := value.Date()
|
||||
hour, minute, second := value.Clock()
|
||||
return time.Date(year, month, day, hour, minute, second, value.Nanosecond(), location)
|
||||
}
|
||||
|
||||
50
internal/dashboard/period_test.go
Normal file
50
internal/dashboard/period_test.go
Normal file
@ -0,0 +1,50 @@
|
||||
package dashboard
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDailyDateKeepsDatabaseDatetimeCalendarDay(t *testing.T) {
|
||||
riyadh := mustLoadLocation(t, "Asia/Riyadh")
|
||||
eventTime := time.Date(2026, 5, 26, 1, 30, 0, 0, time.UTC)
|
||||
|
||||
got := DailyDate(eventTime, riyadh)
|
||||
|
||||
if got.Format("2006-01-02") != "2026-05-26" {
|
||||
t.Fatalf("DailyDate shifted database DATETIME calendar day: got %s", got.Format("2006-01-02"))
|
||||
}
|
||||
if got.Location() != riyadh {
|
||||
t.Fatalf("DailyDate location = %s, want %s", got.Location(), riyadh)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPeriodWindowsKeepsDatabaseDatetimeCalendarDay(t *testing.T) {
|
||||
riyadh := mustLoadLocation(t, "Asia/Riyadh")
|
||||
eventTime := time.Date(2026, 5, 26, 1, 30, 0, 0, time.UTC)
|
||||
|
||||
windows := PeriodWindows(eventTime, riyadh)
|
||||
|
||||
if windows[0].Type != PeriodDay || windows[0].Key != "2026-05-26" {
|
||||
t.Fatalf("day window = %+v, want key 2026-05-26", windows[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestSamePeriodKeepsDatabaseDatetimeCalendarDay(t *testing.T) {
|
||||
riyadh := mustLoadLocation(t, "Asia/Riyadh")
|
||||
left := time.Date(2026, 5, 26, 0, 10, 0, 0, time.UTC)
|
||||
right := time.Date(2026, 5, 26, 23, 50, 0, 0, time.UTC)
|
||||
|
||||
if !SamePeriod(left, right, PeriodWindow{Type: PeriodDay}, riyadh) {
|
||||
t.Fatal("SamePeriod shifted database DATETIME values out of the same calendar day")
|
||||
}
|
||||
}
|
||||
|
||||
func mustLoadLocation(t *testing.T, name string) *time.Location {
|
||||
t.Helper()
|
||||
location, err := time.LoadLocation(name)
|
||||
if err != nil {
|
||||
t.Fatalf("load location %s: %v", name, err)
|
||||
}
|
||||
return location
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user