Date.now() and other calendar thoughts

+1 to replace unclear Date() with clear and explicit Date.now().

3 Likes

This thread has fallen dormant and what I'm going to write here comes at this topic from a different point of view; it relates to a more fundamental concern for time, so I'm probably off-topic but, hopefully, will trigger some more on-topic thinking.

Consider an app which might use three sources of time. It runs a simulation which needs (1) an accurate (true) time, (2) a variable time, to speed up, slow down, stop and reverse the simulation, and (3) the 'system' or 'menu bar' time, changeable in System Preferences.

I suggested, via Radar, many years ago, a framework, maybe called CoreTime (analogous to CoreLocation) which might satisfy this.

Before iOS adopted the use of network time (NTP) to provide time, the phone company time (I think) was used and, at least in south-east Michigan, AT&T time was usually more than one minute divergent from true time.

In short, if a Clock object existed I would like it to have some capabilities (and, I'm leaving aside operations and formatting that can be performed on an initialized Clock). I'd like to be able to create a Clock that played 'true time' (as best it could) within some specified accuracy, while reporting the ability to achieve/maintain it. I'd like to create a Clock for which I could set (and reset) start time and rate (positive, negative and zero). And I think there needs to be a Clock that presents 'menu bar' time. Whether Date() comes from the first or the last of these Clocks should be settable.

I wrote a NTP client years ago because my app needed 'true time' and it was immediately adopted by developers who needed to be able to detect naughty users cheating trial software expiry by setting back their system date!

Iā€™d like to have Date() replaced with Clock.system.now(). That would indeed make it easier to spot when function that is supposed to be pure has implicit dependencies.

I think being able to control time from the Xcode similar to how location is simulated would be useful.

For testing purposes, Iā€™d prefer to have something like

class TestClock: Clock {
    var currentDate: Date
    init(currentDate: Date)
    func now() -> Date { currentDate }
}

For simulation, we could have a LinearClock

class LinearClock: Clock {
    init(base: Clock, offset: TimeInterval, scale: Double)
}

So far, thatā€™s a summary of the things above. But also, Iā€™d like to say that clocks are closely related to timers. I have a rule of thumb to ā€œobserve what you readā€. Observing time is tricky - it changes constantly and reacting to each hardware tick is usually an overkill. So instead time is observed using timers. Timer notifies subscribers when expected moment is reached. I think clocks also should be factories of timers. And setting currentTime in TestTimer should trigger relevant timers.