Fix setUTCXxx methods in Date
authorLars Knoll <lars.knoll@digia.com>
Tue, 9 Sep 2014 13:39:11 +0000 (15:39 +0200)
committerLars Knoll <lars.knoll@digia.com>
Thu, 11 Sep 2014 07:57:00 +0000 (09:57 +0200)
The methods where converting doing a localtime->UTC
conversion even though the input was already in UTC.

Task-number: QTBUG-38448
Change-Id: I4409275fade0dd2a677af2293edc87445f853879
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/jsruntime/qv4dateobject.cpp
tests/auto/qml/qqmlecmascript/data/utcdate.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp

index 67d247d..66601b6 100644 (file)
@@ -550,16 +550,7 @@ static inline QDateTime ToDateTime(double t, Qt::TimeSpec spec)
 {
     if (std::isnan(t))
         return QDateTime();
-    if (spec == Qt::LocalTime)
-        t = LocalTime(t);
-    int year = int(YearFromTime(t));
-    int month = int(MonthFromTime(t) + 1);
-    int day = int(DateFromTime(t));
-    int hours = HourFromTime(t);
-    int mins = MinFromTime(t);
-    int secs = SecFromTime(t);
-    int ms = msFromTime(t);
-    return QDateTime(QDate(year, month, day), QTime(hours, mins, secs, ms), spec);
+    return QDateTime::fromMSecsSinceEpoch(t, spec);
 }
 
 static inline QString ToString(double t)
@@ -586,7 +577,7 @@ static inline QString ToUTCString(double t)
 {
     if (std::isnan(t))
         return QStringLiteral("Invalid Date");
-    return ToDateTime(t, Qt::UTC).toString() + QStringLiteral(" GMT");
+    return ToDateTime(t, Qt::UTC).toString();
 }
 
 static inline QString ToDateString(double t)
@@ -1029,7 +1020,7 @@ ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx)
 
     double t = self->date().asDouble();
     double ms = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
-    self->date().setDouble(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
+    self->date().setDouble(TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))));
     return self->date().asReturnedValue();
 }
 
@@ -1056,7 +1047,7 @@ ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx)
     double t = self->date().asDouble();
     double sec = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
     double ms = (ctx->d()->callData->argc < 2) ? msFromTime(t) : ctx->d()->callData->args[1].toNumber();
-    t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
+    t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)));
     self->date().setDouble(t);
     return self->date().asReturnedValue();
 }
@@ -1086,7 +1077,7 @@ ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx)
     double min = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
     double sec = (ctx->d()->callData->argc < 2) ? SecFromTime(t) : ctx->d()->callData->args[1].toNumber();
     double ms = (ctx->d()->callData->argc < 3) ? msFromTime(t) : ctx->d()->callData->args[2].toNumber();
-    t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
+    t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)));
     self->date().setDouble(t);
     return self->date().asReturnedValue();
 }
@@ -1118,7 +1109,7 @@ ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx)
     double min = (ctx->d()->callData->argc < 2) ? MinFromTime(t) : ctx->d()->callData->args[1].toNumber();
     double sec = (ctx->d()->callData->argc < 3) ? SecFromTime(t) : ctx->d()->callData->args[2].toNumber();
     double ms = (ctx->d()->callData->argc < 4) ? msFromTime(t) : ctx->d()->callData->args[3].toNumber();
-    t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
+    t = TimeClip(MakeDate(Day(t), MakeTime(hour, min, sec, ms)));
     self->date().setDouble(t);
     return self->date().asReturnedValue();
 }
@@ -1144,7 +1135,7 @@ ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx)
 
     double t = self->date().asDouble();
     double date = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
-    t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
+    t = TimeClip(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)));
     self->date().setDouble(t);
     return self->date().asReturnedValue();
 }
@@ -1172,7 +1163,7 @@ ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx)
     double t = self->date().asDouble();
     double month = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
     double date = (ctx->d()->callData->argc < 2) ? DateFromTime(t) : ctx->d()->callData->args[1].toNumber();
-    t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
+    t = TimeClip(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)));
     self->date().setDouble(t);
     return self->date().asReturnedValue();
 }
@@ -1213,7 +1204,7 @@ ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx)
     double year = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
     double month = (ctx->d()->callData->argc < 2) ? MonthFromTime(t) : ctx->d()->callData->args[1].toNumber();
     double date = (ctx->d()->callData->argc < 3) ? DateFromTime(t) : ctx->d()->callData->args[2].toNumber();
-    t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
+    t = TimeClip(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)));
     self->date().setDouble(t);
     return self->date().asReturnedValue();
 }
diff --git a/tests/auto/qml/qqmlecmascript/data/utcdate.qml b/tests/auto/qml/qqmlecmascript/data/utcdate.qml
new file mode 100644 (file)
index 0000000..7f66ee3
--- /dev/null
@@ -0,0 +1,34 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Item {
+    MyDateClass {
+        id: mdc
+    }
+
+    function check_utc(utcstr) {
+        var datetimeutc = utcstr.split('T')
+        var dateutc = datetimeutc[0].split('-')
+        var timeutc = datetimeutc[1].split(':')
+        var utcDate = new Date(0)
+        utcDate.setUTCFullYear(Number(dateutc[0]))
+        utcDate.setUTCMonth(Number(dateutc[1])-1)
+        utcDate.setUTCDate(Number(dateutc[2]))
+        utcDate.setUTCHours(Number(timeutc[0]))
+        utcDate.setUTCMinutes(Number(timeutc[1]))
+        utcDate.setUTCSeconds(Number(timeutc[2]))
+        if (utcDate.getUTCFullYear() != Number(dateutc[0]))
+            return false;
+        if (utcDate.getUTCMonth() != Number(dateutc[1])-1)
+            return false;
+        if (utcDate.getUTCDate() != Number(dateutc[2]))
+            return false;
+        if (utcDate.getUTCHours() != Number(timeutc[0]))
+            return false;
+        if (utcDate.getUTCMinutes() != Number(timeutc[1]))
+            return false;
+        if (utcDate.getUTCSeconds() != Number(timeutc[2]))
+            return false;
+        return true;
+    }
+}
index 01125f8..c246647 100644 (file)
@@ -199,6 +199,7 @@ private slots:
     void sequenceSort_data();
     void sequenceSort();
     void dateParse();
+    void utcDate();
     void qtbug_22464();
     void qtbug_21580();
     void singleV8BindingDestroyedDuringEvaluation();
@@ -7362,6 +7363,21 @@ void tst_qqmlecmascript::dateParse()
 
 }
 
+void tst_qqmlecmascript::utcDate()
+{
+    QQmlComponent component(&engine, testFileUrl("utcdate.qml"));
+
+    QObject *object = component.create();
+    if (object == 0)
+        qDebug() << component.errorString();
+    QVERIFY(object != 0);
+
+    QVariant q;
+    QVariant val = QString::fromLatin1("2014-07-16T23:30:31");
+    QMetaObject::invokeMethod(object, "check_utc", Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, val));
+    QVERIFY(q.toBool() == true);
+}
+
 void tst_qqmlecmascript::concatenatedStringPropertyAccess()
 {
     QQmlComponent component(&engine, testFileUrl("concatenatedStringPropertyAccess.qml"));