std::time::Duration, and It Is Written 5.seconds()Status: Accepted
Date: September 19, 2026 (D5: October 4, 2026, #377)
Related: ADR-141 D2 (a construct a page writes before its record),
ADR-313 D2 (sleep pauses, so it is time::sleep),
ADR-285 (no suffix on a number literal, and why),
ADR-285 (a literal takes its type from its use),
ADR-288 D11 (an entry is written and reviewed, not copied from Rust),
Part II 12.4, Part III 13.3 (cleanup-deadline, which is already a duration
in a manifest)
Part II 12.4’s sleep(5.seconds()) wrote a value of a type nothing declared.
The type is not in dispute — a duration is a duration — so what is left is where it lives and how
it is spelled.
The manifest already has one: cleanup-deadline is a duration a person writes
in a .toml. What was missing is the value a program holds.
std::time::Duration.A std type, not a language one. It carries a span of time and nothing else,
it is a value that copies, and it is what time::sleep, a timeout and a
deadline take. It is Rust’s own type re-exported, not wrapped — a wrapper would
be a second type with the same meaning — and it crosses a thread
(crosses = true).
5.seconds(), as a method on an integer.Changed by ADR-313 D2: sleep pauses, so it is not in the prelude; a program writes time::sleep(5.seconds()) after use std::time.
use std::time
time::sleep(5.seconds())
time::sleep(250.millis())
let deadline = 2.minutes()
An extension std::time provides — seconds, millis, micros, minutes,
hours on both integer types of Part I 2.2. A computed count is written the
same way, retry_after.seconds(), so there is no second spelling: no
Duration::seconds(5), which would be a type’s associated constructor beside
the method (ADR-140 D2). A count below zero is no time
at all rather than an abort, and a count too large to multiply
saturates at the longest span there is rather than wrapping into a short
wait. time::sleep is a suspension point:
its entry carries no sync.
It is what the pages already write, which is not a small argument: the spelling was chosen by whoever wrote the example, and it reads the way the sentence does.
5s and 250ms would be a literal form that record declined for numbers, on
the ground that the digits a number is written in are a spelling and the use
gives the type. Reopening it for one type would make the rule a literal has
no suffix, except for durations — and a rule with an exception in it is a
rule a reader has to remember rather than one they can apply.
std’s, so the language learns nothing.No keyword, no literal, no type in the grammar. What this costs the language
is nothing at all; what it costs std is a type and a trait implementation.
timeout.in_seconds(), in the five units it is made in.Added October 4, 2026 (#377).
let timeout = 90.seconds()
timeout.in_seconds() // 90
timeout.in_minutes() // 1
in_hours, in_minutes, in_seconds, in_millis and in_micros, as
methods on the span: the five constructors of D2 mirrored, so a unit has one
name in each direction. Whole units, cut off, as an integer division is
(Java’s toSeconds, Go’s Milliseconds and Rust’s as_secs cut off too).
The answer is an i64, a count’s type (ADR-285 D1), so the
type says it is whole and the name need not.
Past i64::MAX it stays at i64::MAX. A span holds more microseconds
than an i64 counts only past 292,000 years, so only a span that was itself
saturated (i64::MAX.hours()) gets there; for ever read back as the
largest number is D2’s saturation mirrored, and what a timeout computation
wants rather than an abort.
Why not the other spellings. whole_seconds (Kotlin’s inWholeSeconds)
reads oddly; d.seconds() would be one name that makes a span on a number and
reads a number on a span; to_seconds is a conversion verb this language
writes as as or truncating_; d / 1.seconds() is an operator on a std
type nobody asked for. Rust’s own as_secs, as_millis and kin, which answer
u64 and u128, are not in the ledger: one spelling per unit. A fractional
reading (1.5 seconds) is not decided here.
time::sleep(5.seconds()) is a program.select has the value its timeout arm needs.println(f"{took.in_millis()} ms").std type, its entries, the integer extension, and
the five methods that read it back.cleanup-deadline is read
by the build, not by a program, and the two meeting is a question nobody has
asked.