Clocks Are Not Interchangeable — a Class Model of Four Kinds of Clock generalization arrows point at the shared abstraction; each subclass answers a different question about time «abstract» Clock read() : TimeValue kind : instant | duration uncertainty : known | hidden generalization TimeOfDayClock CLOCK_REALTIME / ms synchronized via NTP can jump back or forward comparable across nodes use: timestamps, deadlines MonotonicClock CLOCK_MONOTONIC / ns never jumps, only slewed rate adjusted up to 0.05% NOT comparable across nodes use: timeouts, durations LogicalClock counter, no oscillator Lamport / version vector measures order only no notion of seconds use: causal ordering UncertaintyClock TrueTime / ClockBound returns [earliest, latest] width = uncertainty bound narrow bound costs hardware use: commit wait, snapshots A reading is not a point in time The value is really an interval: the machine is 95% sure that now is between 10.3 and 10.5. Microsecond digits on a ±100 ms clock are noise. Most APIs hide the interval; TrueTime and ClockBound report it openly. Which clock for which job timeout or elapsed time ......... monotonic clock deadline or calendar time ....... time-of-day clock ordering across machines ........ logical clock · snapshot stamp ... uncertainty clock Inheritance is about guarantees, not implementation A monotonic clock measures how long something took on one machine. Only a logical clock or an uncertainty interval can order events that happen on different machines.