public static func seconds<T: BinaryInteger>(_ seconds: T) -> Duration
public static func seconds(_ seconds: Double) -> Duration
public static func milliseconds<T: BinaryInteger>(_ milliseconds: T) -> Duration
public static func milliseconds(_ milliseconds: Double) -> Duration
public static func microseconds<T: BinaryInteger>(_ microseconds: T) -> Duration
public static func microseconds(_ microseconds: Double) -> Duration
public static func nanoseconds<T: BinaryInteger>(_ value: T) -> Duration
For no good reason, the obvious additional method:
public static func nanoseconds(_ nanoseconds: Double) -> Duration
was omitted from the proposal and implementation. It's somewhat useful. It's relatively simple to implement inside of Duration (where we can use _Int128), but relatively hard to implement well outside of the standard library. We should add it.
I assume it was omitted because it’s always going to truncate? round? the value, and Duration is documented to not have sub-nanosecond precision. But it doesn’t seem harmful to have it when someone could just as easily say Duration(milliseconds: value / 1000) as Duration(nanoseconds: UInt64(value)).
Since we’re on the topic of omissions from these APIs, can we add the overloads that make + commutative (as Strideable already does, and thus all clock and duration types, but not instant types) as well as *?
Agreed, and I will, but we should be willing to take small proposals for obvious missing API without asking every would-be contributor to do this. The possibility of other improvements doesn’t have to hold up a small obvious change.
Sorry, I’m not proposing Strideable conformance; I’m saying that those types in the proposal which already conform to Strideable have commutative +, but other types don’t have commutative +, and we can take the opportunity to address that inconsistency here because being able to add a duration to an instant in one order but not another is not an entirely intuitive limitation (or necessary, unless it messes up overload resolution performance).
I've read somewhere that there are reasons not to provide them, but from a practical point of view, I don't understand why minutes, hours, days, and weeks are missing. They have a pretty clear meaning and even if there exist calendars where their meanings might be different, with documentation their meanings can be made clear. I would optimize for the vast majority of use cases here.
I've actually defined a helper in my own library here that adds these APIs. So I thought maybe they should be considered (again) when doing a "holistic pass about what else is missing here".
I write this kind of code all the time. But I don't see it as a problem because I don't need second-level exactness. As a leap second is introduced less than once a year, it would require 60 years to make a difference of one minute. I see the point about exactness, but again, that could be solved with documentation, a warning or something else.
For a developer who doesn't know that there's something like a leap second, it's as surprising to them as if they used today.advanced(by: .days(1)). And if a developer knows about leap seconds, documenting that Duration.days isn't leap-second aware should be good enough, I think. I would guess that such a pure "Duration" representing API doesn't know anything about any calendrical things.
Just my noob opinion though, I'm no expert in this topic.