From a3522334989c6a7879ef3df194654527b1d9f9a7 Mon Sep 17 00:00:00 2001 From: Nicolas Hillegeer Date: Wed, 9 Oct 2024 18:50:04 +0200 Subject: [PATCH] tui: use RFC3339-alike format with second precision for "Time" (#903) The current time format (Jan 2, 2006 at 3:04pm (MST)) has a few issues: - It displays time at minute granularity, while profiles usually have have second-level (and more[^go]) granularity. - It uses a 12-hour clock, which is tricky to handle at AM/PM switchovers, for people (like myself) who are not used to it. By contrast, a 24-hour clock is unambiguous. - Minor: using names for months makes it more difficult to calculate with time differences. Hence, I propose replacing it with an RFC3339-alike format, with spaces between elements for better readability. [^go]: https://github.com/golang/go/blob/3aa71c12eacd68ec16e7172d92aa5c6af32f0c3b/src/runtime/pprof/proto.go#L351 --- internal/report/report.go | 2 +- internal/report/report_test.go | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/internal/report/report.go b/internal/report/report.go index 5ab0da65..8e73f179 100644 --- a/internal/report/report.go +++ b/internal/report/report.go @@ -1173,7 +1173,7 @@ func ProfileLabels(rpt *Report) []string { label = append(label, "Doc: "+url) } if prof.TimeNanos != 0 { - const layout = "Jan 2, 2006 at 3:04pm (MST)" + const layout = "2006-01-02 15:04:05 MST" label = append(label, "Time: "+time.Unix(0, prof.TimeNanos).Format(layout)) } if prof.DurationNanos != 0 { diff --git a/internal/report/report_test.go b/internal/report/report_test.go index 845c3690..bbb89a7f 100644 --- a/internal/report/report_test.go +++ b/internal/report/report_test.go @@ -21,8 +21,10 @@ import ( "path/filepath" "regexp" "runtime" + "slices" "strings" "testing" + "time" "github.com/google/pprof/internal/binutils" "github.com/google/pprof/internal/graph" @@ -595,3 +597,21 @@ func TestDocURLInLabels(t *testing.T) { t.Errorf("expected URL %q not found in %s", url, labels) } } + +func TestProfileLabels(t *testing.T) { + // Force the local timezone to UTC for the duration of this function to get a + // predictable result out of timezone printing. + defer func(prev *time.Location) { time.Local = prev }(time.Local) + time.Local = time.UTC + + profile := testProfile.Copy() + profile.TimeNanos = time.Unix(131, 0).UnixNano() + rpt := New(profile, &Options{ + SampleValue: func(v []int64) int64 { return v[1] }, + }) + + const want = "Time: 1970-01-01 00:02:11 UTC" + if labels := ProfileLabels(rpt); !slices.Contains(labels, want) { + t.Errorf("wanted to find a label containing %q, but found none in %v", want, labels) + } +}