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>
This commit is contained in:
parent
9d8db91ada
commit
7c33c644d3
@ -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:
|
||||
|
@ -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(); }
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user