Summary
This RFC proposes a more convenient method of formatting std::time::Duration methods to strings.
Motivation
The std::time API is currently pretty bare-bones, compared to time libraries in other languages. This is because date/time processing is a hairy area, and it is preferred that a std-worthy API be iterated outside of std. Examples of available 3rd-party libraries are time and chrono.
Still, for some applications, e.g. measuring time elapsed while a piece of code runs, std::time is perfectly usable, except that printing the results in a non-Debug manner is tedious. This RFC tries to help in this area, namely adding a method of formatting Duration values with some degree of customization.
Detailed design
This RFC does not propose to implement Display on Duration. This might be used later for a standards conforming exact representation (see “Alternatives” below). Instead, a new method called display() is added, similar to that on Path, returning a Display struct with a std::fmt::Display impl.
This provides the opportunity of adding arguments to display(), which is useful since a Duration can be expressed in different units, and the string formatting language is not capable of expressing this on its own. The proposed signature is:
fn display<U: Into<Option<Unit>>>(&self, unit: U) -> Display
with
enum Unit { Secs, Millis, Micros, Nanos }
The std::fmt::Display impl for Display can then format the duration according to the given unit, using the number format given in the format string specification. None selects the unit so that the number is above 1. The unit is added to the result unless “alternate” format is requested with #.
Examples:
let d = Duration::new(0, 500_000_000);
format!("{}", d.display(None)) // -> "500 ms"
format!("{}", d.display(Unit::Secs)) // -> "0.5 s"
format!("{:.3}", d.display(Unit::Secs)) // -> "0.500 s"
format!("{}", d.display(Unit::Micros)) // -> "500000 us"
format!("{:#}", d.display(Unit::Micros)) // -> "500000"
How We Teach This
This is a new API with entry in the library reference.
In the book and Rust by Example, there is currently no example using Duration other than as an argument to thread::sleep.
Drawbacks
- When stabilized, will be around forever, might not be useful enough for all cases.
Alternatives
The time crate implements Display on its Duration, which uses ISO 8601 format (PxDTy.yyyS). Standard conforming, but not very readable. The chrono crate just reuses time::Duration.
Unresolved questions
- More units? Years, months, days, hours, minutes?
- Can
Unit be otherwise useful later?
- Instead of
Option<Unit>, add Unit::Auto?
- Swap meaning of alternate/normal format?
- Support exponential notation?