GitHub

duration

API reference for duration.

Durations, parsed once at the boundary.

Public APIs accept a Duration (seconds as a float, or a timedelta) and parse it with to_seconds into Seconds. Everything past the boundary (clocks, schedulers, schedule decisions) takes Seconds, so a raw float cannot reach a timer without being parsed.

Parsing follows Effect's Duration.make: NaN and -0 become 0. Infinities are kept (an infinite sleep never wakes); negative values are kept (a negative sleep wakes at once).

AttributeTypeDescription
ZEROSeconds = Seconds(0.0)

Classes

Functions

to_seconds

to_seconds(duration) -> Seconds
ParameterTypeDescription
durationDuration

Returns Seconds

def to_seconds(duration: Duration) -> Seconds:
    return Seconds(duration.total_seconds() if isinstance(duration, timedelta) else duration)

to_nanos

to_nanos(seconds) -> int

Whole nanoseconds (floored) in a finite number of seconds.

The float is read as the shortest decimal that prints it, so 1_000_000_000.001 is exactly 1_000_000_000_001_000_000; multiplying by 1e9 in floating point would be off by tens of nanoseconds at epoch-sized values.

ParameterTypeDescription
secondsfloat

Returns int

def to_nanos(seconds: float) -> int:
    """Whole nanoseconds (floored) in a finite number of seconds.

    The float is read as the shortest decimal that prints it, so
    ``1_000_000_000.001`` is exactly ``1_000_000_000_001_000_000``;
    multiplying by ``1e9`` in floating point would be off by tens of
    nanoseconds at epoch-sized values."""
    return math.floor(_exact_nanos(seconds))

to_millis

to_millis(duration) -> float

Milliseconds in duration, read as the shortest decimal that prints it (as to_nanos does), so a duration measured in whole nanoseconds gives nanos / 1e6 as Effect's Duration.toMillis does, not a float product one ulp off.

ParameterTypeDescription
durationDuration

Returns float

def to_millis(duration: Duration) -> float:
    """Milliseconds in ``duration``, read as the shortest decimal that
    prints it (as ``to_nanos`` does), so a duration measured in whole
    nanoseconds gives ``nanos / 1e6`` as Effect's ``Duration.toMillis``
    does, not a float product one ulp off."""
    if isinstance(duration, timedelta):
        return duration / timedelta(milliseconds=1)
    seconds = to_seconds(duration)
    if math.isinf(seconds):
        return float(seconds)
    return float(Decimal(repr(float(seconds))) * 1000)

format_duration

format_duration(seconds) -> str

Human-readable, as Effect's Duration.format: "1s 500ms".

ParameterTypeDescription
secondsSeconds

Returns str

def format_duration(seconds: Seconds) -> str:
    """Human-readable, as Effect's ``Duration.format``: ``"1s 500ms"``."""
    if math.isinf(seconds):
        return "Infinity" if seconds > 0 else "-Infinity"
    nanos = round(_exact_nanos(abs(seconds)))  # Effect keeps whole nanoseconds
    if nanos == 0:
        return "0"
    pieces: list[str] = []
    for suffix, size in _UNITS:
        count, nanos = divmod(nanos, size)
        if count:
            pieces.append(f"{count}{suffix}")
    if nanos:
        pieces.append(f"{nanos}ns")
    return ("-" if seconds < 0 else "") + " ".join(pieces)