diff options
author | Edward Welbourne <[email protected]> | 2021-07-28 12:10:51 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <[email protected]> | 2021-08-13 10:39:03 +0000 |
commit | a18926c736bf9de6bd652c8bb1799d4678001341 (patch) | |
tree | 6457a9aa94c2f6e12f6b780c0751f6db2718e861 /src/qml/jsruntime/qv4dateobject.cpp | |
parent | 2c3ea30205efef22146f3c7218d60b39fee991c2 (diff) |
Use QDateTime to get offsets for emscripten (wasm)
Since our wasm implementation doesn't have access to time-zone data by
default, but its QDateTime implementation does manage to get offsets
right for local time, use it as fall-back for V4's Date
implementation's DaylightSavingTA() and getLocalTZA().
This implementation might also be viable for other cases without
timezone support (and a way to reset it when the system zone has
changed), but we'll need to experiment to find out. For now, since we
have nothing better for wasm, use it there.
In passing, update a comment about a bug report against the ECMA spec
to say it's been fixed (and we're compatible with the result).
Fixes: QTBUG-95314
Change-Id: I40c1537815ada950dc0b5cebd4d641f7bfc45bd9
Reviewed-by: Ulf Hermann <[email protected]>
Reviewed-by: Lorn Potter <[email protected]>
(cherry picked from commit 373897481fb930055e6e89035b1055f8dd80b83f)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
Diffstat (limited to 'src/qml/jsruntime/qv4dateobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4dateobject.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index 389e9351e7..9b751fbeaa 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -78,10 +78,21 @@ QTBUG-75585 for an explanation and possible workarounds. */ #define USE_QTZ_SYSTEM_ZONE +#elif defined(Q_OS_WASM) +/* + TODO: evaluate using this version of the code more generally, rather than + the #else branches of the various USE_QTZ_SYSTEM_ZONE choices. It might even + work better than the timezone variant; experiments needed. +*/ +// Kludge around the lack of time-zone info using QDateTime. +// It uses localtime() and friends to determine offsets from UTC. +#define USE_QDT_LOCAL_TIME #endif #ifdef USE_QTZ_SYSTEM_ZONE #include <QtCore/QTimeZone> +#elif defined(USE_QDT_LOCAL_TIME) +// QDateTime already included above #else # ifdef Q_OS_WIN # include <windows.h> @@ -356,6 +367,7 @@ static inline double MakeDate(double day, double time) mean a whole day of DST offset for some zones, that have crossed the international date line. This shall confuse client code.) The bug report against the ECMAScript spec is https://github.com/tc39/ecma262/issues/725 + and they've now changed the spec so that the following conforms to it ;^> */ static inline double DaylightSavingTA(double t, double localTZA) // t is a UTC time @@ -363,6 +375,12 @@ static inline double DaylightSavingTA(double t, double localTZA) // t is a UTC t return QTimeZone::systemTimeZone().offsetFromUtc( QDateTime::fromMSecsSinceEpoch(qint64(t), Qt::UTC)) * 1e3 - localTZA; } +#elif defined(USE_QDT_LOCAL_TIME) +static inline double DaylightSavingTA(double t, double localTZA) // t is a UTC time +{ + return QDateTime::fromMSecsSinceEpoch(qint64(t), Qt::UTC + ).toLocalTime().offsetFromUtc() * 1e3 - localTZA; +} #else // This implementation fails to take account of past changes in standard offset. static inline double DaylightSavingTA(double t, double /*localTZA*/) @@ -721,6 +739,26 @@ static double getLocalTZA() // TODO: QTimeZone::resetSystemTimeZone(), see QTBUG-56899 and comment above. // Standard offset, with no daylight-savings adjustment, in ms: return QTimeZone::systemTimeZone().standardTimeOffset(QDateTime::currentDateTime()) * 1e3; +#elif defined(USE_QDT_LOCAL_TIME) + QDate today = QDate::currentDate(); + QDateTime near = today.startOfDay(Qt::LocalTime); + // Early out if we're in standard time anyway: + if (!near.isDaylightTime()) + return near.offsetFromUtc() * 1000; + int year, month; + today.getDate(&year, &month, nullptr); + // One of the solstices is probably in standard time: + QDate summer(year, 6, 21), winter(year - (month < 7 ? 1 : 0), 12, 21); + // But check the one closest to the present by preference, in case there's a + // standard time offset change between them: + QDateTime far = summer.startOfDay(Qt::LocalTime); + near = winter.startOfDay(Qt::LocalTime); + if (month > 3 && month < 10) + near.swap(far); + bool isDst = near.isDaylightTime(); + if (isDst && far.isDaylightTime()) // Permanent DST, probably an hour west: + return (qMin(near.offsetFromUtc(), far.offsetFromUtc()) - 3600) * 1000; + return (isDst ? far : near).offsetFromUtc() * 1000; #else # ifdef Q_OS_WIN TIME_ZONE_INFORMATION tzInfo; |