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 {
|
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)
|
dayEnd := localDate.AddDate(0, 0, 1)
|
||||||
|
|
||||||
weekday := int(localDate.Weekday())
|
weekday := int(localDate.Weekday())
|
||||||
@ -59,8 +59,8 @@ func SamePeriod(left time.Time, right time.Time, window PeriodWindow, statZone *
|
|||||||
if window.Type == PeriodAll {
|
if window.Type == PeriodAll {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
leftLocal := left.In(statZone)
|
leftLocal := wallClockInLocation(left, statZone)
|
||||||
rightLocal := right.In(statZone)
|
rightLocal := wallClockInLocation(right, statZone)
|
||||||
switch window.Type {
|
switch window.Type {
|
||||||
case PeriodDay:
|
case PeriodDay:
|
||||||
return startOfDay(leftLocal).Equal(startOfDay(rightLocal))
|
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 {
|
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 {
|
func DateNumber(day time.Time) int {
|
||||||
@ -93,3 +93,15 @@ func startOfDay(value time.Time) time.Time {
|
|||||||
year, month, date := value.Date()
|
year, month, date := value.Date()
|
||||||
return time.Date(year, month, date, 0, 0, 0, 0, value.Location())
|
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