Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
Snapshot · Oct 24, 2026 · Frozen documentation

Duration

Stores a count in a compile-time rational seconds unit.

Sn is under heavy development. This reference includes the intended 1.0 design; features may be incomplete in the current compiler. Read the status →

Module std.time

import std.time;

Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.

Duration

pub struct Duration<Rep = i64, const Numerator: u64 = 1, const Denominator: u64 = 1>
    where Rep: Data, DurationCount

Stores a count in a compile-time rational seconds unit.

Conversion bodies preserve every built-in integer width, signed minimum and finite IEEE count. Full fixed scratch combination rounds IEEE results only after common-unit scaling and exact cancellation. Closed positive periods reduce before nominal type identity: Duration<i64, 2, 2000> and Duration<i64, 1, 1000> denote the same type. Zero periods are rejected at type use; symbolic ratios normalize when closed. Clock integration remains under active implementation. Pure arithmetic/conversion operations are dual-stage const functions: required evaluation uses the ordinary compiler work budget; runtime inputs execute the same checked bodies. No duration operation implicitly changes a nominal type or introduces allocation, synchronization or infinity. Unit periods validate positive reduced ratios. Explicit exact conversion reports precision loss; named rounding selects mathematical precision reduction. Rep: Copyable Defaultable integer or finite IEEE count representation. Numerator: Positive compile-time seconds numerator. Denominator: Positive compile-time seconds denominator.

Example

module example.constant_duration;
import std.time as Time;
from std.time import Duration, Seconds, Milliseconds, DurationError;
const Budget: Milliseconds = 2_s + 250_ms;
const Whole: Seconds = Budget.Floor<Seconds>();
const Rounded: Seconds = Milliseconds.Create(2500).Round<Seconds>();
const ExactMilliseconds: Milliseconds = switch Duration<f64>.Create(1.5_f64).TryTo<Milliseconds>() {
    case .Ok { Value = Value } => break Value;
    case .Err { Error = _ } => { panic; }
};
const RejectFraction: bool = switch Budget.TryTo<Seconds>() {
    case .Ok { Value = _ } => break false;
    case .Err { Error = Error } => break Error == DurationError.PrecisionLoss;
};
fn Main() -> i32 {
    if Budget.Count != 2250 || Whole.Count != 2 || Rounded.Count != 2 { return 1; }
    if ExactMilliseconds.Count != 1500 || !RejectFraction { return 2; }
    return 0;
}

Example

module example.floating_duration_conversion;
from std.time import Duration, Milliseconds, Seconds, DurationError;
// These exact conversion/arithmetic cases deliberately compare IEEE counts.
@allow("W2101")
fn Main() -> i32 {
    let Delay = Duration<f64>.Create(1.5_f64);
    switch Delay.TryTo<Milliseconds>() {
        case .Ok { Value = Value } => { if Value.Count != 1500 { return 1; } }
        case .Err => return 2;
    }
    switch Delay.TryTo<Seconds>() {
        case .Ok => return 3;
        case .Err { Error = Error } => { if Error != DurationError.PrecisionLoss { return 4; } }
    }
    if Delay.Floor<Seconds>().Count != 1 || Delay.Ceil<Seconds>().Count != 2 { return 5; }
    let Negative = -Delay;
    if Negative.Floor<Seconds>().Count != -2 || Negative.Ceil<Seconds>().Count != -1 { return 6; }
    switch Milliseconds.Create(1500).TryTo<Duration<f32>>() {
        case .Ok { Value = Value } => { if Value.Count != 1.5_f32 { return 7; } }
        case .Err => return 8;
    }
    if Delay.Compare(Milliseconds.Create(1500)) != 0 { return 9; }
    return 0;
}

Example

module example.floating_duration_arithmetic;
from std.time import Duration, DurationError;
// These exact conversion/arithmetic cases deliberately compare IEEE counts.
@allow("W2101")
fn Main() -> i32 {
    let Delay = Duration<f64>.Create(1.5_f64);
    let Extra = Duration<f64, 1, 1000>.Create(250.0_f64);
    switch Delay.TryAdd(Extra) {
        case .Ok { Value = Value } => { if Value.Count != 1750.0_f64 { return 1; } }
        case .Err => return 2;
    }
    let Maximum = Duration<f64>.Create(bit_cast<f64>(0x7FEFFFFFFFFFFFFF_u64));
    if (Maximum - Maximum).Count != 0.0_f64 { return 3; }
    switch Maximum.TryAdd(Maximum) {
        case .Ok => return 4;
        case .Err { Error = Error } => { if Error != DurationError.RangeOverflow { return 5; } }
    }
    return 0;
}

Example

module example.integer_duration;
from std.time import Duration, Milliseconds, Seconds, Years, BillionYears;
fn Main() -> i32 {
    let Delay = Milliseconds.Create(2250);
    if Seconds.Create(2) == Delay || !(Seconds.Create(2) != Delay) { return 11; }
    if !(Seconds.Create(2) < Delay) || !(Seconds.Create(2) <= Delay) { return 12; }
    if !(Delay > Seconds.Create(2)) || !(Delay >= Seconds.Create(2)) { return 13; }
    if Seconds.Create(2).Compare(Milliseconds.Create(2000)) != 0 { return 14; }
    if Delay.TryTo<Seconds>() is .Ok { Value = _ } { return 1; }
    if Delay.Floor<Seconds>().Count != 2 { return 2; }
    if Delay.Ceil<Seconds>().Count != 3 { return 3; }
    if Milliseconds.Create(-2250).Floor<Seconds>().Count != -3 { return 4; }
    if Milliseconds.Create(2500).Round<Seconds>().Count != 2 { return 5; }
    if (Seconds.Create(20) + Seconds.Create(22)).Count != 42 { return 6; }
    if (Seconds.Create(2) + Milliseconds.Create(250)).Count != 2250 { return 15; }
    if (Seconds.Create(2) - Milliseconds.Create(250)).Count != 1750 { return 16; }
    let LongTime = BillionYears.Create(1);
    switch LongTime.TryTo<Years>() {
        case .Ok { Value = Value } => { if Value.Count != 1000000000 { return 7; } }
        case .Err { Error = _ } => return 8;
    }
    let Minimum = Duration<i128>.Create(-170141183460469231731687303715884105728_i128);
    switch Minimum.TryTo<Duration<i128>>() {
        case .Ok { Value = Value } => { if Value.Count != Minimum.Count { return 9; } }
        case .Err { Error = _ } => return 10;
    }
    return 0;
}

Create

pub static const fn Create(Count: Rep) -> Duration<Rep, Numerator, Denominator>

Creates a finite count in this validated rational unit. Count: Exact integer or finite IEEE count; no implicit unit conversion. Return: Independent owned duration without allocation or synchronization. Warning: Traps nonfinite counts or invalid periods; use TryCreate for recovery.

TryCreate

pub static const fn TryCreate(Count: Rep) -> Result<Duration<Rep, Numerator, Denominator>, DurationError>

Attempts finite count construction with explicit error handling. Count: Exact integer or IEEE count in this type's rational unit. Return: Owned duration, NonFinite for NaN/infinity, or InvalidPeriod. Note: Preserves signed zero and performs no allocation or synchronization.

pub Count: Rep

pub Count: Rep

Observes the exact count without conversion. Return: Count in the declared rational unit.

operator

pub readonly const fn operator +() -> Duration<Rep, Numerator, Denominator>

Preserves the exact count and unit under ordinary unary plus. Return: Independent duration value with identical representation.

operator

pub readonly const fn operator -() -> Duration<Rep, Numerator, Denominator>

Reverses the count sign with a checked representation boundary. Return: Negated count in the same unit; unrepresentable negation fatal-traps. Note: Signed minimum and nonzero unsigned negation are unrepresentable.

Period

pub static const fn Period() -> DurationPeriod

Validates/reduces this type's declared rational seconds period. Return: Positive reduced period; invalid type parameters fatal-trap when evaluated.

ConvertMagnitude

pub static const fn ConvertMagnitude(Value: readonly DurationMagnitude&,
        Period: DurationPeriod, Rounding: DurationRounding) -> Result<Duration<Rep, Numerator, Denominator>, DurationError>

Converts exact integer or IEEE count facts into this destination type. Value: Exact source facts, borrowed only during conversion. Period: Validated source unit measured in seconds. Rounding: Explicit precision selection. Return: Exact destination count or period/range/precision error; no allocation.

TryTo

pub readonly const fn TryTo<Target>() -> Result<Target, DurationError> where Target: DurationDestination

Attempts exact conversion to a caller-selected duration type. Target: Structural destination type preserving its own count/unit. Return: Destination or precision/range error; no silent truncation or infinity.

Floor

pub readonly const fn Floor<Target>() -> Target where Target: DurationDestination

Rounds toward negative infinity in the selected destination unit. Target: Exact destination type satisfying DurationDestination. Return: Destination count; checked period/range failure fatal-traps.

Ceil

pub readonly const fn Ceil<Target>() -> Target where Target: DurationDestination

Rounds toward positive infinity in the selected destination unit. Target: Exact destination type satisfying DurationDestination. Return: Destination count; checked period/range failure fatal-traps.

Round

pub readonly const fn Round<Target>() -> Target where Target: DurationDestination

Rounds to nearest target count, breaking exact ties toward even. Target: Exact destination type satisfying DurationDestination. Return: Destination count; checked period/range failure fatal-traps.

TryAdd

pub readonly const fn TryAdd<const OtherNumerator: u64, const OtherDenominator: u64>(
        Other: readonly Duration<Rep, OtherNumerator, OtherDenominator>&)
        -> Result<Duration<Rep, CommonDurationNumerator(Numerator, Denominator, OtherNumerator, OtherDenominator), CommonDurationDenominator(Numerator, Denominator, OtherNumerator, OtherDenominator)>, DurationError>

Combines equal-representation finite counts in a reduced common unit. OtherNumerator: Positive other unit seconds numerator. OtherDenominator: Positive other unit seconds denominator. Other: Equal-representation duration borrowed only for this call. Return: Common-unit finite result or final count range error; cancellation precedes narrowing.

operator

pub readonly const fn operator +<const OtherNumerator: u64, const OtherDenominator: u64>(
        Other: readonly Duration<Rep, OtherNumerator, OtherDenominator>&) -> Duration<Rep, CommonDurationNumerator(Numerator, Denominator, OtherNumerator, OtherDenominator), CommonDurationDenominator(Numerator, Denominator, OtherNumerator, OtherDenominator)>

Applies mixed-period + with checked final representation range. OtherNumerator: Positive other unit seconds numerator. OtherDenominator: Positive other unit seconds denominator. Other: Equal-representation duration borrowed only during combination. Return: Finite common-unit result; range/period errors fatal-trap, never Endless.

TrySubtract

pub readonly const fn TrySubtract<const OtherNumerator: u64, const OtherDenominator: u64>(
        Other: readonly Duration<Rep, OtherNumerator, OtherDenominator>&)
        -> Result<Duration<Rep, CommonDurationNumerator(Numerator, Denominator, OtherNumerator, OtherDenominator), CommonDurationDenominator(Numerator, Denominator, OtherNumerator, OtherDenominator)>, DurationError>

Combines equal-representation finite counts in a reduced common unit. OtherNumerator: Positive other unit seconds numerator. OtherDenominator: Positive other unit seconds denominator. Other: Equal-representation duration borrowed only for this call. Return: Common-unit finite result or final count range error; cancellation precedes narrowing.

operator

pub readonly const fn operator -<const OtherNumerator: u64, const OtherDenominator: u64>(
        Other: readonly Duration<Rep, OtherNumerator, OtherDenominator>&) -> Duration<Rep, CommonDurationNumerator(Numerator, Denominator, OtherNumerator, OtherDenominator), CommonDurationDenominator(Numerator, Denominator, OtherNumerator, OtherDenominator)>

Applies mixed-period - with checked final representation range. OtherNumerator: Positive other unit seconds numerator. OtherDenominator: Positive other unit seconds denominator. Other: Equal-representation duration borrowed only during combination. Return: Finite common-unit result; range/period errors fatal-trap, never Endless.

Compare

pub readonly const fn Compare<OtherRep, const OtherNumerator: u64, const OtherDenominator: u64>(
        Other: readonly Duration<OtherRep, OtherNumerator, OtherDenominator>&) -> i32
        where OtherRep: Data, DurationCount

Compares exact finite time values across representations and rational units. OtherRep: Copyable Defaultable other integer or IEEE count representation. OtherNumerator: Positive other unit seconds numerator. OtherDenominator: Positive other unit seconds denominator. Other: Finite duration borrowed only for this exact comparison. Return: Negative, zero or positive for less, equal or greater; no unit narrowing.

operator

pub readonly const fn operator == <OtherRep, const OtherNumerator: u64, const OtherDenominator: u64>(
        Other: readonly Duration<OtherRep, OtherNumerator, OtherDenominator>&) -> bool
        where OtherRep: Data, DurationCount

Tests exact mixed integer duration ordering with == semantics. OtherRep: Copyable Defaultable other integer or IEEE count representation. OtherNumerator: Positive other unit seconds numerator. OtherDenominator: Positive other unit seconds denominator. Other: Duration borrowed for exact rational comparison. Return: Selected relation without allocation, rounding or representation narrowing.

operator

pub readonly const fn operator < <OtherRep, const OtherNumerator: u64, const OtherDenominator: u64>(
        Other: readonly Duration<OtherRep, OtherNumerator, OtherDenominator>&) -> bool
        where OtherRep: Data, DurationCount

Tests exact mixed integer duration ordering with < semantics. OtherRep: Copyable Defaultable other integer or IEEE count representation. OtherNumerator: Positive other unit seconds numerator. OtherDenominator: Positive other unit seconds denominator. Other: Duration borrowed for exact rational comparison. Return: Selected relation without allocation, rounding or representation narrowing.

operator

pub readonly const fn operator <= <OtherRep, const OtherNumerator: u64, const OtherDenominator: u64>(
        Other: readonly Duration<OtherRep, OtherNumerator, OtherDenominator>&) -> bool
        where OtherRep: Data, DurationCount

Tests exact mixed integer duration ordering with <= semantics. OtherRep: Copyable Defaultable other integer or IEEE count representation. OtherNumerator: Positive other unit seconds numerator. OtherDenominator: Positive other unit seconds denominator. Other: Duration borrowed for exact rational comparison. Return: Selected relation without allocation, rounding or representation narrowing.

operator

pub readonly const fn operator > <OtherRep, const OtherNumerator: u64, const OtherDenominator: u64>(
        Other: readonly Duration<OtherRep, OtherNumerator, OtherDenominator>&) -> bool
        where OtherRep: Data, DurationCount

Tests exact mixed integer duration ordering with > semantics. OtherRep: Copyable Defaultable other integer or IEEE count representation. OtherNumerator: Positive other unit seconds numerator. OtherDenominator: Positive other unit seconds denominator. Other: Duration borrowed for exact rational comparison. Return: Selected relation without allocation, rounding or representation narrowing.

operator

pub readonly const fn operator >= <OtherRep, const OtherNumerator: u64, const OtherDenominator: u64>(
        Other: readonly Duration<OtherRep, OtherNumerator, OtherDenominator>&) -> bool
        where OtherRep: Data, DurationCount

Tests exact mixed integer duration ordering with >= semantics. OtherRep: Copyable Defaultable other integer or IEEE count representation. OtherNumerator: Positive other unit seconds numerator. OtherDenominator: Positive other unit seconds denominator. Other: Duration borrowed for exact rational comparison. Return: Selected relation without allocation, rounding or representation narrowing.

Documentation snapshot: October 24, 2026 About versions ↗
Searching Development · language & standard library