# Display for Duration

**URL:** <https://internals.rust-lang.org/t/display-for-duration/17588>\
**Category:** Uncategorized\
**Created:** [October 18, 2022, 12:20pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588 "2022-10-18T12:20:49Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [October 18, 2022, 12:20pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/1 "2022-10-18T12:20:49Z")

</div>

Isn't `Duration` too cautious about with having a `Display` impl?

I understand the concern about `SystemTime`. Dates are messy and need localization, but `Duration` is very simple and has an obvious universal representation, already implemented in its `Debug` format.

`Duration`'s existing debug formatting seems perfectly acceptable to me as an output for `Display` too. It's using a standard SI unit, and fractional seconds aren't more of an internationalization issue than existing `Display` of `f32`. I can imagine users may want to display `Duration` in other ways, like H:M:S or natural-language phrases, but `Display` doesn't promise to be the end of all formatting. `bool`'s `Display` has already set the bar very low, and `Duration` can already do better than that.

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [October 18, 2022, 3:33pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/2 "2022-10-18T15:33:56Z")

</div>

> It's using a standard SI unit, and fractional seconds aren't more of an internationalization issue than existing `Display` of `f32` .

I think it's a bit more: 100ms would be 100мс in Russain, unit names are translated.

That being said, `Display` is quite inadequate to provide i18n, we already have `true` and `false`, and we already use English error messages for Displays for various errors. So I think it's OK for `Display` in general to assume us-international locale, and we probably should just document that.

---

<div class="post-metadata">

**Author:** ![jbe](https://avatars.discourse-cdn.com/v4/letter/j/f6c823/32.png) [@jbe](https://internals.rust-lang.org/u/jbe)\
**Post date:** [October 21, 2022, 5:47pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/3 "2022-10-21T17:47:07Z")

</div>

> [@matklad](#):
>
> I think it's a bit more: 100ms would be 100мс in Russain, unit names are translated.

And `"0.5s"` would be `"0,5s"` in German, for example.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [October 21, 2022, 5:59pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/4 "2022-10-21T17:59:34Z")

</div>

> [@jbe](#):
>
> And `"0.5s"` would be `"0,5s"` in German, for example.

However `f32: Display` is already not localized that way, so it would be consistent for `Duration` to also not have a localized decimal separator.

---

<div class="post-metadata">

**Author:** ![jbe](https://avatars.discourse-cdn.com/v4/letter/j/f6c823/32.png) [@jbe](https://internals.rust-lang.org/u/jbe)\
**Post date:** [October 21, 2022, 6:51pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/5 "2022-10-21T18:51:25Z")

</div>

> [@scottmcm](#):
>
> However `f32: Display` is already not localized that way, so it would be consistent for `Duration` to also not have a localized decimal separator.

I guess the question is where to draw the line between `0.5` and `12/31/2022`. I don't mind the first, but would mind the latter. My personal impression is that `2.1s` is somewhere in between. However, in my case:

- I always use a decimal point instead of decimal comma because I'm so used to that because of programming.
- "s" is the abbreviation for seconds in German as well.

People from other background might cringe if they see an "s" because perhaps it's the abbreviation for hours in their language. Just hypothetically speaking to raise attention to that issue (not sure if it's really an issue, I don't speak many languages).

> [@matklad](#):
>
> we already have `true` and `false`

There are some things in `std` which later turned out to be a not-so-good idea. So taking "X is also implemented in `std`" as an argument _may_ be misleading (not wanting to say it's the case here, I'm really not sure).

---

<div class="post-metadata">

**Author:** ![jdahlstrom](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jdahlstrom/32/3351_2.png) [@jdahlstrom](https://internals.rust-lang.org/u/jdahlstrom)\
**Post date:** [October 21, 2022, 7:01pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/6 "2022-10-21T19:01:51Z")

</div>

"s" _is_ the official SI abbreviation of the unit, for what it’s worth, like J or Pa. But I’m not sure what the standard has to say about unit names in non-Latin alphabets (I guess it does have _something_ to say at least). Still, being standardized by the SI carries a fair bit more weight than just being a conventional abbreviation in a few languages.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [October 21, 2022, 8:00pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/7 "2022-10-21T20:00:06Z")

</div>

I like the argument that it should follow the SI & ISO 31-0 typographic conventions.

Note that `Debug` _doesn't_. Correct SI is "1 s", not "1s". I think keeping it one white-space-separable token is good for Debug, but perhaps `Display` should be "1.234 567 ms" instead of "1.234567ms".

(Apparently they allow `,` or `.` for the decimal separator, so we'd have to pick one of those, but `.` is pretty consistent with what we do in other `Display`s, so it'd probably be that one.)

And my interpretation is that the unit symbols [should not be translated](https://www.bipm.org/documents/20126/41483022/SI-Brochure-9.pdf/fcf090b2-04e6-88cc-1149-c3e029ad8232).

> Les symboles des grandeurs, imprimés en italique, sont généralement de simples lettres de l’alphabet grec ou latin et constituent des recommandations. Les symboles des unités, imprimés en caractères romains (droits), sont obligatoires (voir chapitre 5).

EDIT: Regarding the comment after this, if we're following _correct_ SI then it's definitely μs.

---

<div class="post-metadata">

**Author:** ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)\
**Post date:** [October 21, 2022, 9:13pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/8 "2022-10-21T21:13:13Z")

</div>

Since `Display` has stronger stability promises, we would have to agree how to abbreviate microseconds, at least:

> <https://github.com/rust-lang/rust/pull/75065>
>
> Formatting a Duration currently uses the suffix "µs" for microseconds.
> However, …this does not take into account whether the terminal or other
> output device can handle Unicode. Make it more robust on legacy
> terminals by using "us" instead.

EDIT: Regarding the EDIT above, I'm also on team μs, even though copy-paste is easier than typing it.

---

<div class="post-metadata">

**Author:** ![jbe](https://avatars.discourse-cdn.com/v4/letter/j/f6c823/32.png) [@jbe](https://internals.rust-lang.org/u/jbe)\
**Post date:** [October 22, 2022, 7:14am UTC](https://internals.rust-lang.org/t/display-for-duration/17588/9 "2022-10-22T07:14:49Z")

</div>

If there are really stability guarantees regarding this decision, then it doesn't feel good (to me), because there are many "style" questions that cannot be corrected later (space vs no space, μ vs u, etc).

I would like to ask: What is the gain of implementing `Display` for `Duration`? That should be compared with the possible downsides. Maybe the downsides are small, but so is the gain (perhaps?).

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [October 22, 2022, 1:41pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/10 "2022-10-22T13:41:53Z")

</div>

I'll repeat my argument: I think this is too cautious. It's a bikeshed detail, and if it's not perfect, it doesn't matter.

People can debate spaces and ASCII vs Unicode in terminal _forever_, which means that `Duration` will never have any good-enough `Display` implementation just out of paralysis of the endless discussion.

I suggest stabilizing whatever it uses for `Debug` today, as-is, just to avoid bikeshedding. The details are just not important. `Display` is not a trait for getting formatting perfect. It already formats every single type suboptimally: numbers don't have thousands separators, floats have US typography and ASCIIfied exponent notation, `bool` hardcodes English, `Display` for `Path` does not match `displayNameAtPath` on macOS, `Display` for errors is ad-hoc and weird with chaining. If someone cares whether durations should have a space or not, or needs to localize them, they will have to use something else than Rust's `Display` that is little more than `Debug` without brackets.

---

<div class="post-metadata">

**Author:** ![the8472](https://avatars.discourse-cdn.com/v4/letter/t/0ea827/32.png) [@the8472](https://internals.rust-lang.org/u/the8472)\
**Post date:** [October 22, 2022, 6:19pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/11 "2022-10-22T18:19:23Z")

</div>

> Since `Display` has stronger stability promises,

Imo this is a mischaracterization of the API. While `Debug` explicitly disclaims any stability most `Display` impls actually don't make any positive promise. There are unsettled previous debates about how stable they should be, if round-tripping through `FromStr` should be guaranteed and other things. Some definitely have changed before (e.g. `SocketAddrV6`) and may change again. Stability could also vary between the default and the alternate form.

Additionally there currently is some conflation between `Display` and `ToString` due to the blanket impl (which was a mistake imo). If specialization were available they could be separated again and we could say Display is for humans and ToString for round-tripping.

We definitely have an option to implement Display without promising that it'll remain forever unchanged. Especially if we don't offer a matching FromStr

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [October 22, 2022, 6:32pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/12 "2022-10-22T18:32:30Z")

</div>

Random thought: if we `impl Display for Duration`, at some point we'd probably `impl FromStr for Duration` as well.

---

<div class="post-metadata">

**Author:** ![the8472](https://avatars.discourse-cdn.com/v4/letter/t/0ea827/32.png) [@the8472](https://internals.rust-lang.org/u/the8472)\
**Post date:** [October 22, 2022, 6:44pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/13 "2022-10-22T18:44:35Z")

</div>

Not necessarily. For example one could do a compact, approximate, human-friendly duration impl that only shows the 2 most significant units. E.g. 1 year + 1 day + 5 minutes displays as `1y1d` not `1y1d5m` while 1 year + 1 minute displays as `1y1m`. For a human (1 year + small/tiny bit more) is usually all that's needed to eyeball something.

Obviously that kind of thing would be very inadequate for round-tripping and so a FromStr impl wouldn't be appropriate. Or at least it should use a different format. And in Std we do have the privilege of being able to use specialization, so we could offer a separate ToString impl if necessary.

---

<div class="post-metadata">

**Author:** ![tczajka](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tczajka/32/8923_2.png) [@tczajka](https://internals.rust-lang.org/u/tczajka)\
**Post date:** [October 22, 2022, 11:29pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/14 "2022-10-22T23:29:56Z")

</div>

> [@the8472](#):
>
> For example one could do a compact, approximate, human-friendly duration impl that only shows the 2 most significant units. E.g. 1 year + 1 day + 5 minutes displays as `1y1d` not `1y1d5m` while 1 year + 1 minute displays as `1y1m`. For a human (1 year + small/tiny bit more) is usually all that's needed to eyeball something.

I don't think approximating by default is a good idea. That's what the precision field of the format string is for. If the precision field is not set, the full precision should be displayed, just like it is for `f64` (sort of).

---

<div class="post-metadata">

**Author:** ![djc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/djc/32/1592_2.png) [@djc](https://internals.rust-lang.org/u/djc)\
**Post date:** [October 23, 2022, 6:15am UTC](https://internals.rust-lang.org/t/display-for-duration/17588/15 "2022-10-23T06:15:17Z")

</div>

Note that there is an ISO 8601 duration encoding (unfortunately RFC 3339 doesn't specify a more sensible subset of it), so users may conceptually expect a FromStr impl to parse that.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [October 23, 2022, 6:42am UTC](https://internals.rust-lang.org/t/display-for-duration/17588/16 "2022-10-23T06:42:17Z")

</div>

The ISO8601 duration includes _calendar_ durations (like "P1M"), however.

So that's a reasonable expectation for a `chrono::Duration`, but not for `std::time::Duration` which cannot represent such durations.

---

<div class="post-metadata">

**Author:** ![pdolezal](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pdolezal/32/7137_2.png) [@pdolezal](https://internals.rust-lang.org/u/pdolezal)\
**Post date:** [October 24, 2022, 8:27pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/17 "2022-10-24T20:27:24Z")

</div>

Java `Duration` uses ISO 8601 duration formatting regardless. It is limited to non-calendar durations in the way that `Duration::toString` returns a `PT` representation and `Duration::parse` converts calendar-based units in a non-exact way (e.g., a day equals exactly to 24 hours).

Java `Instant` uses ISO 8601 extended date + time representation in UTC (a.k.a. ISO instant) for both `Instant::toString` and `Instant::parse`.

Both seems quite sensible to me and definitely usable for implementing `Debug` trait in Rust, maybe even good enough for implementing `Display`. After all, they are rather low-level representations and therefore I personally would completely accept that. I would not even object if parsing `Duration` were limited to only the `PT` part unlike Java's acceptance of calendar units, converted to seconds under the hood, which might be surprising sometimes.

---

<div class="post-metadata">

**Author:** ![PoignardAzur](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/poignardazur/32/6464_2.png) [@PoignardAzur](https://internals.rust-lang.org/u/PoignardAzur)\
**Post date:** [October 25, 2022, 11:38am UTC](https://internals.rust-lang.org/t/display-for-duration/17588/18 "2022-10-25T11:38:19Z")

</div>

> [@kornel](#):
>
> People can debate spaces and ASCII vs Unicode in terminal _forever_, which means that `Duration` will never have any good-enough `Display` implementation just out of paralysis of the endless discussion.
> 
> I suggest stabilizing whatever it uses for `Debug` today, as-is, just to avoid bikeshedding.

This, so hard.

There's a point where the amount of effort spent debating a feature and the time the feature is delayed outweighs any possible gains from choosing one strategy over another, and at that point we should just shrug, pick one implementation and stick with it.

Bikeshedding debates aren't just annoying, they're a trap for the developer brain.

---

<div class="post-metadata">

**Author:** ![tczajka](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tczajka/32/8923_2.png) [@tczajka](https://internals.rust-lang.org/u/tczajka)\
**Post date:** [October 25, 2022, 3:44pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/19 "2022-10-25T15:44:31Z")

</div>

Regarding the ISO-8601 format:

I'm quoting from ISO-8601:2000 final draft, which is not the latest version, so some of this might be outdated.

I believe the "P" prefix should **not** be there for `Duration`. The "P" prefix is used when a duration is part of a "time interval", but is not part of the "duration" itself:

> **Time-interval** : a portion of time between two time-points. These time-points are respectively labelled “start” and “end”. Time intervals may be specified by these two time-points, by one of these time-points and the temporal distance between the points or by the temporal distance between these points only. [...]
> 
> **Duration** : a quantity (“length”) of time. [...]
> 
> In basic and extended format the complete representation for duration shall be nYnMnDTnHnMnS or nW. [...]
> 
> A **time interval** is expressed according to the following rules: [...]
> 
> b) for 5.5.1 b), c) and d) the designator [P] shall precede, without spaces, the representation of the duration

So a duration of 5 seconds would be `T5S`, not `PT5S`.

It's OK to assume days have exactly 24 hours, because ISO-8601 is agnostic about the time standard -- it doesn't have to be UTC or anything:

> This International Standard does not assign any particular meaning or interpretation to any data element that uses representations in accordance with this International Standard. Such meaning will be determined by the context of the application. [...]
> 
> **day** : a time-unit of 24 hours

It's even allowed to assume that a month has 30 days!

> **month** : unit of time of 28, 29, 30 or 31 days
> 
> NOTE In certain applications a month is regarded as a unit of time of 30 days.
> 
> **year** : a time-unit of 12 months, considered to approximate the duration required for one revolution of the earth around the sun

`Display` probably shouldn't use months and years, but `FromStr` could assume that months are 30 days are years are 12\*30 = 360 days (hmm...). Or it could just reject months and years as ambiguous.

For fractions of a second, commas or periods are allowed, but commas are preferred. So if `Duration` were to use `ISO-8601`, maybe it should use a comma in `Display`?

> If necessary for a particular application a decimal fraction of hour, minute or second may be included. If a decimal fraction is included, lower order components (if any) shall be omitted and the decimal fraction shall be divided from the integer part by the decimal sign specified in ISO 31-0: i.e. the comma [,] or full stop [.]. Of these, the comma is the preferred sign.

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [October 25, 2022, 6:28pm UTC](https://internals.rust-lang.org/t/display-for-duration/17588/20 "2022-10-25T18:28:54Z")

</div>

> [@tczajka](#):
>
> I believe the "P" prefix should **not** be there for `Duration`. The "P" prefix is used when a duration is part of a "time interval", but is not part of the "duration" itself:

I am in possession of ISO 8601-1:2019, which is the latest standard. The "P" prefix is required.

> [@tczajka](#):
>
> It's even allowed to assume that a month has 30 days!

Not quite (emphasis mine):

> For example, the durations of a year, month, week, day, hour or minute, may depend on when they occur [in a Gregorian calendar (3.1.1.19), a calendar month (3.1.2.19) can have a duration of 28, 29, 30, or 31 days; in a 24-hour clock (3.1.1.10), a clock minute (3.1.2.4) can have a duration of 59, 60, or 61 seconds, etc.]. **Therefore, the exact duration can only be evaluated if the exact duration of each is known.**

> [@tczajka](#):
>
> commas are preferred

No such preference is indicated in ISO 8601-1:2019. It may be indicated in ISO 80000-1, which is referenced, but I am not in possession of that.

[Next page](https://internals.rust-lang.org/t/display-for-duration/17588.md?page=2)
