Personally, seeing something like "200s" is much less intuitive than "3m30s" when I'm trying to see how long something lasted.
func (d Duration) format(buf *[32]byte) int {
// Largest time is 2540400h10m10.000000000s
w := len(buf)
u := uint64(d)
neg := d < 0
if neg {
u = -u
}
if u < uint64(Second) {
// Special case: if duration is smaller than a second,
// use smaller units, like 1.2ms
var prec int
w--
buf[w] = 's'
w--
switch {
case u == 0:
buf[w] = '0'
return w
case u < uint64(Microsecond):
// print nanoseconds
prec = 0
buf[w] = 'n'
case u < uint64(Millisecond):
// print microseconds
prec = 3
// U+00B5 'µ' micro sign == 0xC2 0xB5
w-- // Need room for two bytes.
copy(buf[w:], "µ")
default:
// print milliseconds
prec = 6
buf[w] = 'm'
}
w, u = fmtFrac(buf[:w], u, prec)
w = fmtInt(buf[:w], u)
} else {
w--
buf[w] = 's'
w, u = fmtFrac(buf[:w], u, 9)
// u is now integer seconds
w = fmtInt(buf[:w], u%60)
u /= 60
// u is now integer minutes
if u > 0 {
w--
buf[w] = 'm'
w = fmtInt(buf[:w], u%60)
u /= 60
// u is now integer hours
// Stop at hours because days can be different lengths.
if u > 0 {
w--
buf[w] = 'h'
w = fmtInt(buf[:w], u)
}
}
}
if neg {
w--
buf[w] = '-'
}
return w
}
This is the function Go uses and I think something analogous should be implemented.
Note that the std Durationdoes not implement Display. If you are thinking about the Duration type in the time crate, that's a (popular) ecosystem crate, and IRLO isn't the place to discuss its API design — and IIUC it uses the format you're looking for if you specify a precision.
Duration intentionally does not have a Display impl, as there are a variety of ways to format spans of time for human readability. Duration provides a Debug impl that shows the full precision of the value.
The Debug output is intended to be only developer facing, and to somewhat directly match the actual stored data representation. Also, the alternative flag for debug formatting {:#?} is conventionally for the "pretty print" of derived representational Debug, so reusing it to indicate base 24:60:60 formatting of the duration instead of base 10 is far from ideal.
While I do think not implementing Display is likely the right call for std Duration, providing getters for the parts (e.g. as_weeks, subweek_days, subday_hours, subhour_mins, and submin_secs), especially now that from_timeunit constructors are available for these longer units (unstable, feature(duration_constructors)).