From 1c47acda11ad26a379c6aba0004e661bf1787f14 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Sat, 13 May 2023 20:12:06 -0700 Subject: [PATCH] lib/promutils: add ParseTimeAt() function --- lib/promutils/time.go | 15 ++++++-- lib/promutils/time_test.go | 75 +++++++++++++++++++------------------- 2 files changed, 49 insertions(+), 41 deletions(-) diff --git a/lib/promutils/time.go b/lib/promutils/time.go index 432c2dbc0..986790f43 100644 --- a/lib/promutils/time.go +++ b/lib/promutils/time.go @@ -13,8 +13,18 @@ import ( // // It returns unix timestamp in seconds. func ParseTime(s string) (float64, error) { + currentTimestamp := float64(time.Now().UnixNano()) / 1e9 + return ParseTimeAt(s, currentTimestamp) +} + +// ParseTimeAt parses time s in different formats, assuming the given currentTimestamp. +// +// See https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#timestamp-formats +// +// It returns unix timestamp in seconds. +func ParseTimeAt(s string, currentTimestamp float64) (float64, error) { if s == "now" { - return float64(time.Now().UnixNano()) / 1e9, nil + return currentTimestamp, nil } sOrig := s tzOffset := float64(0) @@ -49,8 +59,7 @@ func ParseTime(s string) (float64, error) { if d > 0 { d = -d } - t := time.Now().Add(d) - return float64(t.UnixNano()) / 1e9, nil + return currentTimestamp + float64(d)/1e9, nil } if len(s) == 4 { // Parse YYYY diff --git a/lib/promutils/time_test.go b/lib/promutils/time_test.go index 740805227..fec51f6ac 100644 --- a/lib/promutils/time_test.go +++ b/lib/promutils/time_test.go @@ -1,19 +1,18 @@ package promutils import ( - "math" "testing" "time" ) -func TestParseTimeSuccess(t *testing.T) { - f := func(s string, resultExpected float64) { +func TestParseTimeAtSuccess(t *testing.T) { + f := func(s string, currentTime, resultExpected float64) { t.Helper() - result, err := ParseTime(s) + result, err := ParseTimeAt(s, currentTime) if err != nil { t.Fatalf("unexpected error: %s", err) } - if math.Abs(result-resultExpected) > 10 { + if result != resultExpected { t.Fatalf("unexpected result; got %v; want %v", result, resultExpected) } } @@ -21,55 +20,55 @@ func TestParseTimeSuccess(t *testing.T) { now := float64(time.Now().UnixNano()) / 1e9 // duration relative to the current time - f("now", now) - f("1h5s", now-3605) + f("now", now, now) + f("1h5s", now, now-3605) // negative duration relative to the current time - f("-5m", now-5*60) - f("-123", now-123) - f("-123.456", now-123.456) - f("now-1h5m", now-(3600+5*60)) + f("-5m", now, now-5*60) + f("-123", now, now-123) + f("-123.456", now, now-123.456) + f("now-1h5m", now, now-(3600+5*60)) // Year - f("2023", 1.6725312e+09) - f("2023Z", 1.6725312e+09) - f("2023+02:00", 1.672524e+09) - f("2023-02:00", 1.6725384e+09) + f("2023", now, 1.6725312e+09) + f("2023Z", now, 1.6725312e+09) + f("2023+02:00", now, 1.672524e+09) + f("2023-02:00", now, 1.6725384e+09) // Year and month - f("2023-05", 1.6828992e+09) - f("2023-05Z", 1.6828992e+09) - f("2023-05+02:00", 1.682892e+09) - f("2023-05-02:00", 1.6829064e+09) + f("2023-05", now, 1.6828992e+09) + f("2023-05Z", now, 1.6828992e+09) + f("2023-05+02:00", now, 1.682892e+09) + f("2023-05-02:00", now, 1.6829064e+09) // Year, month and day - f("2023-05-20", 1.6845408e+09) - f("2023-05-20Z", 1.6845408e+09) - f("2023-05-20+02:30", 1.6845318e+09) - f("2023-05-20-02:30", 1.6845498e+09) + f("2023-05-20", now, 1.6845408e+09) + f("2023-05-20Z", now, 1.6845408e+09) + f("2023-05-20+02:30", now, 1.6845318e+09) + f("2023-05-20-02:30", now, 1.6845498e+09) // Year, month, day and hour - f("2023-05-20T04", 1.6845552e+09) - f("2023-05-20T04Z", 1.6845552e+09) - f("2023-05-20T04+02:30", 1.6845462e+09) - f("2023-05-20T04-02:30", 1.6845642e+09) + f("2023-05-20T04", now, 1.6845552e+09) + f("2023-05-20T04Z", now, 1.6845552e+09) + f("2023-05-20T04+02:30", now, 1.6845462e+09) + f("2023-05-20T04-02:30", now, 1.6845642e+09) // Year, month, day, hour and minute - f("2023-05-20T04:57", 1.68455862e+09) - f("2023-05-20T04:57Z", 1.68455862e+09) - f("2023-05-20T04:57+02:30", 1.68454962e+09) - f("2023-05-20T04:57-02:30", 1.68456762e+09) + f("2023-05-20T04:57", now, 1.68455862e+09) + f("2023-05-20T04:57Z", now, 1.68455862e+09) + f("2023-05-20T04:57+02:30", now, 1.68454962e+09) + f("2023-05-20T04:57-02:30", now, 1.68456762e+09) // Year, month, day, hour, minute and second - f("2023-05-20T04:57:43", 1.684558663e+09) - f("2023-05-20T04:57:43Z", 1.684558663e+09) - f("2023-05-20T04:57:43+02:30", 1.684549663e+09) - f("2023-05-20T04:57:43-02:30", 1.684567663e+09) + f("2023-05-20T04:57:43", now, 1.684558663e+09) + f("2023-05-20T04:57:43Z", now, 1.684558663e+09) + f("2023-05-20T04:57:43+02:30", now, 1.684549663e+09) + f("2023-05-20T04:57:43-02:30", now, 1.684567663e+09) // milliseconds - f("2023-05-20T04:57:43.123Z", 1.6845586631230001e+09) - f("2023-05-20T04:57:43.123456789+02:30", 1.6845496631234567e+09) - f("2023-05-20T04:57:43.123456789-02:30", 1.6845676631234567e+09) + f("2023-05-20T04:57:43.123Z", now, 1.6845586631230001e+09) + f("2023-05-20T04:57:43.123456789+02:30", now, 1.6845496631234567e+09) + f("2023-05-20T04:57:43.123456789-02:30", now, 1.6845676631234567e+09) } func TestParseTimeFailure(t *testing.T) {