Adapt corelib to use QTimeZone in place of Qt::TimeSpec

This saves (mostly in corelib/time/) some complications that used to
arise from needing different code-paths for different time-specs.

Task-number: QTBUG-108199
Change-Id: I5dbd09859fce7599f1ba761f8a0bfc4633d0bef9
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Edward Welbourne 2022-08-30 16:08:07 +02:00
parent e71099989e
commit 3f282e8896
18 changed files with 561 additions and 534 deletions

View File

@ -226,8 +226,8 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt
// find timezones, which is incredibly expensive. As we aren't // find timezones, which is incredibly expensive. As we aren't
// presenting these to the user, we don't care (at all) about the // presenting these to the user, we don't care (at all) about the
// local timezone, so force them to UTC to avoid that conversion. // local timezone, so force them to UTC to avoid that conversion.
firstModified.setTimeSpec(Qt::UTC); firstModified.setTimeZone(QTimeZone::UTC);
secondModified.setTimeSpec(Qt::UTC); secondModified.setTimeZone(QTimeZone::UTC);
r = firstModified.msecsTo(secondModified); r = firstModified.msecsTo(secondModified);
break; break;

View File

@ -1822,7 +1822,7 @@ static inline QDateTime fileTimeToQDateTime(const FILETIME *time)
FileTimeToSystemTime(time, &sTime); FileTimeToSystemTime(time, &sTime);
return QDateTime(QDate(sTime.wYear, sTime.wMonth, sTime.wDay), return QDateTime(QDate(sTime.wYear, sTime.wMonth, sTime.wDay),
QTime(sTime.wHour, sTime.wMinute, sTime.wSecond, sTime.wMilliseconds), QTime(sTime.wHour, sTime.wMinute, sTime.wSecond, sTime.wMilliseconds),
Qt::UTC); QTimeZone::UTC);
} }
QDateTime QFileSystemMetaData::birthTime() const QDateTime QFileSystemMetaData::birthTime() const

View File

@ -18,6 +18,7 @@
#include "qplatformdefs.h" #include "qplatformdefs.h"
#include <QtCore/qglobal.h> #include <QtCore/qglobal.h>
#include <QtCore/qdatetime.h> #include <QtCore/qdatetime.h>
#include <QtCore/qtimezone.h>
#include <QtCore/private/qabstractfileengine_p.h> #include <QtCore/private/qabstractfileengine_p.h>
// Platform-specific includes // Platform-specific includes
@ -264,13 +265,29 @@ inline QDateTime QFileSystemMetaData::fileTime(QAbstractFileEngine::FileTime tim
#if defined(Q_OS_UNIX) #if defined(Q_OS_UNIX)
inline QDateTime QFileSystemMetaData::birthTime() const inline QDateTime QFileSystemMetaData::birthTime() const
{ return birthTime_ ? QDateTime::fromMSecsSinceEpoch(birthTime_, Qt::UTC) : QDateTime(); } {
return birthTime_
? QDateTime::fromMSecsSinceEpoch(birthTime_, QTimeZone::UTC)
: QDateTime();
}
inline QDateTime QFileSystemMetaData::metadataChangeTime() const inline QDateTime QFileSystemMetaData::metadataChangeTime() const
{ return metadataChangeTime_ ? QDateTime::fromMSecsSinceEpoch(metadataChangeTime_, Qt::UTC) : QDateTime(); } {
return metadataChangeTime_
? QDateTime::fromMSecsSinceEpoch(metadataChangeTime_, QTimeZone::UTC)
: QDateTime();
}
inline QDateTime QFileSystemMetaData::modificationTime() const inline QDateTime QFileSystemMetaData::modificationTime() const
{ return modificationTime_ ? QDateTime::fromMSecsSinceEpoch(modificationTime_, Qt::UTC) : QDateTime(); } {
return modificationTime_
? QDateTime::fromMSecsSinceEpoch(modificationTime_, QTimeZone::UTC)
: QDateTime();
}
inline QDateTime QFileSystemMetaData::accessTime() const inline QDateTime QFileSystemMetaData::accessTime() const
{ return accessTime_ ? QDateTime::fromMSecsSinceEpoch(accessTime_, Qt::UTC) : QDateTime(); } {
return accessTime_
? QDateTime::fromMSecsSinceEpoch(accessTime_, QTimeZone::UTC)
: QDateTime();
}
inline uint QFileSystemMetaData::userId() const { return userId_; } inline uint QFileSystemMetaData::userId() const { return userId_; }
inline uint QFileSystemMetaData::groupId() const { return groupId_; } inline uint QFileSystemMetaData::groupId() const { return groupId_; }

View File

@ -17,6 +17,8 @@
#include <qendian.h> #include <qendian.h>
#include <qlocale.h> #include <qlocale.h>
#include <qdatetime.h>
#include <qtimezone.h>
#include <private/qbytearray_p.h> #include <private/qbytearray_p.h>
#include <private/qnumeric_p.h> #include <private/qnumeric_p.h>
#include <private/qsimd_p.h> #include <private/qsimd_p.h>
@ -798,7 +800,7 @@ static QCborValue::Type convertToExtendedType(QCborContainerPrivate *d)
ok = convertDoubleTo(round(e.fpvalue() * 1000), &msecs); ok = convertDoubleTo(round(e.fpvalue() * 1000), &msecs);
} }
if (ok) if (ok)
dt = QDateTime::fromMSecsSinceEpoch(msecs, Qt::UTC); dt = QDateTime::fromMSecsSinceEpoch(msecs, QTimeZone::UTC);
} }
if (dt.isValid()) { if (dt.isValid()) {
QByteArray text = dt.toString(Qt::ISODateWithMs).toLatin1(); QByteArray text = dt.toString(Qt::ISODateWithMs).toLatin1();

View File

@ -6,14 +6,12 @@
#include "private/qstringiterator_p.h" #include "private/qstringiterator_p.h"
#include "qdatastream.h" #include "qdatastream.h"
#include "qset.h"
#include "qvarlengtharray.h"
#include "qlocale.h"
#include "qdatetime.h" #include "qdatetime.h"
#if QT_CONFIG(timezone)
#include "qtimezone.h"
#endif
#include "qdebug.h" #include "qdebug.h"
#include "qlocale.h"
#include "qset.h"
#include "qtimezone.h"
#include "qvarlengtharray.h"
//#define QDATETIMEPARSER_DEBUG //#define QDATETIMEPARSER_DEBUG
#if defined (QDATETIMEPARSER_DEBUG) && !defined(QT_NO_DEBUG_STREAM) #if defined (QDATETIMEPARSER_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
@ -134,9 +132,7 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
int minute = time.minute(); int minute = time.minute();
int second = time.second(); int second = time.second();
int msec = time.msec(); int msec = time.msec();
Qt::TimeSpec tspec = v.timeSpec(); QTimeZone timeZone = v.timeRepresentation();
// Only offset from UTC is amenable to setting an int value:
int offset = tspec == Qt::OffsetFromUTC ? v.offsetFromUtc() : 0;
const SectionNode &node = sectionNodes.at(index); const SectionNode &node = sectionNodes.at(index);
switch (node.type) { switch (node.type) {
@ -168,8 +164,8 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
case TimeZoneSection: case TimeZoneSection:
if (newVal < absoluteMin(index) || newVal > absoluteMax(index)) if (newVal < absoluteMin(index) || newVal > absoluteMax(index))
return false; return false;
tspec = Qt::OffsetFromUTC; // Only offset from UTC is amenable to setting an int value:
offset = newVal; timeZone = QTimeZone::fromSecondsAheadOfUtc(newVal);
break; break;
case AmPmSection: hour = (newVal == 0 ? hour % 12 : (hour % 12) + 12); break; case AmPmSection: hour = (newVal == 0 ? hour % 12 : (hour % 12) + 12); break;
default: default:
@ -209,12 +205,7 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
if (!newDate.isValid() || !newTime.isValid()) if (!newDate.isValid() || !newTime.isValid())
return false; return false;
// Preserve zone: v = QDateTime(newDate, newTime, timeZone);
v =
#if QT_CONFIG(timezone)
tspec == Qt::TimeZone ? QDateTime(newDate, newTime, v.timeZone()) :
#endif
QDateTime(newDate, newTime, tspec, offset);
return true; return true;
} }
@ -231,11 +222,7 @@ int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
const SectionNode &sn = sectionNode(s); const SectionNode &sn = sectionNode(s);
switch (sn.type) { switch (sn.type) {
case TimeZoneSection: case TimeZoneSection:
#if QT_CONFIG(timezone)
return QTimeZone::MaxUtcOffsetSecs; return QTimeZone::MaxUtcOffsetSecs;
#else
return +14 * 3600; // NB: copied from QTimeZone
#endif
case Hour24Section: case Hour24Section:
case Hour12Section: case Hour12Section:
// This is special-cased in parseSection. // This is special-cased in parseSection.
@ -279,11 +266,7 @@ int QDateTimeParser::absoluteMin(int s) const
const SectionNode &sn = sectionNode(s); const SectionNode &sn = sectionNode(s);
switch (sn.type) { switch (sn.type) {
case TimeZoneSection: case TimeZoneSection:
#if QT_CONFIG(timezone)
return QTimeZone::MinUtcOffsetSecs; return QTimeZone::MinUtcOffsetSecs;
#else
return -14 * 3600; // NB: copied from QTimeZone
#endif
case Hour24Section: case Hour24Section:
case Hour12Section: case Hour12Section:
case MinuteSection: case MinuteSection:
@ -1179,26 +1162,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, bool fixup) const
int second = defaultTime.second(); int second = defaultTime.second();
int msec = defaultTime.msec(); int msec = defaultTime.msec();
int dayofweek = calendar.dayOfWeek(defaultDate); int dayofweek = calendar.dayOfWeek(defaultDate);
Qt::TimeSpec tspec = defaultValue.timeSpec(); QTimeZone timeZone = defaultValue.timeRepresentation();
int zoneOffset = 0; // In seconds; local - UTC
#if QT_CONFIG(timezone)
QTimeZone timeZone;
#endif
switch (tspec) {
case Qt::OffsetFromUTC: // timeZone is ignored
zoneOffset = defaultValue.offsetFromUtc();
break;
#if QT_CONFIG(timezone)
case Qt::TimeZone:
timeZone = defaultValue.timeZone();
if (timeZone.isValid())
zoneOffset = timeZone.offsetFromUtc(defaultValue);
// else: is there anything we can do about this ?
break;
#endif
default: // zoneOffset and timeZone are ignored
break;
}
int ampm = -1; int ampm = -1;
Sections isSet = NoSection; Sections isSet = NoSection;
@ -1215,6 +1179,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, bool fixup) const
pos += separator.size(); pos += separator.size();
sectionNodes[index].pos = pos; sectionNodes[index].pos = pos;
int *current = nullptr; int *current = nullptr;
int zoneOffset; // Needed to serve as *current when setting zone
const SectionNode sn = sectionNodes.at(index); const SectionNode sn = sectionNodes.at(index);
ParsedSection sect; ParsedSection sect;
@ -1222,12 +1187,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, bool fixup) const
const QDate date = actualDate(isSet, calendar, year, year2digits, const QDate date = actualDate(isSet, calendar, year, year2digits,
month, day, dayofweek); month, day, dayofweek);
const QTime time = actualTime(isSet, hour, hour12, ampm, minute, second, msec); const QTime time = actualTime(isSet, hour, hour12, ampm, minute, second, msec);
sect = parseSection( sect = parseSection(QDateTime(date, time, timeZone), index, pos);
#if QT_CONFIG(timezone)
tspec == Qt::TimeZone ? QDateTime(date, time, timeZone) :
#endif
QDateTime(date, time, tspec, zoneOffset),
index, pos);
} }
QDTPDEBUG << "sectionValue" << sn.name() << m_text QDTPDEBUG << "sectionValue" << sn.name() << m_text
@ -1262,15 +1222,18 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, bool fixup) const
const bool isUtc = zoneName == "Z"_L1 || zoneName == "UTC"_L1; const bool isUtc = zoneName == "Z"_L1 || zoneName == "UTC"_L1;
if (isUtc || isUtcOffset) { if (isUtc || isUtcOffset) {
tspec = sect.value ? Qt::OffsetFromUTC : Qt::UTC; timeZone = QTimeZone::fromSecondsAheadOfUtc(sect.value);
} else { } else {
#if QT_CONFIG(timezone) #if QT_CONFIG(timezone)
timeZone = QTimeZone(zoneName.toLatin1()); QTimeZone namedZone = QTimeZone(zoneName.toLatin1());
tspec = timeZone.isValid() if (namedZone.isValid()) {
? Qt::TimeZone timeZone = namedZone;
: (Q_ASSERT(startsWithLocalTimeZone(zoneName)), Qt::LocalTime); } else {
Q_ASSERT(startsWithLocalTimeZone(zoneName));
timeZone = QTimeZone::LocalTime;
}
#else #else
tspec = Qt::LocalTime; timeZone = QTimeZone::LocalTime;
#endif #endif
} }
} }
@ -1412,11 +1375,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, bool fixup) const
const QDate date(year, month, day, calendar); const QDate date(year, month, day, calendar);
const QTime time(hour, minute, second, msec); const QTime time(hour, minute, second, msec);
const QDateTime when = const QDateTime when = QDateTime(date, time, timeZone);
#if QT_CONFIG(timezone)
tspec == Qt::TimeZone ? QDateTime(date, time, timeZone) :
#endif
QDateTime(date, time, tspec, zoneOffset);
// If hour wasn't specified, check the default we're using exists on the // If hour wasn't specified, check the default we're using exists on the
// given date (which might be a spring-forward, skipping an hour). // given date (which might be a spring-forward, skipping an hour).
@ -1425,11 +1384,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, bool fixup) const
case QMetaType::QDateTime: { case QMetaType::QDateTime: {
qint64 msecs = when.toMSecsSinceEpoch(); qint64 msecs = when.toMSecsSinceEpoch();
// Fortunately, that gets a useful answer, even though when is invalid ... // Fortunately, that gets a useful answer, even though when is invalid ...
const QDateTime replace = const QDateTime replace = QDateTime::fromMSecsSinceEpoch(msecs, timeZone);
#if QT_CONFIG(timezone)
tspec == Qt::TimeZone ? QDateTime::fromMSecsSinceEpoch(msecs, timeZone) :
#endif
QDateTime::fromMSecsSinceEpoch(msecs, tspec, zoneOffset);
const QTime tick = replace.time(); const QTime tick = replace.time();
if (replace.date() == date if (replace.date() == date
&& (!(isSet & MinuteSection) || tick.minute() == minute) && (!(isSet & MinuteSection) || tick.minute() == minute)
@ -1440,11 +1395,11 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, bool fixup) const
} break; } break;
case QMetaType::QDate: case QMetaType::QDate:
// Don't care about time, so just use start of day (and ignore spec): // Don't care about time, so just use start of day (and ignore spec):
return StateNode(date.startOfDay(Qt::UTC), state, padding, conflicts); return StateNode(date.startOfDay(QTimeZone::UTC), state, padding, conflicts);
break; break;
case QMetaType::QTime: case QMetaType::QTime:
// Don't care about date or spec, so pick a safe spec: // Don't care about date or representation, so pick a safe representation:
return StateNode(QDateTime(date, time, Qt::UTC), state, padding, conflicts); return StateNode(QDateTime(date, time, QTimeZone::UTC), state, padding, conflicts);
default: default:
Q_UNREACHABLE_RETURN(StateNode()); Q_UNREACHABLE_RETURN(StateNode());
} }
@ -2192,7 +2147,7 @@ QString QDateTimeParser::stateName(State s) const
// Only called when we want only one of date or time; use UTC to avoid bogus DST issues. // Only called when we want only one of date or time; use UTC to avoid bogus DST issues.
bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) const bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) const
{ {
QDateTime val(QDate(1900, 1, 1).startOfDay(Qt::UTC)); QDateTime val(QDate(1900, 1, 1).startOfDay(QTimeZone::UTC));
const StateNode tmp = parse(t, -1, val, false); const StateNode tmp = parse(t, -1, val, false);
if (tmp.state != Acceptable || tmp.conflicts) if (tmp.state != Acceptable || tmp.conflicts)
return false; return false;
@ -2232,7 +2187,7 @@ QDateTime QDateTimeParser::getMinimum() const
// method. At the time of writing, this is done by QDateTimeEditPrivate. // method. At the time of writing, this is done by QDateTimeEditPrivate.
// Cache the only case // Cache the only case
static const QDateTime localTimeMin(QDATETIMEEDIT_DATE_MIN.startOfDay(Qt::LocalTime)); static const QDateTime localTimeMin(QDATETIMEEDIT_DATE_MIN.startOfDay());
return localTimeMin; return localTimeMin;
} }
@ -2243,7 +2198,7 @@ QDateTime QDateTimeParser::getMaximum() const
// method. At the time of writing, this is done by QDateTimeEditPrivate. // method. At the time of writing, this is done by QDateTimeEditPrivate.
// Cache the only case // Cache the only case
static const QDateTime localTimeMax(QDATETIMEEDIT_DATE_MAX.endOfDay(Qt::LocalTime)); static const QDateTime localTimeMax(QDATETIMEEDIT_DATE_MAX.endOfDay());
return localTimeMax; return localTimeMax;
} }

View File

@ -331,7 +331,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
For example, for time zone "Europe/Berlin" the OffsetDate in standard and DST might be: For example, for time zone "Europe/Berlin" the OffsetDate in standard and DST might be:
\list \list
\li atUtc = QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC) \li atUtc = QDateTime(QDate(2013, 1, 1), QTime(0, 0), QTimeZone::UTC)
\li offsetFromUtc = 3600 \li offsetFromUtc = 3600
\li standardTimeOffset = 3600 \li standardTimeOffset = 3600
\li daylightTimeOffset = 0 \li daylightTimeOffset = 0
@ -339,7 +339,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
\endlist \endlist
\list \list
\li atUtc = QDateTime(QDate(2013, 6, 1), QTime(0, 0, 0), Qt::UTC) \li atUtc = QDateTime(QDate(2013, 6, 1), QTime(0, 0), QTimeZone::UTC)
\li offsetFromUtc = 7200 \li offsetFromUtc = 7200
\li standardTimeOffset = 3600 \li standardTimeOffset = 3600
\li daylightTimeOffset = 3600 \li daylightTimeOffset = 3600
@ -1584,7 +1584,7 @@ QDataStream &operator>>(QDataStream &ds, QTimeZone &tz)
// zone, with the right offset, ignoring the other data: // zone, with the right offset, ignoring the other data:
tz = QTimeZone(ianaId.toUtf8()); tz = QTimeZone(ianaId.toUtf8());
if (!tz.isValid() || tz.hasDaylightTime() if (!tz.isValid() || tz.hasDaylightTime()
|| tz.offsetFromUtc(QDateTime::fromMSecsSinceEpoch(0, Qt::UTC)) != utcOffset) { || tz.offsetFromUtc(QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC)) != utcOffset) {
// Construct a custom timezone using the saved values: // Construct a custom timezone using the saved values:
tz = QTimeZone(ianaId.toUtf8(), utcOffset, name, abbreviation, tz = QTimeZone(ianaId.toUtf8(), utcOffset, name, abbreviation,
QLocale::Territory(territory), comment); QLocale::Territory(territory), comment);

View File

@ -527,7 +527,7 @@ QTimeZone::OffsetData QTimeZonePrivate::toOffsetData(const QTimeZonePrivate::Dat
{ {
QTimeZone::OffsetData offsetData = invalidOffsetData(); QTimeZone::OffsetData offsetData = invalidOffsetData();
if (data.atMSecsSinceEpoch != invalidMSecs()) { if (data.atMSecsSinceEpoch != invalidMSecs()) {
offsetData.atUtc = QDateTime::fromMSecsSinceEpoch(data.atMSecsSinceEpoch, Qt::UTC); offsetData.atUtc = QDateTime::fromMSecsSinceEpoch(data.atMSecsSinceEpoch, QTimeZone::UTC);
offsetData.offsetFromUtc = data.offsetFromUtc; offsetData.offsetFromUtc = data.offsetFromUtc;
offsetData.standardTimeOffset = data.standardTimeOffset; offsetData.standardTimeOffset = data.standardTimeOffset;
offsetData.daylightTimeOffset = data.daylightTimeOffset; offsetData.daylightTimeOffset = data.daylightTimeOffset;

View File

@ -631,20 +631,22 @@ static QList<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray
Q_ASSERT(startYear <= endYear); Q_ASSERT(startYear <= endYear);
for (int year = startYear; year <= endYear; ++year) { for (int year = startYear; year <= endYear; ++year) {
// Note: std and dst, despite being QDateTime(,, Qt::UTC), have the // Note: std and dst, despite being QDateTime(,, UTC), have the
// date() and time() of the *zone*'s description of the transition // date() and time() of the *zone*'s description of the transition
// moments; the atMSecsSinceEpoch values computed from them are // moments; the atMSecsSinceEpoch values computed from them are
// correctly offse to be UTC-based. // correctly offse to be UTC-based.
QTimeZonePrivate::Data dstData; // Transition to DST QTimeZonePrivate::Data dstData; // Transition to DST
QDateTime dst(calculatePosixDate(dstDateRule, year).startOfDay(Qt::UTC).addSecs(dstTime)); QDateTime dst(calculatePosixDate(dstDateRule, year)
.startOfDay(QTimeZone::UTC).addSecs(dstTime));
dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - stdZone.offset * 1000; dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - stdZone.offset * 1000;
dstData.offsetFromUtc = dstZone.offset; dstData.offsetFromUtc = dstZone.offset;
dstData.standardTimeOffset = stdZone.offset; dstData.standardTimeOffset = stdZone.offset;
dstData.daylightTimeOffset = dstZone.offset - stdZone.offset; dstData.daylightTimeOffset = dstZone.offset - stdZone.offset;
dstData.abbreviation = dstZone.name; dstData.abbreviation = dstZone.name;
QTimeZonePrivate::Data stdData; // Transition to standard time QTimeZonePrivate::Data stdData; // Transition to standard time
QDateTime std(calculatePosixDate(stdDateRule, year).startOfDay(Qt::UTC).addSecs(stdTime)); QDateTime std(calculatePosixDate(stdDateRule, year)
.startOfDay(QTimeZone::UTC).addSecs(stdTime));
stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - dstZone.offset * 1000; stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - dstZone.offset * 1000;
stdData.offsetFromUtc = stdZone.offset; stdData.offsetFromUtc = stdZone.offset;
stdData.standardTimeOffset = stdZone.offset; stdData.standardTimeOffset = stdZone.offset;
@ -655,16 +657,16 @@ static QList<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray
// Handle the special case of fixed state, which may be represented // Handle the special case of fixed state, which may be represented
// by fake transitions at start and end of each year: // by fake transitions at start and end of each year:
if (dstData.atMSecsSinceEpoch < stdData.atMSecsSinceEpoch) { if (dstData.atMSecsSinceEpoch < stdData.atMSecsSinceEpoch) {
if (dst <= QDate(year, 1, 1).startOfDay(Qt::UTC) if (dst <= QDate(year, 1, 1).startOfDay(QTimeZone::UTC)
&& std >= QDate(year, 12, 31).endOfDay(Qt::UTC)) { && std >= QDate(year, 12, 31).endOfDay(QTimeZone::UTC)) {
// Permanent DST: // Permanent DST:
dstData.atMSecsSinceEpoch = lastTranMSecs; dstData.atMSecsSinceEpoch = lastTranMSecs;
result << dstData; result << dstData;
return result; return result;
} }
} else { } else {
if (std <= QDate(year, 1, 1).startOfDay(Qt::UTC) if (std <= QDate(year, 1, 1).startOfDay(QTimeZone::UTC)
&& dst >= QDate(year, 12, 31).endOfDay(Qt::UTC)) { && dst >= QDate(year, 12, 31).endOfDay(QTimeZone::UTC)) {
// Permanent Standard time, perversely described: // Permanent Standard time, perversely described:
stdData.atMSecsSinceEpoch = lastTranMSecs; stdData.atMSecsSinceEpoch = lastTranMSecs;
result << stdData; result << stdData;
@ -1093,7 +1095,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::dataFromRule(QTzTransitionRule rule,
QList<QTimeZonePrivate::Data> QTzTimeZonePrivate::getPosixTransitions(qint64 msNear) const QList<QTimeZonePrivate::Data> QTzTimeZonePrivate::getPosixTransitions(qint64 msNear) const
{ {
const int year = QDateTime::fromMSecsSinceEpoch(msNear, Qt::UTC).date().year(); const int year = QDateTime::fromMSecsSinceEpoch(msNear, QTimeZone::UTC).date().year();
// The Data::atMSecsSinceEpoch of the single entry if zone is constant: // The Data::atMSecsSinceEpoch of the single entry if zone is constant:
qint64 atTime = tranCache().isEmpty() ? msNear : tranCache().last().atMSecsSinceEpoch; qint64 atTime = tranCache().isEmpty() ? msNear : tranCache().last().atMSecsSinceEpoch;
return calculatePosixTransitions(cached_data.m_posixRule, year - 1, year + 1, atTime); return calculatePosixTransitions(cached_data.m_posixRule, year - 1, year + 1, atTime);

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QTest> #include <QTest>
#include <QtCore/QDateTime>
#include <QtCore/private/qfilesystemmetadata_p.h> #include <QtCore/private/qfilesystemmetadata_p.h>
class tst_QFileSystemMetaData : public QObject class tst_QFileSystemMetaData : public QObject
@ -42,14 +43,14 @@ void tst_QFileSystemMetaData::timeSinceEpoch()
data.ftCreationTime = epochToFileTime(afterEpochUtc); data.ftCreationTime = epochToFileTime(afterEpochUtc);
meta.fillFromFindData(data); meta.fillFromFindData(data);
QCOMPARE(meta.birthTime().toUTC(), QCOMPARE(meta.birthTime().toUTC(),
QDateTime::fromMSecsSinceEpoch(afterEpochUtc * qint64(1000), Qt::UTC)); QDateTime::fromMSecsSinceEpoch(afterEpochUtc * qint64(1000), QTimeZone::UTC));
#else #else
QT_STATBUF data; QT_STATBUF data;
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.st_ctime = afterEpochUtc; data.st_ctime = afterEpochUtc;
meta.fillFromStatBuf(data); meta.fillFromStatBuf(data);
QCOMPARE(meta.metadataChangeTime().toUTC(), QCOMPARE(meta.metadataChangeTime().toUTC(),
QDateTime::fromMSecsSinceEpoch(afterEpochUtc * qint64(1000), Qt::UTC)); QDateTime::fromMSecsSinceEpoch(afterEpochUtc * qint64(1000), QTimeZone::UTC));
#endif #endif
} }
#else // i.e. no Q_AUTOTEST_EXPORT #else // i.e. no Q_AUTOTEST_EXPORT

View File

@ -1328,7 +1328,7 @@ void tst_QSettings::testVariantTypes()
testValue("collectList", l4, QVariantList); testValue("collectList", l4, QVariantList);
QDateTime dt = QDateTime::currentDateTime(); QDateTime dt = QDateTime::currentDateTime();
dt.setOffsetFromUtc(3600); dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(3600));
testValue("dateTime", dt, QDateTime); testValue("dateTime", dt, QDateTime);
#if QT_CONFIG(shortcut) #if QT_CONFIG(shortcut)

View File

@ -29,6 +29,7 @@
#include <QSequentialIterable> #include <QSequentialIterable>
#include <QSet> #include <QSet>
#include <QStack> #include <QStack>
#include <QTimeZone>
#include <QtNumeric> #include <QtNumeric>
#include <QUrl> #include <QUrl>
#include <QUuid> #include <QUuid>
@ -1280,8 +1281,9 @@ void tst_QVariant::toDateTime_data()
<< QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ); << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) );
QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 10, 10 ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 0, 0, 0 ) ); QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 10, 10 ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 0, 0, 0 ) );
QTest::newRow( "qstring" ) << QVariant( QString( "2002-10-10T12:34:56" ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ); QTest::newRow( "qstring" ) << QVariant( QString( "2002-10-10T12:34:56" ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) );
QTest::newRow( "qstring-utc" ) << QVariant( QString( "2002-10-10T12:34:56Z" ) ) QTest::newRow("qstring-utc")
<< QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ), Qt::UTC ); << QVariant(QString("2002-10-10T12:34:56Z"))
<< QDateTime(QDate(2002, 10, 10), QTime(12, 34, 56), QTimeZone::UTC);
QTest::newRow( "qstring-with-ms" ) << QVariant( QString( "2002-10-10T12:34:56.789" ) ) QTest::newRow( "qstring-with-ms" ) << QVariant( QString( "2002-10-10T12:34:56.789" ) )
<< QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56, 789 ) ); << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56, 789 ) );
} }

View File

@ -3,10 +3,13 @@
#include <QtCore/qcborvalue.h> #include <QtCore/qcborvalue.h>
#include <QTest> #include <QTest>
#include <QBuffer> #include <QBuffer>
#include <QCborStreamReader> #include <QCborStreamReader>
#include <QCborStreamWriter> #include <QCborStreamWriter>
#include <QDateTime>
#include <QtEndian> #include <QtEndian>
#include <QTimeZone>
#include <QtCore/private/qbytearray_p.h> #include <QtCore/private/qbytearray_p.h>
@ -389,7 +392,7 @@ void tst_QCborValue::extendedTypes_data()
QTest::addColumn<QCborValue>("correctedTaggedValue"); QTest::addColumn<QCborValue>("correctedTaggedValue");
QCborValue v(QCborValue::Invalid); QCborValue v(QCborValue::Invalid);
QDateTime dt = QDateTime::currentDateTimeUtc(); QDateTime dt = QDateTime::currentDateTimeUtc();
QDateTime dtTzOffset(dt.date(), dt.time(), Qt::OffsetFromUTC, dt.offsetFromUtc()); QDateTime dtTzOffset(dt.date(), dt.time(), QTimeZone::fromSecondsAheadOfUtc(dt.offsetFromUtc()));
QUuid uuid = QUuid::createUuid(); QUuid uuid = QUuid::createUuid();
// non-correcting extended types (tagged value remains unchanged) // non-correcting extended types (tagged value remains unchanged)
@ -413,7 +416,7 @@ void tst_QCborValue::extendedTypes_data()
<< QCborKnownTags::Uuid << QCborValue(uuid.toRfc4122()) << v; << QCborKnownTags::Uuid << QCborValue(uuid.toRfc4122()) << v;
// correcting extended types // correcting extended types
QDateTime dtNoMsecs = dt.fromSecsSinceEpoch(dt.toSecsSinceEpoch(), Qt::UTC); QDateTime dtNoMsecs = dt.fromSecsSinceEpoch(dt.toSecsSinceEpoch(), QTimeZone::UTC);
QUrl url("https://example.com/\xc2\xa9 "); QUrl url("https://example.com/\xc2\xa9 ");
QTest::newRow("UnixTime_t:Integer") << QCborValue(dtNoMsecs) << QCborKnownTags::UnixTime_t QTest::newRow("UnixTime_t:Integer") << QCborValue(dtNoMsecs) << QCborKnownTags::UnixTime_t
<< QCborValue(dtNoMsecs.toSecsSinceEpoch()) << QCborValue(dtNoMsecs.toSecsSinceEpoch())
@ -424,7 +427,8 @@ void tst_QCborValue::extendedTypes_data()
QTest::newRow("DateTime::JustDate") << QCborValue(QDateTime({2018, 1, 1}, {})) QTest::newRow("DateTime::JustDate") << QCborValue(QDateTime({2018, 1, 1}, {}))
<< QCborKnownTags::DateTimeString << QCborKnownTags::DateTimeString
<< QCborValue("2018-01-01") << QCborValue("2018-01-01T00:00:00.000"); << QCborValue("2018-01-01") << QCborValue("2018-01-01T00:00:00.000");
QTest::newRow("DateTime::TzOffset") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::UTC)) QTest::newRow("DateTime::TzOffset")
<< QCborValue(QDateTime({2018, 1, 1}, {9, 0}, QTimeZone::UTC))
<< QCborKnownTags::DateTimeString << QCborKnownTags::DateTimeString
<< QCborValue("2018-01-01T09:00:00.000+00:00") << QCborValue("2018-01-01T09:00:00.000+00:00")
<< QCborValue("2018-01-01T09:00:00.000Z"); << QCborValue("2018-01-01T09:00:00.000Z");
@ -1797,7 +1801,8 @@ void tst_QCborValue::sorting()
QCborValue vs2("Hello"), vs3("World"), vs1("foo"); QCborValue vs2("Hello"), vs3("World"), vs1("foo");
QCborValue va1(QCborValue::Array), va2(QCborArray{1}), va3(QCborArray{0, 0}); QCborValue va1(QCborValue::Array), va2(QCborArray{1}), va3(QCborArray{0, 0});
QCborValue vm1(QCborValue::Map), vm2(QCborMap{{1, 0}}), vm3(QCborMap{{0, 0}, {1, 0}}); QCborValue vm1(QCborValue::Map), vm2(QCborMap{{1, 0}}), vm3(QCborMap{{0, 0}, {1, 0}});
QCborValue vdt1(QDateTime::fromMSecsSinceEpoch(0, Qt::UTC)), vdt2(QDateTime::currentDateTimeUtc()); QCborValue vdt1(QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC));
QCborValue vdt2(QDateTime::currentDateTimeUtc());
QCborValue vtagged1(QCborKnownTags::PositiveBignum, QByteArray()), QCborValue vtagged1(QCborKnownTags::PositiveBignum, QByteArray()),
vtagged2(QCborKnownTags::PositiveBignum, 0.0), // bignums are supposed to have byte arrays... vtagged2(QCborKnownTags::PositiveBignum, 0.0), // bignums are supposed to have byte arrays...
vtagged3(QCborKnownTags::Signature, 0), vtagged3(QCborKnownTags::Signature, 0),
@ -1954,13 +1959,14 @@ static void addCommonCborData()
QTest::newRow("DateTime") << QCborValue(dt) // this is UTC QTest::newRow("DateTime") << QCborValue(dt) // this is UTC
<< "\xc0\x78\x18" + dt.toString(Qt::ISODateWithMs).toLatin1() << "\xc0\x78\x18" + dt.toString(Qt::ISODateWithMs).toLatin1()
<< noxfrm; << noxfrm;
QTest::newRow("DateTime-UTC") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::UTC)) QTest::newRow("DateTime-UTC") << QCborValue(QDateTime({2018, 1, 1}, {9, 0}, QTimeZone::UTC))
<< raw("\xc0\x78\x18" "2018-01-01T09:00:00.000Z") << raw("\xc0\x78\x18" "2018-01-01T09:00:00.000Z")
<< noxfrm; << noxfrm;
QTest::newRow("DateTime-Local") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::LocalTime)) QTest::newRow("DateTime-Local") << QCborValue(QDateTime({2018, 1, 1}, {9, 0}))
<< raw("\xc0\x77" "2018-01-01T09:00:00.000") << raw("\xc0\x77" "2018-01-01T09:00:00.000")
<< noxfrm; << noxfrm;
QTest::newRow("DateTime+01:00") << QCborValue(QDateTime({2018, 1, 1}, {9, 0, 0}, Qt::OffsetFromUTC, 3600)) QTest::newRow("DateTime+01:00")
<< QCborValue(QDateTime({2018, 1, 1}, {9, 0}, QTimeZone::fromSecondsAheadOfUtc(3600)))
<< raw("\xc0\x78\x1d" "2018-01-01T09:00:00.000+01:00") << raw("\xc0\x78\x1d" "2018-01-01T09:00:00.000+01:00")
<< noxfrm; << noxfrm;
QTest::newRow("Url:Empty") << QCborValue(QUrl()) << raw("\xd8\x20\x60") << noxfrm; QTest::newRow("Url:Empty") << QCborValue(QUrl()) << raw("\xd8\x20\x60") << noxfrm;
@ -2070,20 +2076,28 @@ void tst_QCborValue::fromCbor_data()
QTest::newRow("String:Chunked:Empty") << QCborValue(QString()) QTest::newRow("String:Chunked:Empty") << QCborValue(QString())
<< raw("\x7f\xff"); << raw("\x7f\xff");
QTest::newRow("DateTime:NoMilli") << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, Qt::UTC)) QTest::newRow("DateTime:NoMilli")
<< QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, QTimeZone::UTC))
<< raw("\xc0\x74" "2018-01-10T06:24:37Z"); << raw("\xc0\x74" "2018-01-10T06:24:37Z");
// date-only is only permitted local time // date-only is only permitted local time
QTest::newRow("DateTime:NoTime:Local") << QCborValue(QDateTime(QDate(2020, 4, 15), QTime(0, 0), Qt::LocalTime)) QTest::newRow("DateTime:NoTime:Local")
<< QCborValue(QDateTime(QDate(2020, 4, 15), QTime(0, 0)))
<< raw("\xc0\x6a" "2020-04-15"); << raw("\xc0\x6a" "2020-04-15");
QTest::newRow("DateTime:24:00:00") << QCborValue(QDateTime(QDate(2020, 4, 16), QTime(0, 0), Qt::UTC)) QTest::newRow("DateTime:24:00:00")
<< QCborValue(QDateTime(QDate(2020, 4, 16), QTime(0, 0), QTimeZone::UTC))
<< raw("\xc0\x74" "2020-04-15T24:00:00Z"); << raw("\xc0\x74" "2020-04-15T24:00:00Z");
QTest::newRow("DateTime:+00:00") << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, Qt::UTC)) QTest::newRow("DateTime:+00:00")
<< QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, QTimeZone::UTC))
<< raw("\xc0\x78\x1d" "2018-01-10T06:24:37.125+00:00"); << raw("\xc0\x78\x1d" "2018-01-10T06:24:37.125+00:00");
QTest::newRow("DateTime:+01:00") << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, Qt::OffsetFromUTC, 60*60)) QTest::newRow("DateTime:+01:00")
<< QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125,
QTimeZone::fromSecondsAheadOfUtc(60 * 60)))
<< raw("\xc0\x78\x1d" "2018-01-10T07:24:37.125+01:00"); << raw("\xc0\x78\x1d" "2018-01-10T07:24:37.125+01:00");
QTest::newRow("UnixTime_t:Integer") << QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, Qt::UTC)) QTest::newRow("UnixTime_t:Integer")
<< QCborValue(QDateTime::fromSecsSinceEpoch(1515565477, QTimeZone::UTC))
<< raw("\xc1\x1a\x5a\x55\xb1\xa5"); << raw("\xc1\x1a\x5a\x55\xb1\xa5");
QTest::newRow("UnixTime_t:Double") << QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, Qt::UTC)) QTest::newRow("UnixTime_t:Double")
<< QCborValue(QDateTime::fromMSecsSinceEpoch(1515565477125, QTimeZone::UTC))
<< raw("\xc1\xfb\x41\xd6\x95\x6c""\x69\x48\x00\x00"); << raw("\xc1\xfb\x41\xd6\x95\x6c""\x69\x48\x00\x00");
QTest::newRow("Url:NotNormalized") << QCborValue(QUrl("https://example.com/\xc2\xa9 ")) QTest::newRow("Url:NotNormalized") << QCborValue(QUrl("https://example.com/\xc2\xa9 "))
@ -2291,7 +2305,7 @@ void tst_QCborValue::extendedTypeValidation_data()
// representation, which means it can't represent dates before year 1 or // representation, which means it can't represent dates before year 1 or
// after year 9999. // after year 9999.
{ {
QDateTime dt(QDate(-1, 1, 1), QTime(0, 0), Qt::UTC); QDateTime dt(QDate(-1, 1, 1), QTime(0, 0), QTimeZone::UTC);
QTest::newRow("UnixTime_t:negative-year") QTest::newRow("UnixTime_t:negative-year")
<< encode(0xc1, 0x3b, quint64(-dt.toSecsSinceEpoch()) - 1) << encode(0xc1, 0x3b, quint64(-dt.toSecsSinceEpoch()) - 1)
<< QCborValue(QCborKnownTags::UnixTime_t, dt.toSecsSinceEpoch()); << QCborValue(QCborKnownTags::UnixTime_t, dt.toSecsSinceEpoch());
@ -2932,7 +2946,7 @@ void tst_QCborValue::debugOutput_data()
QTest::addColumn<QCborValue>("v"); QTest::addColumn<QCborValue>("v");
QTest::addColumn<QString>("expected"); QTest::addColumn<QString>("expected");
QDateTime dt(QDate(2020, 4, 18), QTime(13, 41, 22, 123), Qt::UTC); QDateTime dt(QDate(2020, 4, 18), QTime(13, 41, 22, 123), QTimeZone::UTC);
QBitArray bits = QBitArray::fromBits("\x79\x03", 11); QBitArray bits = QBitArray::fromBits("\x79\x03", 11);
QTest::newRow("Undefined") << QCborValue() << "QCborValue()"; QTest::newRow("Undefined") << QCborValue() << "QCborValue()";

View File

@ -13,9 +13,7 @@
# include <QProcess> # include <QProcess>
#endif #endif
#include <QScopedArrayPointer> #include <QScopedArrayPointer>
#if QT_CONFIG(timezone)
#include <QTimeZone> #include <QTimeZone>
#endif
#include <private/qlocale_p.h> #include <private/qlocale_p.h>
#include <private/qlocale_tools_p.h> #include <private/qlocale_tools_p.h>
@ -1935,26 +1933,26 @@ void tst_QLocale::formatTimeZone()
{ {
QLocale enUS("en_US"); QLocale enUS("en_US");
QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, 60 * 60); QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0), QTimeZone::fromSecondsAheadOfUtc(60 * 60));
QCOMPARE(enUS.toString(dt1, "t"), QLatin1String("UTC+01:00")); QCOMPARE(enUS.toString(dt1, "t"), QLatin1String("UTC+01:00"));
QDateTime dt2(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, -60 * 60); QDateTime dt2(QDate(2013, 1, 1), QTime(1, 0), QTimeZone::fromSecondsAheadOfUtc(-60 * 60));
QCOMPARE(enUS.toString(dt2, "t"), QLatin1String("UTC-01:00")); QCOMPARE(enUS.toString(dt2, "t"), QLatin1String("UTC-01:00"));
QDateTime dt3(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC); QDateTime dt3(QDate(2013, 1, 1), QTime(0, 0), QTimeZone::UTC);
QCOMPARE(enUS.toString(dt3, "t"), QLatin1String("UTC")); QCOMPARE(enUS.toString(dt3, "t"), QLatin1String("UTC"));
// LocalTime should vary // LocalTime should vary
if (europeanTimeZone) { if (europeanTimeZone) {
// Time definitely in Standard Time // Time definitely in Standard Time
QDateTime dt4(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::LocalTime); QDateTime dt4 = QDate(2013, 1, 1).startOfDay();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QEXPECT_FAIL("", "Windows only returns long name (QTBUG-32759)", Continue); QEXPECT_FAIL("", "Windows only returns long name (QTBUG-32759)", Continue);
#endif // Q_OS_WIN #endif // Q_OS_WIN
QCOMPARE(enUS.toString(dt4, "t"), QLatin1String("CET")); QCOMPARE(enUS.toString(dt4, "t"), QLatin1String("CET"));
// Time definitely in Daylight Time // Time definitely in Daylight Time
QDateTime dt5(QDate(2013, 6, 1), QTime(0, 0, 0), Qt::LocalTime); QDateTime dt5 = QDate(2013, 6, 1).startOfDay();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QEXPECT_FAIL("", "Windows only returns long name (QTBUG-32759)", Continue); QEXPECT_FAIL("", "Windows only returns long name (QTBUG-32759)", Continue);
#endif // Q_OS_WIN #endif // Q_OS_WIN
@ -2051,7 +2049,7 @@ void tst_QLocale::toDateTime_data()
<< u"ddd, d MMM yyyy HH:mm:ss t"_s << u"Sun, 29 Mar 2020 02:26:3 Z"_s << false; << u"ddd, d MMM yyyy HH:mm:ss t"_s << u"Sun, 29 Mar 2020 02:26:3 Z"_s << false;
QTest::newRow("s-Z") // Same, but with a format that accepts the single digit: QTest::newRow("s-Z") // Same, but with a format that accepts the single digit:
<< "C" << QDateTime(QDate(2020, 3, 29), QTime(2, 26, 3), Qt::UTC) << "C" << QDateTime(QDate(2020, 3, 29), QTime(2, 26, 3), QTimeZone::UTC)
<< u"ddd, d MMM yyyy HH:mm:s t"_s << u"Sun, 29 Mar 2020 02:26:3 Z"_s << false; << u"ddd, d MMM yyyy HH:mm:s t"_s << u"Sun, 29 Mar 2020 02:26:3 Z"_s << false;
QTest::newRow("RFC-1123") QTest::newRow("RFC-1123")

View File

@ -2,14 +2,14 @@
// Copyright (C) 2016 Intel Corporation. // Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <private/qglobal_p.h> // for the icu feature test #include <QDateTime>
#include <QTest> #include <QTest>
#if QT_CONFIG(timezone)
#include <QTimeZone> #include <QLocale>
#endif
#include <qdatetime.h>
#include <qlocale.h>
#include <QMap> #include <QMap>
#include <QTimeZone>
#include <private/qglobal_p.h> // for the icu feature test
class tst_QDate : public QObject class tst_QDate : public QObject
{ {
@ -527,7 +527,7 @@ void tst_QDate::startOfDay_endOfDay()
QFETCH(QByteArray, zoneName); QFETCH(QByteArray, zoneName);
QFETCH(QTime, start); QFETCH(QTime, start);
QFETCH(QTime, end); QFETCH(QTime, end);
const QTimeZone zone(zoneName); const auto zone = QTimeZone(zoneName);
QVERIFY(zone.isValid()); QVERIFY(zone.isValid());
const bool isSystem = QTimeZone::systemTimeZone() == zone; const bool isSystem = QTimeZone::systemTimeZone() == zone;
QDateTime front(date.startOfDay(zone)), back(date.endOfDay(zone)); QDateTime front(date.startOfDay(zone)), back(date.endOfDay(zone));
@ -546,13 +546,13 @@ void tst_QDate::startOfDay_endOfDay()
} }
if (front.timeSpec() == Qt::LocalTime) if (front.timeSpec() == Qt::LocalTime)
break; break;
front = date.startOfDay(Qt::LocalTime); front = date.startOfDay();
back = date.endOfDay(Qt::LocalTime); back = date.endOfDay();
} while (isSystem); } while (isSystem);
if (end.isValid()) if (end.isValid())
QCOMPARE(date.addDays(1).startOfDay(Qt::LocalTime).addMSecs(-1), back); QCOMPARE(date.addDays(1).startOfDay().addMSecs(-1), back);
if (start.isValid()) if (start.isValid())
QCOMPARE(date.addDays(-1).endOfDay(Qt::LocalTime).addMSecs(1), front); QCOMPARE(date.addDays(-1).endOfDay().addMSecs(1), front);
if (!isSystem) { if (!isSystem) {
// These might fail if system zone coincides with zone; but only if it // These might fail if system zone coincides with zone; but only if it
// did something similarly unusual on the date picked for this test. // did something similarly unusual on the date picked for this test.
@ -572,12 +572,13 @@ void tst_QDate::startOfDay_endOfDay_fixed_data()
{ {
const qint64 kilo(1000); const qint64 kilo(1000);
using Bounds = std::numeric_limits<qint64>; using Bounds = std::numeric_limits<qint64>;
const auto UTC = QTimeZone::UTC;
const QDateTime const QDateTime
first(QDateTime::fromMSecsSinceEpoch(Bounds::min() + 1, Qt::UTC)), first(QDateTime::fromMSecsSinceEpoch(Bounds::min() + 1, UTC)),
start32sign(QDateTime::fromMSecsSinceEpoch(Q_INT64_C(-0x80000000) * kilo, Qt::UTC)), start32sign(QDateTime::fromMSecsSinceEpoch(Q_INT64_C(-0x80000000) * kilo, UTC)),
end32sign(QDateTime::fromMSecsSinceEpoch(Q_INT64_C(0x80000000) * kilo, Qt::UTC)), end32sign(QDateTime::fromMSecsSinceEpoch(Q_INT64_C(0x80000000) * kilo, UTC)),
end32unsign(QDateTime::fromMSecsSinceEpoch(Q_INT64_C(0x100000000) * kilo, Qt::UTC)), end32unsign(QDateTime::fromMSecsSinceEpoch(Q_INT64_C(0x100000000) * kilo, UTC)),
last(QDateTime::fromMSecsSinceEpoch(Bounds::max(), Qt::UTC)); last(QDateTime::fromMSecsSinceEpoch(Bounds::max(), UTC));
const struct { const struct {
const char *name; const char *name;
@ -605,28 +606,29 @@ void tst_QDate::startOfDay_endOfDay_fixed()
const QTime early(0, 0), late(23, 59, 59, 999); const QTime early(0, 0), late(23, 59, 59, 999);
QFETCH(QDate, date); QFETCH(QDate, date);
QDateTime start(date.startOfDay(Qt::UTC)); QDateTime start(date.startOfDay(QTimeZone::UTC));
QDateTime end(date.endOfDay(Qt::UTC)); QDateTime end(date.endOfDay(QTimeZone::UTC));
QCOMPARE(start.date(), date); QCOMPARE(start.date(), date);
QCOMPARE(end.date(), date); QCOMPARE(end.date(), date);
QCOMPARE(start.time(), early); QCOMPARE(start.time(), early);
QCOMPARE(end.time(), late); QCOMPARE(end.time(), late);
QCOMPARE(date.addDays(1).startOfDay(Qt::UTC).addMSecs(-1), end); QCOMPARE(date.addDays(1).startOfDay(QTimeZone::UTC).addMSecs(-1), end);
QCOMPARE(date.addDays(-1).endOfDay(Qt::UTC).addMSecs(1), start); QCOMPARE(date.addDays(-1).endOfDay(QTimeZone::UTC).addMSecs(1), start);
for (int offset = -60 * 16; offset <= 60 * 16; offset += 65) { for (int offset = -60 * 16; offset <= 60 * 16; offset += 65) {
start = date.startOfDay(Qt::OffsetFromUTC, offset); const auto zone = QTimeZone::fromSecondsAheadOfUtc(offset);
end = date.endOfDay(Qt::OffsetFromUTC, offset); start = date.startOfDay(zone);
end = date.endOfDay(zone);
QCOMPARE(start.date(), date); QCOMPARE(start.date(), date);
QCOMPARE(end.date(), date); QCOMPARE(end.date(), date);
QCOMPARE(start.time(), early); QCOMPARE(start.time(), early);
QCOMPARE(end.time(), late); QCOMPARE(end.time(), late);
QCOMPARE(date.addDays(1).startOfDay(Qt::OffsetFromUTC, offset).addMSecs(-1), end); QCOMPARE(date.addDays(1).startOfDay(zone).addMSecs(-1), end);
QCOMPARE(date.addDays(-1).endOfDay(Qt::OffsetFromUTC, offset).addMSecs(1), start); QCOMPARE(date.addDays(-1).endOfDay(zone).addMSecs(1), start);
} }
// Minimal testing for LocalTime and TimeZone // Minimal testing for LocalTime and TimeZone
QCOMPARE(date.startOfDay(Qt::LocalTime).date(), date); QCOMPARE(date.startOfDay().date(), date);
QCOMPARE(date.endOfDay(Qt::LocalTime).date(), date); QCOMPARE(date.endOfDay().date(), date);
#if QT_CONFIG(timezone) #if QT_CONFIG(timezone)
const QTimeZone cet("Europe/Oslo"); const QTimeZone cet("Europe/Oslo");
if (cet.isValid()) { if (cet.isValid()) {
@ -640,10 +642,11 @@ void tst_QDate::startOfDay_endOfDay_bounds()
{ {
// Check the days in which QDateTime's range starts and ends: // Check the days in which QDateTime's range starts and ends:
using Bounds = std::numeric_limits<qint64>; using Bounds = std::numeric_limits<qint64>;
const auto UTC = QTimeZone::UTC;
const QDateTime const QDateTime
first(QDateTime::fromMSecsSinceEpoch(Bounds::min(), Qt::UTC)), first(QDateTime::fromMSecsSinceEpoch(Bounds::min(), UTC)),
last(QDateTime::fromMSecsSinceEpoch(Bounds::max(), Qt::UTC)), last(QDateTime::fromMSecsSinceEpoch(Bounds::max(), UTC)),
epoch(QDateTime::fromMSecsSinceEpoch(0, Qt::UTC)); epoch(QDateTime::fromMSecsSinceEpoch(0, UTC));
// First, check these *are* the start and end of QDateTime's range: // First, check these *are* the start and end of QDateTime's range:
QVERIFY(first.isValid()); QVERIFY(first.isValid());
QVERIFY(last.isValid()); QVERIFY(last.isValid());
@ -654,15 +657,15 @@ void tst_QDate::startOfDay_endOfDay_bounds()
QVERIFY(!last.addMSecs(1).isValid() || last.addMSecs(1) < last); QVERIFY(!last.addMSecs(1).isValid() || last.addMSecs(1) < last);
// Now test start/end methods with them: // Now test start/end methods with them:
QCOMPARE(first.date().endOfDay(Qt::UTC).time(), QTime(23, 59, 59, 999)); QCOMPARE(first.date().endOfDay(UTC).time(), QTime(23, 59, 59, 999));
QCOMPARE(last.date().startOfDay(Qt::UTC).time(), QTime(0, 0)); QCOMPARE(last.date().startOfDay(UTC).time(), QTime(0, 0));
QVERIFY(!first.date().startOfDay(Qt::UTC).isValid()); QVERIFY(!first.date().startOfDay(UTC).isValid());
QVERIFY(!last.date().endOfDay(Qt::UTC).isValid()); QVERIFY(!last.date().endOfDay(UTC).isValid());
// Test for QTBUG-100873, shouldn't assert: // Test for QTBUG-100873, shouldn't assert:
const QDate qdteMin(1752, 9, 14); // Used by QDateTimeEdit const QDate qdteMin(1752, 9, 14); // Used by QDateTimeEdit
QCOMPARE(qdteMin.startOfDay(Qt::UTC).date(), qdteMin); QCOMPARE(qdteMin.startOfDay(UTC).date(), qdteMin);
QCOMPARE(qdteMin.startOfDay(Qt::LocalTime).date(), qdteMin); QCOMPARE(qdteMin.startOfDay().date(), qdteMin);
#if QT_CONFIG(timezone) #if QT_CONFIG(timezone)
QCOMPARE(qdteMin.startOfDay(QTimeZone::systemTimeZone()).date(), qdteMin); QCOMPARE(qdteMin.startOfDay(QTimeZone::systemTimeZone()).date(), qdteMin);
QTimeZone berlin("Europe/Berlin"); QTimeZone berlin("Europe/Berlin");

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
#include <QTest> #include <QTest>
#include <qtimezone.h> #include <qtimezone.h>
#include <private/qtimezoneprivate_p.h> #include <private/qtimezoneprivate_p.h>
#include <qlocale.h> #include <qlocale.h>
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
@ -73,8 +74,8 @@ private:
void tst_QTimeZone::printTimeZone(const QTimeZone &tz) void tst_QTimeZone::printTimeZone(const QTimeZone &tz)
{ {
QDateTime now = QDateTime::currentDateTime(); QDateTime now = QDateTime::currentDateTime();
QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC); QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC);
QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC); QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC);
qDebug() << ""; qDebug() << "";
qDebug() << "Time Zone = " << tz; qDebug() << "Time Zone = " << tz;
qDebug() << ""; qDebug() << "";
@ -158,9 +159,9 @@ void tst_QTimeZone::createTest()
QCOMPARE(tz.territory(), QLocale::NewZealand); QCOMPARE(tz.territory(), QLocale::NewZealand);
QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC); QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC);
QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC); QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC);
QDateTime janPrev = QDateTime(QDate(2011, 1, 1), QTime(0, 0, 0), Qt::UTC); QDateTime janPrev = QDateTime(QDate(2011, 1, 1), QTime(0, 0), QTimeZone::UTC);
QCOMPARE(tz.offsetFromUtc(jan), 13 * 3600); QCOMPARE(tz.offsetFromUtc(jan), 13 * 3600);
QCOMPARE(tz.offsetFromUtc(jun), 12 * 3600); QCOMPARE(tz.offsetFromUtc(jun), 12 * 3600);
@ -180,7 +181,8 @@ void tst_QTimeZone::createTest()
QTimeZone::OffsetData tran = tz.nextTransition(jan); QTimeZone::OffsetData tran = tz.nextTransition(jan);
// 2012-04-01 03:00 NZDT, +13 -> +12 // 2012-04-01 03:00 NZDT, +13 -> +12
QCOMPARE(tran.atUtc, QCOMPARE(tran.atUtc,
QDateTime(QDate(2012, 4, 1), QTime(3, 0), Qt::OffsetFromUTC, 13 * 3600)); QDateTime(QDate(2012, 4, 1), QTime(3, 0),
QTimeZone::fromSecondsAheadOfUtc(13 * 3600)));
QCOMPARE(tran.offsetFromUtc, 12 * 3600); QCOMPARE(tran.offsetFromUtc, 12 * 3600);
QCOMPARE(tran.standardTimeOffset, 12 * 3600); QCOMPARE(tran.standardTimeOffset, 12 * 3600);
QCOMPARE(tran.daylightTimeOffset, 0); QCOMPARE(tran.daylightTimeOffset, 0);
@ -188,7 +190,8 @@ void tst_QTimeZone::createTest()
tran = tz.nextTransition(jun); tran = tz.nextTransition(jun);
// 2012-09-30 02:00 NZST, +12 -> +13 // 2012-09-30 02:00 NZST, +12 -> +13
QCOMPARE(tran.atUtc, QCOMPARE(tran.atUtc,
QDateTime(QDate(2012, 9, 30), QTime(2, 0), Qt::OffsetFromUTC, 12 * 3600)); QDateTime(QDate(2012, 9, 30), QTime(2, 0),
QTimeZone::fromSecondsAheadOfUtc(12 * 3600)));
QCOMPARE(tran.offsetFromUtc, 13 * 3600); QCOMPARE(tran.offsetFromUtc, 13 * 3600);
QCOMPARE(tran.standardTimeOffset, 12 * 3600); QCOMPARE(tran.standardTimeOffset, 12 * 3600);
QCOMPARE(tran.daylightTimeOffset, 3600); QCOMPARE(tran.daylightTimeOffset, 3600);
@ -196,7 +199,8 @@ void tst_QTimeZone::createTest()
tran = tz.previousTransition(jan); tran = tz.previousTransition(jan);
// 2011-09-25 02:00 NZST, +12 -> +13 // 2011-09-25 02:00 NZST, +12 -> +13
QCOMPARE(tran.atUtc, QCOMPARE(tran.atUtc,
QDateTime(QDate(2011, 9, 25), QTime(2, 0), Qt::OffsetFromUTC, 12 * 3600)); QDateTime(QDate(2011, 9, 25), QTime(2, 0),
QTimeZone::fromSecondsAheadOfUtc(12 * 3600)));
QCOMPARE(tran.offsetFromUtc, 13 * 3600); QCOMPARE(tran.offsetFromUtc, 13 * 3600);
QCOMPARE(tran.standardTimeOffset, 12 * 3600); QCOMPARE(tran.standardTimeOffset, 12 * 3600);
QCOMPARE(tran.daylightTimeOffset, 3600); QCOMPARE(tran.daylightTimeOffset, 3600);
@ -204,17 +208,20 @@ void tst_QTimeZone::createTest()
tran = tz.previousTransition(jun); tran = tz.previousTransition(jun);
// 2012-04-01 03:00 NZDT, +13 -> +12 (again) // 2012-04-01 03:00 NZDT, +13 -> +12 (again)
QCOMPARE(tran.atUtc, QCOMPARE(tran.atUtc,
QDateTime(QDate(2012, 4, 1), QTime(3, 0), Qt::OffsetFromUTC, 13 * 3600)); QDateTime(QDate(2012, 4, 1), QTime(3, 0),
QTimeZone::fromSecondsAheadOfUtc(13 * 3600)));
QCOMPARE(tran.offsetFromUtc, 12 * 3600); QCOMPARE(tran.offsetFromUtc, 12 * 3600);
QCOMPARE(tran.standardTimeOffset, 12 * 3600); QCOMPARE(tran.standardTimeOffset, 12 * 3600);
QCOMPARE(tran.daylightTimeOffset, 0); QCOMPARE(tran.daylightTimeOffset, 0);
QTimeZone::OffsetDataList expected; QTimeZone::OffsetDataList expected;
// Reuse 2012's fall-back data for 2011-04-03: // Reuse 2012's fall-back data for 2011-04-03:
tran.atUtc = QDateTime(QDate(2011, 4, 3), QTime(3, 0), Qt::OffsetFromUTC, 13 * 3600); tran.atUtc = QDateTime(QDate(2011, 4, 3), QTime(3, 0),
QTimeZone::fromSecondsAheadOfUtc(13 * 3600));
expected << tran; expected << tran;
// 2011's spring-forward: // 2011's spring-forward:
tran.atUtc = QDateTime(QDate(2011, 9, 25), QTime(2, 0), Qt::OffsetFromUTC, 12 * 3600); tran.atUtc = QDateTime(QDate(2011, 9, 25), QTime(2, 0),
QTimeZone::fromSecondsAheadOfUtc(12 * 3600));
tran.offsetFromUtc = 13 * 3600; tran.offsetFromUtc = 13 * 3600;
tran.daylightTimeOffset = 3600; tran.daylightTimeOffset = 3600;
expected << tran; expected << tran;
@ -256,9 +263,9 @@ void tst_QTimeZone::nullTest()
QCOMPARE(nullTz1.territory(), QLocale::AnyTerritory); QCOMPARE(nullTz1.territory(), QLocale::AnyTerritory);
QCOMPARE(nullTz1.comment(), QString()); QCOMPARE(nullTz1.comment(), QString());
QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC); QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC);
QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC); QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC);
QDateTime janPrev = QDateTime(QDate(2011, 1, 1), QTime(0, 0, 0), Qt::UTC); QDateTime janPrev = QDateTime(QDate(2011, 1, 1), QTime(0, 0), QTimeZone::UTC);
QCOMPARE(nullTz1.abbreviation(jan), QString()); QCOMPARE(nullTz1.abbreviation(jan), QString());
QCOMPARE(nullTz1.displayName(jan), QString()); QCOMPARE(nullTz1.displayName(jan), QString());
@ -514,7 +521,7 @@ void tst_QTimeZone::systemZone()
QDate(2038, 1, 20) // First day after 32-bit time_t's range QDate(2038, 1, 20) // First day after 32-bit time_t's range
}; };
for (const auto &date : dates) for (const auto &date : dates)
QCOMPARE(date.startOfDay(Qt::LocalTime), date.startOfDay(zone)); QCOMPARE(date.startOfDay(QTimeZone::LocalTime), date.startOfDay(zone));
#if __cpp_lib_chrono >= 201907L #if __cpp_lib_chrono >= 201907L
const std::chrono::time_zone *currentTimeZone = std::chrono::current_zone(); const std::chrono::time_zone *currentTimeZone = std::chrono::current_zone();
@ -636,7 +643,7 @@ void tst_QTimeZone::utcOffsetId()
QTimeZone zone(id); QTimeZone zone(id);
QCOMPARE(zone.isValid(), valid); QCOMPARE(zone.isValid(), valid);
if (valid) { if (valid) {
QDateTime epoch(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::UTC); QDateTime epoch(QDate(1970, 1, 1), QTime(0, 0), QTimeZone::UTC);
QFETCH(int, offset); QFETCH(int, offset);
QCOMPARE(zone.offsetFromUtc(epoch), offset); QCOMPARE(zone.offsetFromUtc(epoch), offset);
QVERIFY(!zone.hasDaylightTime()); QVERIFY(!zone.hasDaylightTime());
@ -669,15 +676,15 @@ void tst_QTimeZone::specificTransition_data()
QTest::newRow("Moscow/2014") // From original bug-report QTest::newRow("Moscow/2014") // From original bug-report
<< QByteArray("Europe/Moscow") << QByteArray("Europe/Moscow")
<< QDate(2011, 4, 1) << QDate(2021, 12, 31) << 1 << QDate(2011, 4, 1) << QDate(2021, 12, 31) << 1
<< QDateTime(QDate(2014, 10, 26), QTime(2, 0, 0), << QDateTime(QDate(2014, 10, 26), QTime(2, 0),
Qt::OffsetFromUTC, 4 * 3600).toUTC() QTimeZone::fromSecondsAheadOfUtc(4 * 3600)).toUTC()
<< 3 * 3600 << 3 * 3600 << 0; << 3 * 3600 << 3 * 3600 << 0;
} }
QTest::newRow("Moscow/2011") // Transition on 2011-03-27 QTest::newRow("Moscow/2011") // Transition on 2011-03-27
<< QByteArray("Europe/Moscow") << QByteArray("Europe/Moscow")
<< QDate(2010, 11, 1) << QDate(2014, 10, 25) << 1 << QDate(2010, 11, 1) << QDate(2014, 10, 25) << 1
<< QDateTime(QDate(2011, 3, 27), QTime(2, 0, 0), << QDateTime(QDate(2011, 3, 27), QTime(2, 0),
Qt::OffsetFromUTC, 3 * 3600).toUTC() QTimeZone::fromSecondsAheadOfUtc(3 * 3600)).toUTC()
<< 4 * 3600 << 4 * 3600 << 0; << 4 * 3600 << 4 * 3600 << 0;
} }
@ -849,12 +856,13 @@ void tst_QTimeZone::availableTimeZoneIds()
void tst_QTimeZone::stressTest() void tst_QTimeZone::stressTest()
{ {
const auto UTC = QTimeZone::UTC;
const QList<QByteArray> idList = QTimeZone::availableTimeZoneIds(); const QList<QByteArray> idList = QTimeZone::availableTimeZoneIds();
for (const QByteArray &id : idList) { for (const QByteArray &id : idList) {
QTimeZone testZone = QTimeZone(id); QTimeZone testZone = QTimeZone(id);
QCOMPARE(testZone.isValid(), true); QCOMPARE(testZone.isValid(), true);
QCOMPARE(testZone.id(), id); QCOMPARE(testZone.id(), id);
QDateTime testDate = QDateTime(QDate(2015, 1, 1), QTime(0, 0, 0), Qt::UTC); QDateTime testDate = QDateTime(QDate(2015, 1, 1), QTime(0, 0), UTC);
testZone.territory(); testZone.territory();
testZone.comment(); testZone.comment();
testZone.displayName(testDate); testZone.displayName(testDate);
@ -871,10 +879,10 @@ void tst_QTimeZone::stressTest()
testZone.nextTransition(testDate); testZone.nextTransition(testDate);
testZone.previousTransition(testDate); testZone.previousTransition(testDate);
// Dates known to be outside possible tz file pre-calculated rules range // Dates known to be outside possible tz file pre-calculated rules range
QDateTime lowDate1 = QDateTime(QDate(1800, 1, 1), QTime(0, 0, 0), Qt::UTC); QDateTime lowDate1 = QDateTime(QDate(1800, 1, 1), QTime(0, 0), UTC);
QDateTime lowDate2 = QDateTime(QDate(1800, 6, 1), QTime(0, 0, 0), Qt::UTC); QDateTime lowDate2 = QDateTime(QDate(1800, 6, 1), QTime(0, 0), UTC);
QDateTime highDate1 = QDateTime(QDate(2200, 1, 1), QTime(0, 0, 0), Qt::UTC); QDateTime highDate1 = QDateTime(QDate(2200, 1, 1), QTime(0, 0), UTC);
QDateTime highDate2 = QDateTime(QDate(2200, 6, 1), QTime(0, 0, 0), Qt::UTC); QDateTime highDate2 = QDateTime(QDate(2200, 6, 1), QTime(0, 0), UTC);
testZone.nextTransition(lowDate1); testZone.nextTransition(lowDate1);
testZone.nextTransition(lowDate2); testZone.nextTransition(lowDate2);
testZone.previousTransition(lowDate2); testZone.previousTransition(lowDate2);
@ -1196,8 +1204,8 @@ void tst_QTimeZone::icuTest()
{ {
#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu) #if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu)
// Known datetimes // Known datetimes
qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
// Test default constructor // Test default constructor
QIcuTimeZonePrivate tzpd; QIcuTimeZonePrivate tzpd;
@ -1241,9 +1249,10 @@ void tst_QTimeZone::icuTest()
void tst_QTimeZone::tzTest() void tst_QTimeZone::tzTest()
{ {
#if defined QT_BUILD_INTERNAL && defined Q_OS_UNIX && !defined Q_OS_DARWIN && !defined Q_OS_ANDROID #if defined QT_BUILD_INTERNAL && defined Q_OS_UNIX && !defined Q_OS_DARWIN && !defined Q_OS_ANDROID
const auto UTC = QTimeZone::UTC;
// Known datetimes // Known datetimes
qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), UTC).toMSecsSinceEpoch();
qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), UTC).toMSecsSinceEpoch();
// Test default constructor // Test default constructor
QTzTimeZonePrivate tzpd; QTzTimeZonePrivate tzpd;
@ -1276,8 +1285,8 @@ void tst_QTimeZone::tzTest()
// It shouldn't have any transitions. QTimeZone::hasTransitions() only says // It shouldn't have any transitions. QTimeZone::hasTransitions() only says
// whether the backend supports them, so ask for transitions in a wide // whether the backend supports them, so ask for transitions in a wide
// enough interval that one would show up, if there are any: // enough interval that one would show up, if there are any:
QVERIFY(permaDst.transitions(QDate(2015, 1, 1).startOfDay(Qt::UTC).toMSecsSinceEpoch(), QVERIFY(permaDst.transitions(QDate(2015, 1, 1).startOfDay(UTC).toMSecsSinceEpoch(),
QDate(2020, 1, 1).startOfDay(Qt::UTC).toMSecsSinceEpoch() QDate(2020, 1, 1).startOfDay(UTC).toMSecsSinceEpoch()
).isEmpty()); ).isEmpty());
QTimeZone tzBrazil("BRT+3"); // parts of Northern Brazil, as a POSIX rule QTimeZone tzBrazil("BRT+3"); // parts of Northern Brazil, as a POSIX rule
@ -1348,14 +1357,16 @@ void tst_QTimeZone::tzTest()
} }
dat = tzp.nextTransition(ancient); dat = tzp.nextTransition(ancient);
QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600), QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch,
QDateTime(QDate(1893, 4, 1), QTime(0, 6, 32), Qt::OffsetFromUTC, 3600)); QTimeZone::fromSecondsAheadOfUtc(3600)),
QDateTime(QDate(1893, 4, 1), QTime(0, 6, 32),
QTimeZone::fromSecondsAheadOfUtc(3600)));
QCOMPARE(dat.standardTimeOffset, 3600); QCOMPARE(dat.standardTimeOffset, 3600);
QCOMPARE(dat.daylightTimeOffset, 0); QCOMPARE(dat.daylightTimeOffset, 0);
// Date-times late enough to exercise POSIX rules: // Date-times late enough to exercise POSIX rules:
qint64 stdHi = QDate(2100, 1, 1).startOfDay(Qt::UTC).toMSecsSinceEpoch(); qint64 stdHi = QDate(2100, 1, 1).startOfDay(UTC).toMSecsSinceEpoch();
qint64 dstHi = QDate(2100, 6, 1).startOfDay(Qt::UTC).toMSecsSinceEpoch(); qint64 dstHi = QDate(2100, 6, 1).startOfDay(UTC).toMSecsSinceEpoch();
// Relevant last Sundays in October and March: // Relevant last Sundays in October and March:
QCOMPARE(Qt::DayOfWeek(QDate(2099, 10, 25).dayOfWeek()), Qt::Sunday); QCOMPARE(Qt::DayOfWeek(QDate(2099, 10, 25).dayOfWeek()), Qt::Sunday);
QCOMPARE(Qt::DayOfWeek(QDate(2100, 3, 28).dayOfWeek()), Qt::Sunday); QCOMPARE(Qt::DayOfWeek(QDate(2100, 3, 28).dayOfWeek()), Qt::Sunday);
@ -1375,32 +1386,33 @@ void tst_QTimeZone::tzTest()
dat = tzp.previousTransition(stdHi); dat = tzp.previousTransition(stdHi);
QCOMPARE(dat.abbreviation, QStringLiteral("CET")); QCOMPARE(dat.abbreviation, QStringLiteral("CET"));
QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::UTC), QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, UTC),
QDateTime(QDate(2099, 10, 25), QTime(3, 0), Qt::OffsetFromUTC, 7200)); QDateTime(QDate(2099, 10, 25), QTime(3, 0), QTimeZone::fromSecondsAheadOfUtc(7200)));
QCOMPARE(dat.offsetFromUtc, 3600); QCOMPARE(dat.offsetFromUtc, 3600);
QCOMPARE(dat.standardTimeOffset, 3600); QCOMPARE(dat.standardTimeOffset, 3600);
QCOMPARE(dat.daylightTimeOffset, 0); QCOMPARE(dat.daylightTimeOffset, 0);
dat = tzp.previousTransition(dstHi); dat = tzp.previousTransition(dstHi);
QCOMPARE(dat.abbreviation, QStringLiteral("CEST")); QCOMPARE(dat.abbreviation, QStringLiteral("CEST"));
QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::UTC), QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, UTC),
QDateTime(QDate(2100, 3, 28), QTime(2, 0), Qt::OffsetFromUTC, 3600)); QDateTime(QDate(2100, 3, 28), QTime(2, 0), QTimeZone::fromSecondsAheadOfUtc(3600)));
QCOMPARE(dat.offsetFromUtc, 7200); QCOMPARE(dat.offsetFromUtc, 7200);
QCOMPARE(dat.standardTimeOffset, 3600); QCOMPARE(dat.standardTimeOffset, 3600);
QCOMPARE(dat.daylightTimeOffset, 3600); QCOMPARE(dat.daylightTimeOffset, 3600);
dat = tzp.nextTransition(stdHi); dat = tzp.nextTransition(stdHi);
QCOMPARE(dat.abbreviation, QStringLiteral("CEST")); QCOMPARE(dat.abbreviation, QStringLiteral("CEST"));
QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::UTC), QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, UTC),
QDateTime(QDate(2100, 3, 28), QTime(2, 0), Qt::OffsetFromUTC, 3600)); QDateTime(QDate(2100, 3, 28), QTime(2, 0), QTimeZone::fromSecondsAheadOfUtc(3600)));
QCOMPARE(dat.offsetFromUtc, 7200); QCOMPARE(dat.offsetFromUtc, 7200);
QCOMPARE(dat.standardTimeOffset, 3600); QCOMPARE(dat.standardTimeOffset, 3600);
QCOMPARE(dat.daylightTimeOffset, 3600); QCOMPARE(dat.daylightTimeOffset, 3600);
dat = tzp.nextTransition(dstHi); dat = tzp.nextTransition(dstHi);
QCOMPARE(dat.abbreviation, QStringLiteral("CET")); QCOMPARE(dat.abbreviation, QStringLiteral("CET"));
QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600), QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch,
QDateTime(QDate(2100, 10, 31), QTime(3, 0), Qt::OffsetFromUTC, 7200)); QTimeZone::fromSecondsAheadOfUtc(3600)),
QDateTime(QDate(2100, 10, 31), QTime(3, 0), QTimeZone::fromSecondsAheadOfUtc(7200)));
QCOMPARE(dat.offsetFromUtc, 3600); QCOMPARE(dat.offsetFromUtc, 3600);
QCOMPARE(dat.standardTimeOffset, 3600); QCOMPARE(dat.standardTimeOffset, 3600);
QCOMPARE(dat.daylightTimeOffset, 0); QCOMPARE(dat.daylightTimeOffset, 0);
@ -1429,7 +1441,7 @@ void tst_QTimeZone::tzTest()
QCOMPARE(tzBarnaul.data(std).abbreviation, QString("+07")); QCOMPARE(tzBarnaul.data(std).abbreviation, QString("+07"));
// first full day of the new rule (tzdata2016b) // first full day of the new rule (tzdata2016b)
QDateTime dt(QDate(2016, 3, 28), QTime(0, 0, 0), Qt::UTC); QDateTime dt(QDate(2016, 3, 28), QTime(0, 0), UTC);
QCOMPARE(tzBarnaul.data(dt.toMSecsSinceEpoch()).abbreviation, QString("+07")); QCOMPARE(tzBarnaul.data(dt.toMSecsSinceEpoch()).abbreviation, QString("+07"));
} }
#endif // QT_BUILD_INTERNAL && Q_OS_UNIX && !Q_OS_DARWIN #endif // QT_BUILD_INTERNAL && Q_OS_UNIX && !Q_OS_DARWIN
@ -1439,8 +1451,8 @@ void tst_QTimeZone::macTest()
{ {
#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_DARWIN) #if defined(QT_BUILD_INTERNAL) && defined(Q_OS_DARWIN)
// Known datetimes // Known datetimes
qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
// Test default constructor // Test default constructor
QMacTimeZonePrivate tzpd; QMacTimeZonePrivate tzpd;
@ -1495,8 +1507,8 @@ void tst_QTimeZone::winTest()
{ {
#if defined(QT_BUILD_INTERNAL) && defined(USING_WIN_TZ) #if defined(QT_BUILD_INTERNAL) && defined(USING_WIN_TZ)
// Known datetimes // Known datetimes
qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
// Test default constructor // Test default constructor
QWinTimeZonePrivate tzpd; QWinTimeZonePrivate tzpd;
@ -1598,9 +1610,11 @@ void tst_QTimeZone::localeSpecificDisplayName()
void tst_QTimeZone::testCetPrivate(const QTimeZonePrivate &tzp) void tst_QTimeZone::testCetPrivate(const QTimeZonePrivate &tzp)
{ {
// Known datetimes // Known datetimes
qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); const auto UTC = QTimeZone::UTC;
qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); const auto eastOneHour = QTimeZone::fromSecondsAheadOfUtc(3600);
qint64 prev = QDateTime(QDate(2011, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch(); qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), UTC).toMSecsSinceEpoch();
qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), UTC).toMSecsSinceEpoch();
qint64 prev = QDateTime(QDate(2011, 1, 1), QTime(0, 0), UTC).toMSecsSinceEpoch();
QCOMPARE(tzp.offsetFromUtc(std), 3600); QCOMPARE(tzp.offsetFromUtc(std), 3600);
QCOMPARE(tzp.offsetFromUtc(dst), 7200); QCOMPARE(tzp.offsetFromUtc(dst), 7200);
@ -1633,32 +1647,34 @@ void tst_QTimeZone::testCetPrivate(const QTimeZonePrivate &tzp)
if (tzp.hasTransitions()) { if (tzp.hasTransitions()) {
QTimeZonePrivate::Data tran = tzp.nextTransition(std); QTimeZonePrivate::Data tran = tzp.nextTransition(std);
// 2012-03-25 02:00 CET, +1 -> +2 // 2012-03-25 02:00 CET, +1 -> +2
QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC), QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC),
QDateTime(QDate(2012, 3, 25), QTime(2, 0), Qt::OffsetFromUTC, 3600)); QDateTime(QDate(2012, 3, 25), QTime(2, 0), eastOneHour));
QCOMPARE(tran.offsetFromUtc, 7200); QCOMPARE(tran.offsetFromUtc, 7200);
QCOMPARE(tran.standardTimeOffset, 3600); QCOMPARE(tran.standardTimeOffset, 3600);
QCOMPARE(tran.daylightTimeOffset, 3600); QCOMPARE(tran.daylightTimeOffset, 3600);
tran = tzp.nextTransition(dst); tran = tzp.nextTransition(dst);
// 2012-10-28 03:00 CEST, +2 -> +1 // 2012-10-28 03:00 CEST, +2 -> +1
QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC), QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC),
QDateTime(QDate(2012, 10, 28), QTime(3, 0), Qt::OffsetFromUTC, 2 * 3600)); QDateTime(QDate(2012, 10, 28), QTime(3, 0),
QTimeZone::fromSecondsAheadOfUtc(2 * 3600)));
QCOMPARE(tran.offsetFromUtc, 3600); QCOMPARE(tran.offsetFromUtc, 3600);
QCOMPARE(tran.standardTimeOffset, 3600); QCOMPARE(tran.standardTimeOffset, 3600);
QCOMPARE(tran.daylightTimeOffset, 0); QCOMPARE(tran.daylightTimeOffset, 0);
tran = tzp.previousTransition(std); tran = tzp.previousTransition(std);
// 2011-10-30 03:00 CEST, +2 -> +1 // 2011-10-30 03:00 CEST, +2 -> +1
QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC), QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC),
QDateTime(QDate(2011, 10, 30), QTime(3, 0), Qt::OffsetFromUTC, 2 * 3600)); QDateTime(QDate(2011, 10, 30), QTime(3, 0),
QTimeZone::fromSecondsAheadOfUtc(2 * 3600)));
QCOMPARE(tran.offsetFromUtc, 3600); QCOMPARE(tran.offsetFromUtc, 3600);
QCOMPARE(tran.standardTimeOffset, 3600); QCOMPARE(tran.standardTimeOffset, 3600);
QCOMPARE(tran.daylightTimeOffset, 0); QCOMPARE(tran.daylightTimeOffset, 0);
tran = tzp.previousTransition(dst); tran = tzp.previousTransition(dst);
// 2012-03-25 02:00 CET, +1 -> +2 (again) // 2012-03-25 02:00 CET, +1 -> +2 (again)
QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC), QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC),
QDateTime(QDate(2012, 3, 25), QTime(2, 0), Qt::OffsetFromUTC, 3600)); QDateTime(QDate(2012, 3, 25), QTime(2, 0), eastOneHour));
QCOMPARE(tran.offsetFromUtc, 7200); QCOMPARE(tran.offsetFromUtc, 7200);
QCOMPARE(tran.standardTimeOffset, 3600); QCOMPARE(tran.standardTimeOffset, 3600);
QCOMPARE(tran.daylightTimeOffset, 3600); QCOMPARE(tran.daylightTimeOffset, 3600);
@ -1666,14 +1682,15 @@ void tst_QTimeZone::testCetPrivate(const QTimeZonePrivate &tzp)
QTimeZonePrivate::DataList expected; QTimeZonePrivate::DataList expected;
// 2011-03-27 02:00 CET, +1 -> +2 // 2011-03-27 02:00 CET, +1 -> +2
tran.atMSecsSinceEpoch = QDateTime(QDate(2011, 3, 27), QTime(2, 0), tran.atMSecsSinceEpoch = QDateTime(QDate(2011, 3, 27), QTime(2, 0),
Qt::OffsetFromUTC, 3600).toMSecsSinceEpoch(); eastOneHour).toMSecsSinceEpoch();
tran.offsetFromUtc = 7200; tran.offsetFromUtc = 7200;
tran.standardTimeOffset = 3600; tran.standardTimeOffset = 3600;
tran.daylightTimeOffset = 3600; tran.daylightTimeOffset = 3600;
expected << tran; expected << tran;
// 2011-10-30 03:00 CEST, +2 -> +1 // 2011-10-30 03:00 CEST, +2 -> +1
tran.atMSecsSinceEpoch = QDateTime(QDate(2011, 10, 30), QTime(3, 0), tran.atMSecsSinceEpoch = QDateTime(QDate(2011, 10, 30), QTime(3, 0),
Qt::OffsetFromUTC, 2 * 3600).toMSecsSinceEpoch(); QTimeZone::fromSecondsAheadOfUtc(2 * 3600)
).toMSecsSinceEpoch();
tran.offsetFromUtc = 3600; tran.offsetFromUtc = 3600;
tran.standardTimeOffset = 3600; tran.standardTimeOffset = 3600;
tran.daylightTimeOffset = 0; tran.daylightTimeOffset = 0;
@ -1681,10 +1698,8 @@ void tst_QTimeZone::testCetPrivate(const QTimeZonePrivate &tzp)
QTimeZonePrivate::DataList result = tzp.transitions(prev, std); QTimeZonePrivate::DataList result = tzp.transitions(prev, std);
QCOMPARE(result.size(), expected.size()); QCOMPARE(result.size(), expected.size());
for (int i = 0; i < expected.size(); ++i) { for (int i = 0; i < expected.size(); ++i) {
QCOMPARE(QDateTime::fromMSecsSinceEpoch(result.at(i).atMSecsSinceEpoch, QCOMPARE(QDateTime::fromMSecsSinceEpoch(result.at(i).atMSecsSinceEpoch, eastOneHour),
Qt::OffsetFromUTC, 3600), QDateTime::fromMSecsSinceEpoch(expected.at(i).atMSecsSinceEpoch, eastOneHour));
QDateTime::fromMSecsSinceEpoch(expected.at(i).atMSecsSinceEpoch,
Qt::OffsetFromUTC, 3600));
QCOMPARE(result.at(i).offsetFromUtc, expected.at(i).offsetFromUtc); QCOMPARE(result.at(i).offsetFromUtc, expected.at(i).offsetFromUtc);
QCOMPARE(result.at(i).standardTimeOffset, expected.at(i).standardTimeOffset); QCOMPARE(result.at(i).standardTimeOffset, expected.at(i).standardTimeOffset);
QCOMPARE(result.at(i).daylightTimeOffset, expected.at(i).daylightTimeOffset); QCOMPARE(result.at(i).daylightTimeOffset, expected.at(i).daylightTimeOffset);
@ -1698,10 +1713,13 @@ void tst_QTimeZone::testEpochTranPrivate(const QTimeZonePrivate &tzp)
if (!tzp.hasTransitions()) if (!tzp.hasTransitions())
return; // test only viable for transitions return; // test only viable for transitions
const auto UTC = QTimeZone::UTC;
const auto hour = std::chrono::hours{1};
QTimeZonePrivate::Data tran = tzp.nextTransition(0); // i.e. first after epoch QTimeZonePrivate::Data tran = tzp.nextTransition(0); // i.e. first after epoch
// 1970-04-26 02:00 EST, -5 -> -4 // 1970-04-26 02:00 EST, -5 -> -4
const QDateTime after = QDateTime(QDate(1970, 4, 26), QTime(2, 0), Qt::OffsetFromUTC, -5 * 3600); const QDateTime after = QDateTime(QDate(1970, 4, 26), QTime(2, 0),
const QDateTime found = QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC); QTimeZone::fromDurationAheadOfUtc(-5 * hour));
const QDateTime found = QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC);
#ifdef USING_WIN_TZ // MS gets the date wrong: 5th April instead of 26th. #ifdef USING_WIN_TZ // MS gets the date wrong: 5th April instead of 26th.
QCOMPARE(found.toOffsetFromUtc(-5 * 3600).time(), after.time()); QCOMPARE(found.toOffsetFromUtc(-5 * 3600).time(), after.time());
#else #else
@ -1712,16 +1730,16 @@ void tst_QTimeZone::testEpochTranPrivate(const QTimeZonePrivate &tzp)
QCOMPARE(tran.daylightTimeOffset, 3600); QCOMPARE(tran.daylightTimeOffset, 3600);
// Pre-epoch time-zones might not be supported at all: // Pre-epoch time-zones might not be supported at all:
tran = tzp.nextTransition(QDateTime(QDate(1601, 1, 1), QTime(0, 0), tran = tzp.nextTransition(QDateTime(QDate(1601, 1, 1), QTime(0, 0), UTC).toMSecsSinceEpoch());
Qt::UTC).toMSecsSinceEpoch());
if (tran.atMSecsSinceEpoch != QTimeZonePrivate::invalidMSecs() if (tran.atMSecsSinceEpoch != QTimeZonePrivate::invalidMSecs()
// Toronto *did* have a transition before 1970 (DST since 1918): // Toronto *did* have a transition before 1970 (DST since 1918):
&& tran.atMSecsSinceEpoch < 0) { && tran.atMSecsSinceEpoch < 0) {
// ... but, if they are, we should be able to search back to them: // ... but, if they are, we should be able to search back to them:
tran = tzp.previousTransition(0); // i.e. last before epoch tran = tzp.previousTransition(0); // i.e. last before epoch
// 1969-10-26 02:00 EDT, -4 -> -5 // 1969-10-26 02:00 EDT, -4 -> -5
QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC), QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, UTC),
QDateTime(QDate(1969, 10, 26), QTime(2, 0), Qt::OffsetFromUTC, -4 * 3600)); QDateTime(QDate(1969, 10, 26), QTime(2, 0),
QTimeZone::fromDurationAheadOfUtc(-4 * hour)));
QCOMPARE(tran.offsetFromUtc, -5 * 3600); QCOMPARE(tran.offsetFromUtc, -5 * 3600);
QCOMPARE(tran.standardTimeOffset, -5 * 3600); QCOMPARE(tran.standardTimeOffset, -5 * 3600);
QCOMPARE(tran.daylightTimeOffset, 0); QCOMPARE(tran.daylightTimeOffset, 0);

View File

@ -390,7 +390,7 @@ void tst_QDateTime::equivalentUtc()
{ {
bool result = false; bool result = false;
const QDateTime other = QDateTime::fromMSecsSinceEpoch( const QDateTime other = QDateTime::fromMSecsSinceEpoch(
qint64(JULIAN_DAY_2010 - JULIAN_DAY_1970) * MSECS_PER_DAY, Qt::UTC); qint64(JULIAN_DAY_2010 - JULIAN_DAY_1970) * MSECS_PER_DAY, QTimeZone::UTC);
const auto list = daily(JULIAN_DAY_2010, JULIAN_DAY_2020); const auto list = daily(JULIAN_DAY_2010, JULIAN_DAY_2020);
QBENCHMARK { QBENCHMARK {
for (const QDateTime &test : list) for (const QDateTime &test : list)
@ -416,7 +416,7 @@ void tst_QDateTime::lessThanUtc()
{ {
bool result = false; bool result = false;
const QDateTime other = QDateTime::fromMSecsSinceEpoch( const QDateTime other = QDateTime::fromMSecsSinceEpoch(
qint64(JULIAN_DAY_2010 - JULIAN_DAY_1970) * MSECS_PER_DAY, Qt::UTC); qint64(JULIAN_DAY_2010 - JULIAN_DAY_1970) * MSECS_PER_DAY, QTimeZone::UTC);
const auto list = daily(JULIAN_DAY_2010, JULIAN_DAY_2020); const auto list = daily(JULIAN_DAY_2010, JULIAN_DAY_2020);
QBENCHMARK { QBENCHMARK {
for (const QDateTime &test : list) for (const QDateTime &test : list)
@ -500,7 +500,7 @@ void tst_QDateTime::fromMSecsSinceEpoch()
const int end = JULIAN_DAY_2020 - JULIAN_DAY_1970; const int end = JULIAN_DAY_2020 - JULIAN_DAY_1970;
QBENCHMARK { QBENCHMARK {
for (int jd = start; jd < end; ++jd) for (int jd = start; jd < end; ++jd)
QDateTime::fromMSecsSinceEpoch(jd * MSECS_PER_DAY, Qt::LocalTime); QDateTime::fromMSecsSinceEpoch(jd * MSECS_PER_DAY);
} }
} }
@ -510,7 +510,7 @@ void tst_QDateTime::fromMSecsSinceEpochUtc()
const int end = JULIAN_DAY_2020 - JULIAN_DAY_1970; const int end = JULIAN_DAY_2020 - JULIAN_DAY_1970;
QBENCHMARK { QBENCHMARK {
for (int jd = start; jd < end; ++jd) for (int jd = start; jd < end; ++jd)
QDateTime::fromMSecsSinceEpoch(jd * MSECS_PER_DAY, Qt::UTC); QDateTime::fromMSecsSinceEpoch(jd * MSECS_PER_DAY, QTimeZone::UTC);
} }
} }

View File

@ -108,9 +108,9 @@ void tst_QTimeZone::transitionList()
{ {
QFETCH(QByteArray, name); QFETCH(QByteArray, name);
const QTimeZone zone = name.isEmpty() ? QTimeZone::systemTimeZone() : QTimeZone(name); const QTimeZone zone = name.isEmpty() ? QTimeZone::systemTimeZone() : QTimeZone(name);
const QDateTime early = QDate(1625, 6, 8).startOfDay(Qt::UTC); // Cassini's birth date const QDateTime early = QDate(1625, 6, 8).startOfDay(QTimeZone::UTC); // Cassini's birth date
const QDateTime late // End of 32-bit signed time_t const QDateTime late // End of 32-bit signed time_t
= QDateTime::fromSecsSinceEpoch(std::numeric_limits<qint32>::max(), Qt::UTC); = QDateTime::fromSecsSinceEpoch(std::numeric_limits<qint32>::max(), QTimeZone::UTC);
QTimeZone::OffsetDataList seq; QTimeZone::OffsetDataList seq;
QBENCHMARK { QBENCHMARK {
seq = zone.transitions(early, late); seq = zone.transitions(early, late);
@ -122,7 +122,7 @@ void tst_QTimeZone::transitionsForward()
{ {
QFETCH(QByteArray, name); QFETCH(QByteArray, name);
const QTimeZone zone = name.isEmpty() ? QTimeZone::systemTimeZone() : QTimeZone(name); const QTimeZone zone = name.isEmpty() ? QTimeZone::systemTimeZone() : QTimeZone(name);
const QDateTime early = QDate(1625, 6, 8).startOfDay(Qt::UTC); // Cassini's birth date const QDateTime early = QDate(1625, 6, 8).startOfDay(QTimeZone::UTC); // Cassini's birth date
QBENCHMARK { QBENCHMARK {
QTimeZone::OffsetData tran = zone.nextTransition(early); QTimeZone::OffsetData tran = zone.nextTransition(early);
while (tran.atUtc.isValid()) while (tran.atUtc.isValid())
@ -135,7 +135,7 @@ void tst_QTimeZone::transitionsReverse()
QFETCH(QByteArray, name); QFETCH(QByteArray, name);
const QTimeZone zone = name.isEmpty() ? QTimeZone::systemTimeZone() : QTimeZone(name); const QTimeZone zone = name.isEmpty() ? QTimeZone::systemTimeZone() : QTimeZone(name);
const QDateTime late // End of 32-bit signed time_t const QDateTime late // End of 32-bit signed time_t
= QDateTime::fromSecsSinceEpoch(std::numeric_limits<qint32>::max(), Qt::UTC); = QDateTime::fromSecsSinceEpoch(std::numeric_limits<qint32>::max(), QTimeZone::UTC);
QBENCHMARK { QBENCHMARK {
QTimeZone::OffsetData tran = zone.previousTransition(late); QTimeZone::OffsetData tran = zone.previousTransition(late);
while (tran.atUtc.isValid()) while (tran.atUtc.isValid())