Hello,
I'm trying to have a Task wait until a Foundation Date, but I can't quite figure out the necessary incantation:
// I don't know how to build a ContinuousClock.Instant from a Date
let instant: ContinuousClock.Instant = ???
try await Task.sleep(until: instant)
// I can't find the UTCClock mentioned in SE-0329
// <https://github.com/apple/swift-evolution/blob/main/proposals/0329-clock-instant-duration.md>
try await Task.sleep(until: date, using: ???)
I did try to Google for a solution, but I remain clueless 
May I ask for your help, if you know a technique that achieves this goal?
1 Like
ole
(Ole Begemann)
2
I'd do it like this:
let targetDate: Date = …
let seconds = targetDate.timeIntervalSinceNow
try await Task.sleep(for: .seconds(seconds))
Alternatively, you can first create an Instant with ContinuousClock.Instant.now + .seconds(seconds) and then use sleep(until:), but that seems unnecessary.
3 Likes
AlexanderM
(Alexander Momchilov)
4
And by the power of Swift, you can make it as elegant as:
try await Task.sleep2(until: targetDate)
Demo:
import Foundation
extension Task {
static func sleep(until target: Date) async throws where Success == Never, Failure == Never {
let duration = target.timeIntervalSinceNow
try await Self.sleep(for: .seconds(duration))
}
}
print("Waiting for 1s...")
try await Task.sleep(until: Date.now.addingTimeInterval(1))
print("... done.")
(Ironically, to test it, I'm using a relative time, kinda defeating the point
)
3 Likes
Yes, I was about to add this extension :-)
Maybe the promised UTCClock of SE-0329 will ship one day!
1 Like
Retrospectively, I asked the wrong question 
I do indeed have a target Date, but the current date (now) is injected, for testability and previews. I ended up with:
// Works for both past and future dates.
// For past dates, seconds is negative, and Task.sleep
// returns immediately.
let seconds = targetDate.timeIntervalSince(currentDate())
try await Task.sleep(for: .seconds(seconds))
Thank you all for your support 
2 Likes
In case anyone was wondering (I did for a beat), there's really really no reason to use the until form instead:
public func sleep(
for duration: Instant.Duration,
tolerance: Instant.Duration? = nil
) async throws {
try await sleep(until: now.advanced(by: duration), tolerance: tolerance)
}