From 5f7c584bb3259cf8ef667864a46569f89229c922 Mon Sep 17 00:00:00 2001 From: Ahmet Alp Balkan Date: Tue, 12 May 2015 19:59:34 +0000 Subject: [PATCH] Allow duration strings as --since/--until MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #13107. This change enables Go duration strings computed relative to the client machine’s time to be used as input parameters to `docker events --since/--until` and `docker logs --since` arguments. Added unit tests for pkg/timeutils.GetTimestamp as well. Signed-off-by: Ahmet Alp Balkan --- timeutils/utils.go | 15 +++++++++++---- timeutils/utils_test.go | 10 +++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/timeutils/utils.go b/timeutils/utils.go index 6af16a1..8437f12 100644 --- a/timeutils/utils.go +++ b/timeutils/utils.go @@ -6,10 +6,17 @@ import ( "time" ) -// GetTimestamp tries to parse given string as RFC3339 time -// or Unix timestamp (with seconds precision), if successful -//returns a Unix timestamp as string otherwise returns value back. -func GetTimestamp(value string) string { +// GetTimestamp tries to parse given string as golang duration, +// then RFC3339 time and finally as a Unix timestamp. If +// any of these were successful, it returns a Unix timestamp +// as string otherwise returns the given value back. +// In case of duration input, the returned timestamp is computed +// as the given reference time minus the amount of the duration. +func GetTimestamp(value string, reference time.Time) string { + if d, err := time.ParseDuration(value); value != "0" && err == nil { + return strconv.FormatInt(reference.Add(-d).Unix(), 10) + } + var format string if strings.Contains(value, ".") { format = time.RFC3339Nano diff --git a/timeutils/utils_test.go b/timeutils/utils_test.go index 1d724fb..f71dcb5 100644 --- a/timeutils/utils_test.go +++ b/timeutils/utils_test.go @@ -1,10 +1,13 @@ package timeutils import ( + "fmt" "testing" + "time" ) func TestGetTimestamp(t *testing.T) { + now := time.Now() cases := []struct{ in, expected string }{ {"0", "-62167305600"}, // 0 gets parsed year 0 @@ -23,12 +26,17 @@ func TestGetTimestamp(t *testing.T) { // unix timestamps returned as is {"1136073600", "1136073600"}, + // Durations + {"1m", fmt.Sprintf("%d", now.Add(-1*time.Minute).Unix())}, + {"1.5h", fmt.Sprintf("%d", now.Add(-90*time.Minute).Unix())}, + {"1h30m", fmt.Sprintf("%d", now.Add(-90*time.Minute).Unix())}, + // String fallback {"invalid", "invalid"}, } for _, c := range cases { - o := GetTimestamp(c.in) + o := GetTimestamp(c.in, now) if o != c.expected { t.Fatalf("wrong value for '%s'. expected:'%s' got:'%s'", c.in, c.expected, o) }