From 6f44c597e8acc60fa25164be17dc50999057a325 Mon Sep 17 00:00:00 2001 From: Sahil Singh Date: Sun, 26 Apr 2026 20:24:22 +0530 Subject: [PATCH] duration: extract roundDuration helper and round consistently Consolidates ad-hoc rounding (int(d.Hours()+0.5)) and integer truncation into a single roundDuration helper, so days/weeks/months/years all use round-half-up semantics. Adds day/week/month/year constants and extends tests for the new rounding behavior. Refs #6891 Signed-off-by: Sahil Singh --- duration.go | 27 +++++++++++++++++++-------- duration_test.go | 11 +++++++++-- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/duration.go b/duration.go index 48dd874..e965efe 100644 --- a/duration.go +++ b/duration.go @@ -7,6 +7,17 @@ import ( "time" ) +const ( + day = 24 * time.Hour + week = 7 * day + month = 30 * day + year = 365 * day +) + +func roundDuration(d, unit time.Duration) int { + return int(float64(d)/float64(unit) + 0.5) +} + // HumanDuration returns a human-readable approximation of a duration // (eg. "About a minute", "4 hours ago", etc.). func HumanDuration(d time.Duration) string { @@ -20,16 +31,16 @@ func HumanDuration(d time.Duration) string { return "About a minute" } else if minutes < 60 { return fmt.Sprintf("%d minutes", minutes) - } else if hours := int(d.Hours() + 0.5); hours == 1 { + } else if hours := roundDuration(d, time.Hour); hours == 1 { return "About an hour" } else if hours < 48 { return fmt.Sprintf("%d hours", hours) - } else if hours < 24*7*2 { - return fmt.Sprintf("%d days", hours/24) - } else if hours < 24*30*2 { - return fmt.Sprintf("%d weeks", hours/24/7) - } else if hours < 24*365*2 { - return fmt.Sprintf("%d months", hours/24/30) + } else if d < 2*week { + return fmt.Sprintf("%d days", roundDuration(d, day)) + } else if d < 2*month { + return fmt.Sprintf("%d weeks", roundDuration(d, week)) + } else if d < 2*year { + return fmt.Sprintf("%d months", roundDuration(d, month)) } - return fmt.Sprintf("%d years", int(d.Hours())/24/365) + return fmt.Sprintf("%d years", roundDuration(d, year)) } diff --git a/duration_test.go b/duration_test.go index 93d2a32..62e2b0c 100644 --- a/duration_test.go +++ b/duration_test.go @@ -57,7 +57,7 @@ func ExampleHumanDuration() { // 7 days // 13 days // 2 weeks - // 2 weeks + // 3 weeks // 3 weeks // 4 weeks // 4 weeks @@ -108,21 +108,28 @@ func TestHumanDuration(t *testing.T) { assertEquals(t, "2 days", HumanDuration(2*day)) assertEquals(t, "7 days", HumanDuration(7*day)) assertEquals(t, "13 days", HumanDuration(13*day+5*time.Hour)) + assertEquals(t, "3 days", HumanDuration(2*day+17*time.Hour)) + assertEquals(t, "14 days", HumanDuration(13*day+12*time.Hour)) assertEquals(t, "2 weeks", HumanDuration(2*week)) - assertEquals(t, "2 weeks", HumanDuration(2*week+4*day)) + assertEquals(t, "3 weeks", HumanDuration(2*week+4*day)) assertEquals(t, "3 weeks", HumanDuration(3*week)) + assertEquals(t, "4 weeks", HumanDuration(3*week+6*day)) assertEquals(t, "4 weeks", HumanDuration(4*week)) assertEquals(t, "4 weeks", HumanDuration(4*week+3*day)) assertEquals(t, "4 weeks", HumanDuration(1*month)) + assertEquals(t, "8 weeks", HumanDuration(8*week+3*day)) assertEquals(t, "6 weeks", HumanDuration(1*month+2*week)) assertEquals(t, "2 months", HumanDuration(2*month)) assertEquals(t, "2 months", HumanDuration(2*month+2*week)) assertEquals(t, "3 months", HumanDuration(3*month)) assertEquals(t, "3 months", HumanDuration(3*month+1*week)) + assertEquals(t, "4 months", HumanDuration(3*month+20*day)) assertEquals(t, "5 months", HumanDuration(5*month+2*week)) assertEquals(t, "13 months", HumanDuration(13*month)) assertEquals(t, "23 months", HumanDuration(23*month)) assertEquals(t, "24 months", HumanDuration(24*month)) assertEquals(t, "2 years", HumanDuration(24*month+2*week)) assertEquals(t, "3 years", HumanDuration(3*year+2*month)) + assertEquals(t, "4 years", HumanDuration(3*year+8*month)) + assertEquals(t, "4 years", HumanDuration(3*year+200*day)) }