diff --git a/backend/clock/clock.go b/backend/clock/clock.go new file mode 100644 index 0000000..d5b2da3 --- /dev/null +++ b/backend/clock/clock.go @@ -0,0 +1,10 @@ +package clock + +import "time" + +// Now returns the current UTC time, used everywhere for wall-clock consistency. +// All scheduling comparisons, timestamp recording, and duration calculations use +// this function so they're consistent with the database (TIMESTAMPTZ in UTC). +func Now() time.Time { + return time.Now().UTC() +} diff --git a/backend/clock/clock_test.go b/backend/clock/clock_test.go new file mode 100644 index 0000000..5e24542 --- /dev/null +++ b/backend/clock/clock_test.go @@ -0,0 +1,24 @@ +package clock + +import ( + "testing" + "time" +) + +func TestNow_ReturnsUTC(t *testing.T) { + t.Parallel() + now := Now() + if now.Location() != time.UTC { + t.Errorf("clock.Now() returned time in %v, expected UTC", now.Location()) + } +} + +func TestNow_IsReasonable(t *testing.T) { + t.Parallel() + now := Now() + // Check it's within the last minute (reasonable) + since := time.Since(now) + if since < 0 || since > time.Minute { + t.Errorf("clock.Now() returned unreasonable time: %v ago", since) + } +}