summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2016-11-21 18:17:07 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2016-12-14 16:40:42 +0000
commit7c33c644d399e7d547ccf9f779197208d07bca84 (patch)
treede04e8d639b246c57667d6b7b6a259e7044c8e18
parent9d8db91ada0ab340ae781862f567c9b104e83c63 (diff)
Fix QDateTime::toString(Qt::ISODate)'s handling of Qt::TimeZone
When the time is specified relative to a zone, the ISO date produced lacked its offset suffix; all zones were treated as if they were local time. Handle zone as for an offset from UTC and ensure we do set the date-time objects's offset from UTC when it's zone-based. Change-Id: I7c9896bb8ec0a9d89df14a6e94b005174ab9e943 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/tools/qdatetime.cpp16
-rw-r--r--src/corelib/tools/qdatetime_p.h3
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp23
3 files changed, 40 insertions, 2 deletions
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index d52f03acae..4337a4d13f 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -2576,6 +2576,13 @@ static inline Qt::TimeSpec getSpec(const QDateTimeData &d)
return extractSpec(getStatus(d));
}
+#if QT_CONFIG(timezone)
+void QDateTimePrivate::setUtcOffsetByTZ(qint64 atMSecsSinceEpoch)
+{
+ m_offsetFromUtc = m_timeZone.d->offsetFromUtc(atMSecsSinceEpoch);
+}
+#endif
+
// Refresh the LocalTime validity and offset
static void refreshDateTime(QDateTimeData &d)
{
@@ -2591,10 +2598,12 @@ static void refreshDateTime(QDateTimeData &d)
#if QT_CONFIG(timezone)
// If not valid time zone then is invalid
if (spec == Qt::TimeZone) {
- if (!d->m_timeZone.isValid())
+ if (!d->m_timeZone.isValid()) {
status &= ~QDateTimePrivate::ValidDateTime;
- else
+ } else {
epochMSecs = QDateTimePrivate::zoneMSecsToEpochMSecs(msecs, d->m_timeZone, extractDaylightStatus(status), &testDate, &testTime);
+ d->setUtcOffsetByTZ(epochMSecs);
+ }
}
#endif // timezone
@@ -3822,6 +3831,9 @@ QString QDateTime::toString(Qt::DateFormat format) const
buf += QLatin1Char('Z');
break;
case Qt::OffsetFromUTC:
+#if QT_CONFIG(timezone)
+ case Qt::TimeZone:
+#endif
buf += toOffsetString(Qt::ISODate, offsetFromUtc());
break;
default:
diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h
index a217990c8d..b8f6736ac4 100644
--- a/src/corelib/tools/qdatetime_p.h
+++ b/src/corelib/tools/qdatetime_p.h
@@ -136,6 +136,9 @@ public:
static qint64 zoneMSecsToEpochMSecs(qint64 msecs, const QTimeZone &zone,
DaylightStatus hint = UnknownDaylightTime,
QDate *localDate = 0, QTime *localTime = 0);
+
+ // Inlined for its one caller in qdatetime.cpp
+ inline void setUtcOffsetByTZ(qint64 atMSecsSinceEpoch);
#endif // timezone
static inline qint64 minJd() { return QDate::minJd(); }
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index d4ae1b2a91..a5efbb9950 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -77,6 +77,7 @@ private slots:
void fromMSecsSinceEpoch();
void toString_isoDate_data();
void toString_isoDate();
+ void toString_isoDate_extra();
void toString_textDate_data();
void toString_textDate();
void toString_rfcDate_data();
@@ -794,6 +795,28 @@ void tst_QDateTime::toString_isoDate()
QLocale::setDefault(oldLocale);
}
+void tst_QDateTime::toString_isoDate_extra()
+{
+ QDateTime dt = QDateTime::fromMSecsSinceEpoch(0, Qt::UTC);
+ QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1970-01-01T00:00:00Z"));
+#if QT_CONFIG(timezone)
+ QTimeZone PST("America/Vancouver");
+ if (PST.isValid()) {
+ dt = QDateTime::fromMSecsSinceEpoch(0, PST);
+ QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1969-12-31T16:00:00-08:00"));
+ } else {
+ qDebug("Missed zone test: no America/Vancouver zone available");
+ }
+ QTimeZone CET("Europe/Berlin");
+ if (CET.isValid()) {
+ dt = QDateTime::fromMSecsSinceEpoch(0, CET);
+ QCOMPARE(dt.toString(Qt::ISODate), QLatin1String("1970-01-01T01:00:00+01:00"));
+ } else {
+ qDebug("Missed zone test: no Europe/Berlin zone available");
+ }
+#endif // timezone
+}
+
void tst_QDateTime::toString_textDate_data()
{
QTest::addColumn<QDateTime>("datetime");