From a14d95503d4cd5b54661d6c4713b8b51cbd7d2ec Mon Sep 17 00:00:00 2001 From: Dean Chen <862469039@qq.com> Date: Wed, 22 Jul 2026 15:40:47 +0500 Subject: [PATCH 1/2] model: add Duration unit constants and conversion methods Working with model.Duration is awkward for simple conversions and multiplications because callers must cast to/from time.Duration: int64(d)/int64(time.Millisecond) 15 * 24 * model.Duration(time.Hour) model.Duration(n * time.Millisecond) Add common unit constants (Nanosecond through Week) and conversion methods (Nanoseconds through Hours) mirroring the standard time package. Day and Week are included because ParseDuration already supports those units. Fixes #222 Signed-off-by: Dean Chen <862469039@qq.com> --- model/time.go | 41 +++++++++++++++++++++++++++++++++++++++++ model/time_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/model/time.go b/model/time.go index 0854753f..4d572b8a 100644 --- a/model/time.go +++ b/model/time.go @@ -164,6 +164,47 @@ func (t *Time) UnmarshalJSON(b []byte) error { // This type should not propagate beyond the scope of input/output processing. type Duration time.Duration +// Common durations. Day and Week are included because ParseDuration supports +// those units (unlike the standard time package). +// +// To count the number of units in a Duration, divide: +// +// second := model.Second +// fmt.Print(int64(second/model.Millisecond)) // prints 1000 +// +// To convert an integer number of units to a Duration, multiply: +// +// seconds := 10 +// fmt.Print(model.Duration(seconds)*model.Second) // prints 10s +const ( + Nanosecond Duration = 1 + Microsecond = 1000 * Nanosecond + Millisecond = 1000 * Microsecond + Second = 1000 * Millisecond + Minute = 60 * Second + Hour = 60 * Minute + Day = 24 * Hour + Week = 7 * Day +) + +// Nanoseconds returns the duration as an integer nanosecond count. +func (d Duration) Nanoseconds() int64 { return time.Duration(d).Nanoseconds() } + +// Microseconds returns the duration as an integer microsecond count. +func (d Duration) Microseconds() int64 { return time.Duration(d).Microseconds() } + +// Milliseconds returns the duration as an integer millisecond count. +func (d Duration) Milliseconds() int64 { return time.Duration(d).Milliseconds() } + +// Seconds returns the duration as a floating point number of seconds. +func (d Duration) Seconds() float64 { return time.Duration(d).Seconds() } + +// Minutes returns the duration as a floating point number of minutes. +func (d Duration) Minutes() float64 { return time.Duration(d).Minutes() } + +// Hours returns the duration as a floating point number of hours. +func (d Duration) Hours() float64 { return time.Duration(d).Hours() } + // Set implements pflag/flag.Value. func (d *Duration) Set(s string) error { var err error diff --git a/model/time_test.go b/model/time_test.go index 7633b46e..a7aae292 100644 --- a/model/time_test.go +++ b/model/time_test.go @@ -67,6 +67,41 @@ func TestDuration(t *testing.T) { require.Equalf(t, delta, duration, "Expected %s to be equal to %s", delta, duration) } +func TestDurationConstants(t *testing.T) { + require.Equal(t, Duration(time.Nanosecond), Nanosecond) + require.Equal(t, Duration(time.Microsecond), Microsecond) + require.Equal(t, Duration(time.Millisecond), Millisecond) + require.Equal(t, Duration(time.Second), Second) + require.Equal(t, Duration(time.Minute), Minute) + require.Equal(t, Duration(time.Hour), Hour) + require.Equal(t, Duration(24*time.Hour), Day) + require.Equal(t, Duration(7*24*time.Hour), Week) + + // Typical usage from the issue: multiply integers by model constants. + require.Equal(t, Duration(15*24*time.Hour), 15*Day) + require.Equal(t, Duration(5000*time.Millisecond), 5000*Millisecond) +} + +func TestDurationMethods(t *testing.T) { + d := 2*Hour + 30*Minute + 15*Second + 250*Millisecond + td := time.Duration(d) + + require.Equal(t, td.Nanoseconds(), d.Nanoseconds()) + require.Equal(t, td.Microseconds(), d.Microseconds()) + require.Equal(t, td.Milliseconds(), d.Milliseconds()) + require.Equal(t, td.Seconds(), d.Seconds()) + require.Equal(t, td.Minutes(), d.Minutes()) + require.Equal(t, td.Hours(), d.Hours()) + + require.Equal(t, int64(2*60*60*1000+30*60*1000+15*1000+250), d.Milliseconds()) + require.Equal(t, int64(1500), (1500 * Microsecond).Microseconds()) + require.Equal(t, int64(1500), (1500 * Nanosecond).Nanoseconds()) + + // Negative durations. + require.Equal(t, int64(-1500), (-1500 * Millisecond).Milliseconds()) + require.Equal(t, -1.5, (-1500 * Millisecond).Seconds()) +} + func TestParseDuration(t *testing.T) { type testCase struct { in string From 972fa163d601bb8fd307ce064ba03681487cb93d Mon Sep 17 00:00:00 2001 From: Dean Chen <862469039@qq.com> Date: Wed, 22 Jul 2026 17:52:25 +0500 Subject: [PATCH 2/2] test(model): fix testifylint expected/actual order for Duration constants Signed-off-by: Dean Chen <862469039@qq.com> --- model/time_test.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/model/time_test.go b/model/time_test.go index a7aae292..16445400 100644 --- a/model/time_test.go +++ b/model/time_test.go @@ -68,18 +68,19 @@ func TestDuration(t *testing.T) { } func TestDurationConstants(t *testing.T) { - require.Equal(t, Duration(time.Nanosecond), Nanosecond) - require.Equal(t, Duration(time.Microsecond), Microsecond) - require.Equal(t, Duration(time.Millisecond), Millisecond) - require.Equal(t, Duration(time.Second), Second) - require.Equal(t, Duration(time.Minute), Minute) - require.Equal(t, Duration(time.Hour), Hour) - require.Equal(t, Duration(24*time.Hour), Day) - require.Equal(t, Duration(7*24*time.Hour), Week) + // require.Equal(expected, actual) — expected is the reference time.Duration cast. + require.Equal(t, Nanosecond, Duration(time.Nanosecond)) + require.Equal(t, Microsecond, Duration(time.Microsecond)) + require.Equal(t, Millisecond, Duration(time.Millisecond)) + require.Equal(t, Second, Duration(time.Second)) + require.Equal(t, Minute, Duration(time.Minute)) + require.Equal(t, Hour, Duration(time.Hour)) + require.Equal(t, Day, Duration(24*time.Hour)) + require.Equal(t, Week, Duration(7*24*time.Hour)) // Typical usage from the issue: multiply integers by model constants. - require.Equal(t, Duration(15*24*time.Hour), 15*Day) - require.Equal(t, Duration(5000*time.Millisecond), 5000*Millisecond) + require.Equal(t, 15*Day, Duration(15*24*time.Hour)) + require.Equal(t, 5000*Millisecond, Duration(5000*time.Millisecond)) } func TestDurationMethods(t *testing.T) {