diff options
-rw-r--r-- | src/qml/doc/src/types/qmldate.qdoc | 26 | ||||
-rw-r--r-- | src/qml/qml/qqmllocale.cpp | 18 | ||||
-rw-r--r-- | src/qml/qml/qqmllocale_p.h | 1 | ||||
-rw-r--r-- | tests/auto/qml/qqmllocale/data/timeZoneUpdated.qml | 51 | ||||
-rw-r--r-- | tests/auto/qml/qqmllocale/tst_qqmllocale.cpp | 41 |
5 files changed, 137 insertions, 0 deletions
diff --git a/src/qml/doc/src/types/qmldate.qdoc b/src/qml/doc/src/types/qmldate.qdoc index 802f977503..f1cff3dfff 100644 --- a/src/qml/doc/src/types/qmldate.qdoc +++ b/src/qml/doc/src/types/qmldate.qdoc @@ -198,3 +198,29 @@ \endcode */ +/*! + \qmlmethod string Date::timeZoneUpdated() + + Informs the JS engine that the system's timezone has been changed, which is necessary + for the correct manipulation of date/time data. + + JS stores Date objects in UTC time; all access to and from Date components in local + time involves the application of the current offset from UTC. If the current offset + changes due to the timezone being updated, the JS engine needs to be informed so that + it can recalculate the offset. + + This function should be called after the system's timezone has been updated. + + For example, an application that changes the timezone would call timeZoneUpdated() after + setting the new time zone: + + \code + property string selectedTimeZone + + onSelectedTimeZoneChanged: { + MyFunctions.setSystemTimeZone(selectedTimeZone) + Date.timeZoneUpdated() + } + \endcode +*/ + diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 7d2dafe3b3..9a2ec6f0e3 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -131,6 +131,13 @@ static const char *dateFromLocaleDateStringFunction = " })" "})"; +static const char *dateTimeZoneUpdatedFunction = + "(function(timeZoneUpdatedFunc) { " + " Date.timeZoneUpdated = (function() {" + " return timeZoneUpdatedFunc.apply(null, arguments);" + " })" + "})"; + static void registerFunction(QV8Engine *engine, const char *script, v8::InvocationCallback func) { @@ -150,6 +157,7 @@ void QQmlDateExtension::registerExtension(QV8Engine *engine) registerFunction(engine, dateFromLocaleStringFunction, fromLocaleString); registerFunction(engine, dateFromLocaleTimeStringFunction, fromLocaleTimeString); registerFunction(engine, dateFromLocaleDateStringFunction, fromLocaleDateString); + registerFunction(engine, dateTimeZoneUpdatedFunction, timeZoneUpdated); } v8::Handle<v8::Value> QQmlDateExtension::toLocaleString(const v8::Arguments& args) @@ -387,6 +395,16 @@ v8::Handle<v8::Value> QQmlDateExtension::fromLocaleDateString(const v8::Argument return QJSConverter::toDateTime(QDateTime(dt)); } +v8::Handle<v8::Value> QQmlDateExtension::timeZoneUpdated(const v8::Arguments& args) +{ + if (args.Length() != 0) + V8THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments"); + + v8::Date::DateTimeConfigurationChangeNotification(); + + return v8::Undefined(); +} + //----------------- // Number extension diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index c701c1ca1c..7007770245 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -66,6 +66,7 @@ private: static v8::Handle<v8::Value> fromLocaleString(const v8::Arguments& args); static v8::Handle<v8::Value> fromLocaleTimeString(const v8::Arguments& args); static v8::Handle<v8::Value> fromLocaleDateString(const v8::Arguments& args); + static v8::Handle<v8::Value> timeZoneUpdated(const v8::Arguments& args); }; diff --git a/tests/auto/qml/qqmllocale/data/timeZoneUpdated.qml b/tests/auto/qml/qqmllocale/data/timeZoneUpdated.qml new file mode 100644 index 0000000000..92d1f5bc40 --- /dev/null +++ b/tests/auto/qml/qqmllocale/data/timeZoneUpdated.qml @@ -0,0 +1,51 @@ +import QtQuick 2.0 + +Item { + property bool success: false + + property date localDate + property date utcDate + + Component.onCompleted: { + // Test date: 2012-06-01T02:15:30+10:00 (AEST timezone) + localDate = new Date(2012, 6-1, 1, 2, 15, 30) + utcDate = new Date(Date.UTC(2012, 6-1, 1, 2, 15, 30)) + + if (localDate.getTimezoneOffset() != -600) return + + if (localDate.toLocaleString() != "Friday, June 1, 2012 2:15:30 AM AEST") return + if (localDate.toISOString() != "2012-05-31T16:15:30.000Z") return + + if (utcDate.toISOString() != "2012-06-01T02:15:30.000Z") return + if (utcDate.toLocaleString() != "Friday, June 1, 2012 12:15:30 PM AEST") return + + success = true + } + + function check() { + success = false + + // We have changed to IST time zone - inform JS: + Date.timeZoneUpdated() + + if (localDate.getTimezoneOffset() != -330) return + + if (localDate.toLocaleString() != "Friday, June 1, 2012 2:15:30 AM IST") return + if (localDate.toISOString() != "2012-05-31T20:45:30.000Z") return + + if (utcDate.toISOString() != "2012-06-01T06:45:30.000Z") return + if (utcDate.toLocaleString() != "Friday, June 1, 2012 12:15:30 PM IST") return + + // Create new dates in this timezone + localDate = new Date(2012, 6-1, 1, 2, 15, 30) + utcDate = new Date(Date.UTC(2012, 6-1, 1, 2, 15, 30)) + + if (localDate.toLocaleString() != "Friday, June 1, 2012 2:15:30 AM IST") return + if (localDate.toISOString() != "2012-05-31T20:45:30.000Z") return + + if (utcDate.toISOString() != "2012-06-01T02:15:30.000Z") return + if (utcDate.toLocaleString() != "Friday, June 1, 2012 7:45:30 AM IST") return + + success = true + } +} diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp index e74570261f..c39426375f 100644 --- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp +++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp @@ -47,6 +47,8 @@ #include <qcolor.h> #include "../../shared/util.h" +#include <time.h> + class tst_qqmllocale : public QQmlDataTest { Q_OBJECT @@ -80,6 +82,7 @@ private slots: void dateTimeFormat(); void timeFormat_data(); void timeFormat(); + void timeZoneUpdated(); void dateToLocaleString_data(); void dateToLocaleString(); @@ -1214,6 +1217,44 @@ void tst_qqmllocale::stringLocaleCompare() QCOMPARE(obj->property("comparison").toInt(), QString::localeAwareCompare(string1, string2)); } +static void setTimeZone(const QByteArray &tz) +{ + qputenv("TZ", tz); +#if defined(Q_OS_WIN32) + ::_tzset(); +#elif defined(Q_OS_UNIX) + ::tzset(); +#endif +} + +void tst_qqmllocale::timeZoneUpdated() +{ +#if !defined(Q_OS_WIN32) && !defined(Q_OS_UINX) + QSKIP("Timezone manipulation not available for this platform"); +#endif + + QByteArray original(qgetenv("TZ")); + + // Set the timezone to Brisbane time + setTimeZone(QByteArray("AEST-10:00")); + + QQmlEngine e; + QQmlComponent c(&e, testFileUrl("timeZoneUpdated.qml")); + QScopedPointer<QObject> obj(c.create()); + QVERIFY(obj); + QCOMPARE(obj->property("success").toBool(), true); + + // Change to Indian time + setTimeZone(QByteArray("IST-05:30")); + + QMetaObject::invokeMethod(obj.data(), "check"); + + // Reset to original time + setTimeZone(original); + + QCOMPARE(obj->property("success").toBool(), true); +} + QTEST_MAIN(tst_qqmllocale) #include "tst_qqmllocale.moc" |