How do you measure elapsed time, and how do you show a duration?
Predict first
What does this print?
print(Duration.seconds(90).formatted(.time(pattern: .minuteSecond)))
- 1:30
- 01:30
- 90
Predict first
What does this print?
print(Duration.milliseconds(1500))
- 1.5 seconds
- 1500 ms
- 1.5
Mental model. Wall-clock time is the clock on the wall that someone can reset. A monotonic clock is a stopwatch nobody can touch.
Date is wall-clock time and can jump (clock changes, NTP), so subtracting two Date()s is not a reliable stopwatch. Use a monotonic clock: ContinuousClock keeps counting while the device sleeps, SuspendingClock pauses when it sleeps. clock.measure { } returns a Duration. Separately, ProcessInfo.systemUptime and mach_continuous_time are the lower-level options.
To show time to a person, Duration and Date.ComponentsFormatStyle format spans (“1:30”, “2 hr, 5 min”), and RelativeDateTimeFormatter produces “2 hours ago”. TimeInterval is just a Double of seconds, and DateInterval is a start plus a length.
The minuteSecond pattern does not pad the minutes. Pass padMinuteToLength: 2 if you want 01:30.
Duration prints in seconds with units, which makes log lines self-explanatory.
Common traps
- Timing code with
Date(). A clock adjustment mid-measurement gives negative or huge numbers. - Choosing
Suspendingfor a timeout that must expire in real time. It stops while asleep.
They might follow up with
- How would you build a “time ago” label?
RelativeDateTimeFormatterwith a fixedunitsStyle, refreshed on a timer. - Where does
Task.sleepfit? It accepts a clock, andTask.sleep(for:)usesContinuousClockby default.
Related questions
- 2.2.1 What is a Date in Foundation, and what does it not contain?
← What goes wrong with DateFormatter, and how do you parse a fixed…