Hello, I recently asked about random durations on this forum. However I was hitting some limitations and was encouraged to pitch. Looking forward to your feedback ![]()
Introduction
This proposal introduces public APIs to enable seamless integration of Int128 into the Duration type. Specifically, it provides support for directly accessing a Duration's attosecond representation via the newly available Int128 type and simplifies the creation of Duration values from attoseconds.
Motivation
The Duration type currently offers two ways to construct and decompose itself:
Low and high bits
public struct Duration: Sendable {
public var _low: UInt64
public var _high: Int64
public init(_high: Int64, low: UInt64) { ... }
}
Components
extension Duration {
public var components: (seconds: Int64, attoseconds: Int64) { ... }
public init(secondsComponent: Int64, attosecondsComponent: Int64) { ... }
}
However, both approaches have limitations when it comes to exposing Duration's total attosecond representation:
- The
_lowand_highproperties are underscored, indicating that their direct use is discouraged. - The
componentsproperty decomposes the value into seconds and attoseconds, requiring additional arithmetic operations for many use cases.
This gap becomes particularly evident in scenarios like generating a random Duration, which currently requires verbose and potentially inefficient code:
func randomDuration(upTo maxDuration: Duration) -> Duration {
let attosecondsPerSecond: Int128 = 1_000_000_000_000_000_000
let upperRange = Int128(maxDuration.components.seconds) * attosecondsPerSecond + Int128(maxDuration.components.attoseconds)
let (seconds, attoseconds) = Int128.random(in: 0..<upperRange).quotientAndRemainder(dividingBy: attosecondsPerSecond)
return .init(secondsComponent: Int64(seconds), attosecondsComponent: Int64(attoseconds))
}
By introducing direct Int128 support to Duration, this complexity is eliminated. Developers can write concise and efficient code instead:
func randomDuration(upTo maxDuration: Duration) -> Duration {
return Duration(attoseconds: Int128.random(in: 0..<maxDuration.attoseconds))
}
This addition reduces boilerplate, minimizes potential errors, and improves performance for use cases requiring high-precision time calculations.
Proposed solution
This proposal complements the existing construction and decomposition options by introducing a third approach, leveraging the new Int128 type:
- A new computed property
attoseconds, which exposes the total attoseconds of aDurationas anInt128. - A new initializer
init(attoseconds: Int128), which allows creating aDurationdirectly from a single 128-bit value.
These additions provide a direct and efficient mechanism for working with Duration values while maintaining full compatibility with existing APIs.
Detailed design
Internally, the Duration type represents its value using the underscored _high and _low properties, which encode attoseconds as a 128-bit integer split into two 64-bit values. The proposed APIs unify these components into a single Int128 representation:
@available(SwiftStdlib 6.0, *)
extension Duration {
/// The duration represented in attoseconds.
public var attoseconds: Int128 {
Int128(_low: _low, _high: _high)
}
/// Initializes a `Duration` from the given number of attoseconds.
public init(attoseconds: Int128) {
self.init(_high: attoseconds._high, low: attoseconds._low)
}
}