diff options
author | Erik Verbruggen <erik.verbruggen@qt.io> | 2016-07-08 16:40:28 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2016-08-10 17:17:15 +0000 |
commit | 6e687e85719cf6e8cad218b0307749f7abd049a6 (patch) | |
tree | 6b3ac827dda0be334ecc50adcc3832be0781364c /src/qml/jsruntime/qv4dateobject.cpp | |
parent | 8bf7cfb7880775f49dfbaf9a2be2202479eaaf99 (diff) |
V4: Handle QTime->DateObject conversion better
By specification, date conversion functions for dates before the epoch
are not DST corrected. We converted QTime to a QDateTime where we set
the date part to Jan. 1, 1970, and then convert that to msecs since the
epoch UTC. For places on Earth where they had DST on that day (e.g.
Hobart in Australia), strange things happen: conversion from a QTime to
DateObject will use DST (because it's after the epoch in local time),
but conversions from DateObject to QTime won't use the DST because it's
before the epoch (in UTC).
Now as everyone knows, a 24-hour clock time has no meaning without a
date, only "elapsed time" has. But users still expect to be able to pass
QTime to QML/JS. So, we do the conversion on day 0 of month 0 of year 0,
and all of it in local time. This gives a stable conversion in both
directions, and the values in both C++ and QML/JS are the same for any
timezone (with or without DST) on this planet.
Task-number: QTBUG-54378
Change-Id: I892e16a93f015e92d311c6cae3ae7768b7373f6a
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4dateobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4dateobject.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index df648ba9ee..04358fe3b5 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -639,6 +639,28 @@ Heap::DateObject::DateObject(const QDateTime &date) this->date = date.isValid() ? date.toMSecsSinceEpoch() : qt_qnan(); } +Heap::DateObject::DateObject(const QTime &time) +{ + if (!time.isValid()) { + date = qt_qnan(); + return; + } + + /* All programmers know that stuff starts at 0. Whatever that may mean in this context (and + * local timezone), it's before the epoch, so there is defenitely no DST problem. Specifically: + * you can't start with a date before the epoch, add some[*] hours, and end up with a date + * after. That's a problem for timezones where new year happens during DST, like + * Australia/Hobart, because we have to ignore DST before the epoch (but honor it after the + * epoch). + * + * [*] Well, when "some" is in the range 0-24. If you add something like 1M then this might + * still happen. + */ + static const double d = MakeDay(0, 0, 0); + double t = MakeTime(time.hour(), time.minute(), time.second(), time.msec()); + date = TimeClip(UTC(MakeDate(d, t))); +} + QDateTime DateObject::toQDateTime() const { return ToDateTime(date(), Qt::LocalTime); |