[Development] More on QDateTime / QTimeZone
John Layt
jlayt at kde.org
Fri Sep 13 15:50:29 CEST 2013
On Thursday 12 Sep 2013 19:24:15 Knoll Lars wrote:
> On 9/12/13 9:06 PM, "John Layt" <jlayt at kde.org> wrote:
> >The first is it means creating a QDateTime becomes a
> >lot slower as we need to calculate the epoch offset up-front, instead of
> >only when/if needed.
>
> We might be able to simply cache the time zone offset once and cache it.
> Then it should be at the same speed.
No, because we don't know the rules for when to apply Daylight Time, that's
why we'd need to call mktime for every new datetime creation. It can't be
avoided.
Besides, we already have a spec that offers this style behaviour: OffsetFromUTC.
> >The second is it means that the behaviour of the local
> >date/time staying constant over time zone changes will no longer be true.
> > It would be up to the app to realise a time zone change has happened and
> >to know what to do with the datetimes as a result.
>
> Well, IMO that's in most cases what you'd want in any case. I can't see
> how a date time specifying 5pm for a meeting should stay at 5pm when I fly
> to finland...
You also don't say I want an appointment at 2pm UTC whatever that happens to
be in local time, if you do and the daylight conversion rules change your
local appointment time also ends up changing. You instead say I want an
appointment at 3pm local time *in Oslo*. You only convert that to UTC if you
need to see what that local time is in another tz. QTimeZone will give us a
proper way to do that. You'd be crazy to currently be using LocalTime for
such things, you'd use UTC or OffsetFromUTC or KDateTime instead.
Where the local date/time stays constant is what's normally known as Clock
Time or Wall Time, i.e. I want to wake up at 7am no matter where in the world
I am. That's what LocalTime is closest to. If we switched LocalTime then
we'd need to add a new spec for ClockTime/WallTime/SystemTime to replicate
that behaviour.
The problem with LocalTime is it's neither fish nor fowl, it's just "This local
time, if you want UTC just use whatever the system time zone currently is".
We don't know what the most common use case is, but I suspect it's getting the
current local time, and showing a local date as a string. Most other use
cases will revolve around "whatever the current system tz is", or even not
care at all. It's the local time value they mostly want, not the UTC
equivalent.
The biggest problem I see with switching the behaviour is to define how to
update a datetime if needed after a time zone change. If we cache whatever
offset mktime returns at QDateTime creation, then when the tz changes any new
dates will immediately be created with the new offset, but the old instances
will still have the old offset, leaving things inconsistent and still not under
the apps control. You would also then need api for the app to tell the old
instances to update to the new offset, which seems ugly and inefficient and prone
to failure. The alternative is to use a cached QTimeZone to look up the offset
every time, that way the offset remains consistent until the app chooses to
refresh the cached QTimeZone, but then you lose any efficiency gains and you
might as well keep the old behaviour for now.
We also need to think about the serialization behaviour: do we still serialize
as the local time as we currently do, or as the UTC time? And how does that
affect serializing a time expressed in a QTimeZone? Is it a time in UTC to be
interpreted into a given tz, or is it a given local time to be interpreted
into UTC? If I make an appointment for 3pm Oslo time then I want that to stay
in Oslo time regardless if the rules for conversion to UTC change between
serialize/deserialize, so that still needs to serialize as local.
We'd also need to think about de-serializing old formats and how to convert
them correctly.
We may not need to implement all this in the first cut, but we at least need to
think about how it will work, otherwise we could end up releasing something
half-way there and then finding we can't actually make it work in teh full
solution.
If we do make the change, I'd also rather do it in a different way. Keep the
LocalTime spec behaving as it does so legacy code can easily switch to using
it, but create a new spec called something like SystemTime that behaves the
way you want, then possibly change the default spec from LocalTime to
SystemTime.
> Wouldn't the issues here be solved by storing all time values in UTC? In
> any case, I don't believe this is a showstopper for 5.2.
No, because you still need to make that initial conversion from local time to
UTC using mktime, so you'll still get the same inconsistencies. But yes, it's
a problem for later.
> These are corner cases (as the OSes don't really solve them as well
> apparently). I'd not worry too much about this for 5.2. If we get this
> settled in 5.3 it's good enough.
Corner cases, yes, thankfully most people don't schedule appointments for 2am
in the morning of daylight time conversion, and many of the banks I've worked
for shut down systems to avoid any ambiguities, but I'd hate for my local
nuclear power reactor or air traffic control system to be relying on the correct
behaviour :-) (hopefully they use UTC anyway). It's easily solved if the
standard was just a little more detailed in the expected behaviour. It's not
hard to state that the expected behaviour is to assume the first occurrence
unless otherwise requested. Which is exactly how QDateTime and QTimeZone will
deal with it. So long as the rules are applied consistently then all the
problems go away, it's the bugs that make it hard.
Long term I would like to have a global QTimeZone instance that we use instead
of mktime and localtime, that would cleanly solve all the cross-platform
problems, but I'd rather wait until QTimeZone is bedded in first and optimised.
It also needs the tz change signal to work properly.
John.
More information about the Development
mailing list