From bbceab0b24fc06300da059a9bca4fe7efac50dd1 Mon Sep 17 00:00:00 2001 From: sneak Date: Fri, 6 Nov 2026 19:12:41 -0800 Subject: [PATCH] Show UTC as the first header clock instead of hardcoded Los Angeles time The header drew the host's local time and then America/Los_Angeles time, so on a Mac in that zone both clocks read the same and neither was UTC. The first clock is now UTC and the second the host's local time, which also drops the hardcoded zone and its load-failure path. --- internal/monitor/export_test.go | 4 ++++ internal/monitor/ui.go | 21 +++++++++++---------- internal/monitor/ui_test.go | 27 +++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 internal/monitor/ui_test.go diff --git a/internal/monitor/export_test.go b/internal/monitor/export_test.go index f330e5a..4bf82c1 100644 --- a/internal/monitor/export_test.go +++ b/internal/monitor/export_test.go @@ -2,6 +2,7 @@ package monitor import ( "context" + "time" "git.eeqj.de/sneak/rtnetmon/internal/starlink" ) @@ -59,6 +60,9 @@ func (m *Monitor) TCPHosts() []string { return m.tcpHosts } // Interfaces returns the monitored interfaces. func (m *Monitor) Interfaces() []*InterfaceStatus { return m.interfaces } +// ClockStrings exposes clockStrings for external tests. +func ClockStrings(now time.Time) (string, string) { return clockStrings(now) } + // PingArgs exposes pingArgs for external tests. func PingArgs(goos, iface, host string) []string { return pingArgs(goos, iface, host) } diff --git a/internal/monitor/ui.go b/internal/monitor/ui.go index 185fcbe..9044498 100644 --- a/internal/monitor/ui.go +++ b/internal/monitor/ui.go @@ -337,6 +337,15 @@ func drawICMPStats(scr tcell.Screen, y int, st *InterfaceStatus) int { } // uiLoop runs the UI event loop. +// clockFormat is the layout of both header clocks. +const clockFormat = time.RFC1123Z + +// clockStrings renders the header clocks: UTC first, then the host's local +// time in whatever location now carries. +func clockStrings(now time.Time) (string, string) { + return now.UTC().Format(clockFormat), now.Format(clockFormat) +} + func (m *Monitor) uiLoop(ctx context.Context) { m.logf("UI loop started") @@ -348,13 +357,6 @@ func (m *Monitor) uiLoop(ctx context.Context) { m.logf("Screen finalized") }() - pstLoc, err := time.LoadLocation("America/Los_Angeles") - if err != nil { - m.logf("Error loading PST location: %v", err) - - pstLoc = time.UTC - } - timestampSpinFrame := 0 lastTimestampSpinUpdate := time.Now() @@ -365,8 +367,7 @@ func (m *Monitor) uiLoop(ctx context.Context) { Put(m.screen, colLeft, rowTopRule, HLine(w), tcell.StyleDefault) now := time.Now() - timeStr := now.Format(time.RFC1123Z) - pstTimeStr := now.In(pstLoc).Format(time.RFC1123Z) + timeStr, localTimeStr := clockStrings(now) if time.Since(lastTimestampSpinUpdate) >= time.Second { timestampSpinFrame = (timestampSpinFrame + 1) % len(brailleSpins()) @@ -380,7 +381,7 @@ func (m *Monitor) uiLoop(ctx context.Context) { Put(m.screen, colSpinner, rowClock, string(brailleChar)+" ", tcell.StyleDefault) DrawRainbowText(m.screen, colMeter, rowClock, timeStr, colors) DrawRainbowText(m.screen, colMeter+len(timeStr)+clockGap, rowClock, - pstTimeStr, colors) + localTimeStr, colors) Put(m.screen, colLeft, rowBottomRule, HLine(w), tcell.StyleDefault) runtime := time.Since(m.startTime).Round(time.Second).String() diff --git a/internal/monitor/ui_test.go b/internal/monitor/ui_test.go new file mode 100644 index 0000000..5a072be --- /dev/null +++ b/internal/monitor/ui_test.go @@ -0,0 +1,27 @@ +package monitor_test + +import ( + "testing" + "time" + + "git.eeqj.de/sneak/rtnetmon/internal/monitor" +) + +// TestClockStrings checks that the header shows UTC first and the host's +// local time second, so the two differ whenever the host is not on UTC. +func TestClockStrings(t *testing.T) { + t.Parallel() + + berlin := time.FixedZone("CET", 3600) + now := time.Date(2026, time.November, 6, 20, 30, 0, 0, berlin) + + utc, local := monitor.ClockStrings(now) + + if want := "Fri, 06 Nov 2026 19:30:00 +0000"; utc != want { + t.Errorf("utc = %q, want %q", utc, want) + } + + if want := "Fri, 06 Nov 2026 20:30:00 +0100"; local != want { + t.Errorf("local = %q, want %q", local, want) + } +}