diff options
Diffstat (limited to 'src/corelib/tools/qdatetime.cpp')
-rw-r--r-- | src/corelib/tools/qdatetime.cpp | 889 |
1 files changed, 494 insertions, 395 deletions
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 6750925853..140a5c1eaf 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -57,9 +57,6 @@ #include <time.h> #ifdef Q_OS_WIN # include <qt_windows.h> -# ifdef Q_OS_WINCE -# include "qfunctions_wince.h" -# endif # ifdef Q_OS_WINRT # include "qfunctions_winrt.h" # endif @@ -71,8 +68,6 @@ QT_BEGIN_NAMESPACE -Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QDateTimePrivate>, defaultDateTimePrivate, (new QDateTimePrivate())) - /***************************************************************************** Date/Time Constants *****************************************************************************/ @@ -1685,9 +1680,6 @@ QString QTime::toString(const QString& format) const bool QTime::setHMS(int h, int m, int s, int ms) { -#if defined(Q_OS_WINCE) - startTick = NullTime; -#endif if (!isValid(h,m,s,ms)) { mds = NullTime; // make this invalid return false; @@ -1767,10 +1759,6 @@ QTime QTime::addMSecs(int ms) const t.mds = (ds() + ms) % MSECS_PER_DAY; } } -#if defined(Q_OS_WINCE) - if (startTick > NullTime) - t.startTick = (startTick + ms) % MSECS_PER_DAY; -#endif return t; } @@ -1792,13 +1780,7 @@ int QTime::msecsTo(const QTime &t) const { if (!isValid() || !t.isValid()) return 0; -#if defined(Q_OS_WINCE) - // GetLocalTime() for Windows CE has no milliseconds resolution - if (t.startTick > NullTime && startTick > NullTime) - return t.startTick - startTick; - else -#endif - return t.ds() - ds(); + return t.ds() - ds(); } @@ -2137,13 +2119,14 @@ int QTime::elapsed() const QDateTime static helper functions *****************************************************************************/ +// get the types from QDateTime (through QDateTimePrivate) +typedef QDateTimePrivate::QDateTimeShortData ShortData; +typedef QDateTimePrivate::QDateTimeData QDateTimeData; + // Calls the platform variant of tzset static void qt_tzset() { -#if defined(Q_OS_WINCE) - // WinCE doesn't use tzset - return; -#elif defined(Q_OS_WIN) +#if defined(Q_OS_WIN) _tzset(); #else tzset(); @@ -2157,12 +2140,7 @@ static void qt_tzset() // Relies on tzset, mktime, or localtime having been called to populate timezone static int qt_timezone() { -#if defined(Q_OS_WINCE) - TIME_ZONE_INFORMATION tzi; - GetTimeZoneInformation(&tzi); - // Expressed in minutes, convert to seconds - return (tzi.Bias + tzi.StandardBias) * 60; -#elif defined(_MSC_VER) && _MSC_VER >= 1400 +#if defined(_MSC_VER) long offset; _get_timezone(&offset); return offset; @@ -2191,16 +2169,6 @@ static int qt_timezone() // Returns the tzname, assume tzset has been called already static QString qt_tzname(QDateTimePrivate::DaylightStatus daylightStatus) { -#if defined(Q_OS_WINCE) - TIME_ZONE_INFORMATION tzi; - DWORD res = GetTimeZoneInformation(&tzi); - if (res == TIME_ZONE_ID_UNKNOWN) - return QString(); - else if (daylightStatus == QDateTimePrivate::DaylightTime) - return QString::fromWCharArray(tzi.DaylightName); - else - return QString::fromWCharArray(tzi.StandardName); -#else int isDst = (daylightStatus == QDateTimePrivate::DaylightTime) ? 1 : 0; #if defined(_MSC_VER) && _MSC_VER >= 1400 size_t s = 0; @@ -2211,7 +2179,6 @@ static QString qt_tzname(QDateTimePrivate::DaylightStatus daylightStatus) #else return QString::fromLocal8Bit(tzname[isDst]); #endif // Q_OS_WIN -#endif // Q_OS_WINCE } // Calls the platform variant of mktime for the given date, time and daylightStatus, @@ -2226,48 +2193,6 @@ static qint64 qt_mktime(QDate *date, QTime *time, QDateTimePrivate::DaylightStat int yy, mm, dd; date->getDate(&yy, &mm, &dd); -#if defined(Q_OS_WINCE) - // WinCE doesn't provide standard C library time functions - SYSTEMTIME st; - memset(&st, 0, sizeof(SYSTEMTIME)); - st.wSecond = time->second(); - st.wMinute = time->minute(); - st.wHour = time->hour(); - st.wDay = dd; - st.wMonth = mm; - st.wYear = yy; - FILETIME lft; - bool valid = SystemTimeToFileTime(&st, &lft); - FILETIME ft; - if (valid) - valid = LocalFileTimeToFileTime(&lft, &ft); - const time_t secsSinceEpoch = ftToTime_t(ft); - const time_t localSecs = ftToTime_t(lft); - TIME_ZONE_INFORMATION tzi; - GetTimeZoneInformation(&tzi); - bool isDaylight = false; - // Check for overflow - qint64 localDiff = qAbs(localSecs - secsSinceEpoch); - int daylightOffset = qAbs(tzi.Bias + tzi.DaylightBias) * 60; - if (localDiff > daylightOffset) - valid = false; - else - isDaylight = (localDiff == daylightOffset); - if (daylightStatus) { - if (isDaylight) - *daylightStatus = QDateTimePrivate::DaylightTime; - else - *daylightStatus = QDateTimePrivate::StandardTime; - } - if (abbreviation) { - if (isDaylight) - *abbreviation = QString::fromWCharArray(tzi.DaylightName); - else - *abbreviation = QString::fromWCharArray(tzi.StandardName); - } - if (ok) - *ok = valid; -#else // All other platforms provide standard C library time functions tm local; memset(&local, 0, sizeof(local)); // tm_[wy]day plus any non-standard fields @@ -2329,7 +2254,6 @@ static qint64 qt_mktime(QDate *date, QTime *time, QDateTimePrivate::DaylightStat if (ok) *ok = false; } -#endif // Q_OS_WINCE return ((qint64)secsSinceEpoch * 1000) + msec; } @@ -2345,23 +2269,7 @@ static bool qt_localtime(qint64 msecsSinceEpoch, QDate *localDate, QTime *localT tm local; bool valid = false; -#if defined(Q_OS_WINCE) - FILETIME utcTime = time_tToFt(secsSinceEpoch); - FILETIME resultTime; - valid = FileTimeToLocalFileTime(&utcTime , &resultTime); - SYSTEMTIME sysTime; - if (valid) - valid = FileTimeToSystemTime(&resultTime , &sysTime); - - if (valid) { - local.tm_sec = sysTime.wSecond; - local.tm_min = sysTime.wMinute; - local.tm_hour = sysTime.wHour; - local.tm_mday = sysTime.wDay; - local.tm_mon = sysTime.wMonth - 1; - local.tm_year = sysTime.wYear - 1900; - } -#elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) +#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // localtime() is required to work as if tzset() was called before it. // localtime_r() does not have this requirement, so make an explicit call. qt_tzset(); @@ -2574,240 +2482,403 @@ static qint64 localMSecsToEpochMSecs(qint64 localMsecs, } } -/***************************************************************************** - QDateTimePrivate member functions - *****************************************************************************/ +static inline bool specCanBeSmall(Qt::TimeSpec spec) +{ + return spec == Qt::LocalTime || spec == Qt::UTC; +} -QDateTimePrivate::QDateTimePrivate(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec, - int offsetSeconds) - : m_msecs(0), - m_spec(Qt::LocalTime), - m_offsetFromUtc(0), - m_status(0) +static Q_DECL_CONSTEXPR inline +QDateTimePrivate::StatusFlags mergeSpec(QDateTimePrivate::StatusFlags status, Qt::TimeSpec spec) { - setTimeSpec(toSpec, offsetSeconds); - setDateTime(toDate, toTime); + return QDateTimePrivate::StatusFlags((status & ~QDateTimePrivate::TimeSpecMask) | + (int(spec) << QDateTimePrivate::TimeSpecShift)); } -#ifndef QT_BOOTSTRAPPED -QDateTimePrivate::QDateTimePrivate(const QDate &toDate, const QTime &toTime, - const QTimeZone &toTimeZone) - : m_spec(Qt::TimeZone), - m_offsetFromUtc(0), - m_timeZone(toTimeZone), - m_status(0) +static Q_DECL_CONSTEXPR inline Qt::TimeSpec extractSpec(QDateTimePrivate::StatusFlags status) { - setDateTime(toDate, toTime); + return Qt::TimeSpec((status & QDateTimePrivate::TimeSpecMask) >> QDateTimePrivate::TimeSpecShift); } -#endif // QT_BOOTSTRAPPED -void QDateTimePrivate::setTimeSpec(Qt::TimeSpec spec, int offsetSeconds) +// Set the Daylight Status if LocalTime set via msecs +static Q_DECL_RELAXED_CONSTEXPR inline QDateTimePrivate::StatusFlags +mergeDaylightStatus(QDateTimePrivate::StatusFlags sf, QDateTimePrivate::DaylightStatus status) +{ + sf &= ~QDateTimePrivate::DaylightMask; + if (status == QDateTimePrivate::DaylightTime) { + sf |= QDateTimePrivate::SetToDaylightTime; + } else if (status == QDateTimePrivate::StandardTime) { + sf |= QDateTimePrivate::SetToStandardTime; + } + return sf; +} + +// Get the DST Status if LocalTime set via msecs +static Q_DECL_RELAXED_CONSTEXPR inline +QDateTimePrivate::DaylightStatus extractDaylightStatus(QDateTimePrivate::StatusFlags status) { - clearValidDateTime(); - clearSetToDaylightStatus(); + if (status & QDateTimePrivate::SetToDaylightTime) + return QDateTimePrivate::DaylightTime; + if (status & QDateTimePrivate::SetToStandardTime) + return QDateTimePrivate::StandardTime; + return QDateTimePrivate::UnknownDaylightTime; +} + +static inline qint64 getMSecs(const QDateTimeData &d) +{ + if (d.isShort()) { + // same as, but producing better code + //return d.data.msecs; + return qintptr(d.d) >> 8; + } + return d->m_msecs; +} + +static inline QDateTimePrivate::StatusFlags getStatus(const QDateTimeData &d) +{ + if (d.isShort()) { + // same as, but producing better code + //return StatusFlag(d.data.status); + return QDateTimePrivate::StatusFlag(qintptr(d.d) & 0xFF); + } + return d->m_status; +} + +static inline Qt::TimeSpec getSpec(const QDateTimeData &d) +{ + return extractSpec(getStatus(d)); +} + +// Refresh the LocalTime validity and offset +static void refreshDateTime(QDateTimeData &d) +{ + auto status = getStatus(d); + const auto spec = extractSpec(status); + const qint64 msecs = getMSecs(d); + qint64 epochMSecs = 0; + int offsetFromUtc = 0; + QDate testDate; + QTime testTime; + Q_ASSERT(spec == Qt::TimeZone || spec == Qt::LocalTime); #ifndef QT_BOOTSTRAPPED - m_timeZone = QTimeZone(); + // If not valid time zone then is invalid + if (spec == Qt::TimeZone) { + if (!d->m_timeZone.isValid()) + status &= ~QDateTimePrivate::ValidDateTime; + else + epochMSecs = QDateTimePrivate::zoneMSecsToEpochMSecs(msecs, d->m_timeZone, &testDate, &testTime); + } #endif // QT_BOOTSTRAPPED - switch (spec) { - case Qt::OffsetFromUTC: - if (offsetSeconds == 0) { - m_spec = Qt::UTC; - m_offsetFromUtc = 0; + // If not valid date and time then is invalid + if (!(status & QDateTimePrivate::ValidDate) || !(status & QDateTimePrivate::ValidTime)) { + status &= ~QDateTimePrivate::ValidDateTime; + if (status & QDateTimePrivate::ShortData) { + d.data.status = status; } else { - m_spec = Qt::OffsetFromUTC; - m_offsetFromUtc = offsetSeconds; + d->m_status = status; + d->m_offsetFromUtc = 0; } + return; + } + + // We have a valid date and time and a Qt::LocalTime or Qt::TimeZone that needs calculating + // LocalTime and TimeZone might fall into a "missing" DST transition hour + // Calling toEpochMSecs will adjust the returned date/time if it does + if (spec == Qt::LocalTime) { + auto dstStatus = extractDaylightStatus(status); + epochMSecs = localMSecsToEpochMSecs(msecs, &dstStatus, &testDate, &testTime); + } + if (timeToMSecs(testDate, testTime) == msecs) { + status |= QDateTimePrivate::ValidDateTime; + // Cache the offset to use in offsetFromUtc() + offsetFromUtc = (msecs - epochMSecs) / 1000; + } else { + status &= ~QDateTimePrivate::ValidDateTime; + } + + if (status & QDateTimePrivate::ShortData) { + d.data.status = status; + } else { + d->m_status = status; + d->m_offsetFromUtc = offsetFromUtc; + } +} + +// Check the UTC / offsetFromUTC validity +static void checkValidDateTime(QDateTimeData &d) +{ + auto status = getStatus(d); + auto spec = extractSpec(status); + switch (spec) { + case Qt::OffsetFromUTC: + case Qt::UTC: + // for these, a valid date and a valid time imply a valid QDateTime + if ((status & QDateTimePrivate::ValidDate) && (status & QDateTimePrivate::ValidTime)) + status |= QDateTimePrivate::ValidDateTime; + else + status &= ~QDateTimePrivate::ValidDateTime; + if (status & QDateTimePrivate::ShortData) + d.data.status = status; + else + d->m_status = status; break; case Qt::TimeZone: - // Use system time zone instead - m_spec = Qt::LocalTime; - m_offsetFromUtc = 0; + case Qt::LocalTime: + // for these, we need to check whether the timezone is valid and whether + // the time is valid in that timezone. Expensive, but no other option. + refreshDateTime(d); break; + } +} + +static void setTimeSpec(QDateTimeData &d, Qt::TimeSpec spec, int offsetSeconds) +{ + auto status = getStatus(d); + status &= ~(QDateTimePrivate::ValidDateTime | QDateTimePrivate::DaylightMask | + QDateTimePrivate::TimeSpecMask); + + switch (spec) { + case Qt::OffsetFromUTC: + if (offsetSeconds == 0) + spec = Qt::UTC; + break; + case Qt::TimeZone: + // Use system time zone instead + spec = Qt::LocalTime; + // fallthrough case Qt::UTC: case Qt::LocalTime: - m_spec = spec; - m_offsetFromUtc = 0; + offsetSeconds = 0; break; } + + status = mergeSpec(status, spec); + if (d.isShort() && offsetSeconds == 0) { + d.data.status = status; + } else { + d.detach(); + d->m_status = status & ~QDateTimePrivate::ShortData; + d->m_offsetFromUtc = offsetSeconds; +#ifndef QT_BOOTSTRAPPED + d->m_timeZone = QTimeZone(); +#endif // QT_BOOTSTRAPPED + } } -void QDateTimePrivate::setDateTime(const QDate &date, const QTime &time) +static void setDateTime(QDateTimeData &d, const QDate &date, const QTime &time) { // If the date is valid and the time is not we set time to 00:00:00 QTime useTime = time; if (!useTime.isValid() && date.isValid()) useTime = QTime::fromMSecsSinceStartOfDay(0); - StatusFlags newStatus; + QDateTimePrivate::StatusFlags newStatus = 0; // Set date value and status qint64 days = 0; if (date.isValid()) { days = date.toJulianDay() - JULIAN_DAY_FOR_EPOCH; - newStatus = ValidDate; - } else if (date.isNull()) { - newStatus = NullDate; + newStatus = QDateTimePrivate::ValidDate; } // Set time value and status int ds = 0; if (useTime.isValid()) { ds = useTime.msecsSinceStartOfDay(); - newStatus |= ValidTime; - } else if (time.isNull()) { - newStatus |= NullTime; + newStatus |= QDateTimePrivate::ValidTime; } // Set msecs serial value - m_msecs = (days * MSECS_PER_DAY) + ds; - m_status = newStatus; + qint64 msecs = (days * MSECS_PER_DAY) + ds; + if (d.isShort()) { + // let's see if we can keep this short + d.data.msecs = qintptr(msecs); + if (d.data.msecs == msecs) { + // yes, we can + d.data.status &= ~(QDateTimePrivate::ValidityMask | QDateTimePrivate::DaylightMask); + d.data.status |= newStatus; + } else { + // nope... + d.detach(); + } + } + if (!d.isShort()) { + d.detach(); + d->m_msecs = msecs; + d->m_status &= ~(QDateTimePrivate::ValidityMask | QDateTimePrivate::DaylightMask); + d->m_status |= newStatus; + } // Set if date and time are valid - checkValidDateTime(); + checkValidDateTime(d); } -QPair<QDate, QTime> QDateTimePrivate::getDateTime() const +static QPair<QDate, QTime> getDateTime(const QDateTimeData &d) { QPair<QDate, QTime> result; - msecsToTime(m_msecs, &result.first, &result.second); + qint64 msecs = getMSecs(d); + auto status = getStatus(d); + msecsToTime(msecs, &result.first, &result.second); - if (isNullDate()) + if (!status.testFlag(QDateTimePrivate::ValidDate)) result.first = QDate(); - if (isNullTime()) + if (!status.testFlag(QDateTimePrivate::ValidTime)) result.second = QTime(); return result; } -// Set the Daylight Status if LocalTime set via msecs -void QDateTimePrivate::setDaylightStatus(QDateTimePrivate::DaylightStatus status) -{ - if (status == DaylightTime) { - m_status = m_status & ~SetToStandardTime; - m_status = m_status | SetToDaylightTime; - } else if (status == StandardTime) { - m_status = m_status & ~SetToDaylightTime; - m_status = m_status | SetToStandardTime; +/***************************************************************************** + QDateTime::Data member functions + *****************************************************************************/ + +inline QDateTime::Data::Data(Qt::TimeSpec spec) +{ + if (CanBeSmall && Q_LIKELY(specCanBeSmall(spec))) { + d = reinterpret_cast<QDateTimePrivate *>(quintptr(mergeSpec(QDateTimePrivate::ShortData, spec))); } else { - clearSetToDaylightStatus(); + // the structure is too small, we need to detach + d = new QDateTimePrivate; + d->ref.ref(); + d->m_status = mergeSpec(0, spec); } } -// Get the DST Status if LocalTime set via msecs -QDateTimePrivate::DaylightStatus QDateTimePrivate::daylightStatus() const +inline QDateTime::Data::Data(const Data &other) + : d(other.d) { - if ((m_status & SetToDaylightTime) == SetToDaylightTime) - return DaylightTime; - if ((m_status & SetToStandardTime) == SetToStandardTime) - return StandardTime; - return UnknownDaylightTime; + if (!isShort()) { + // check if we could shrink + ShortData sd; + sd.msecs = qintptr(d->m_msecs); + if (CanBeSmall && specCanBeSmall(extractSpec(d->m_status)) && sd.msecs == d->m_msecs) { + sd.status = d->m_status | QDateTimePrivate::ShortData; + data = sd; + } else { + // no, have to keep it big + d->ref.ref(); + } + } } -qint64 QDateTimePrivate::toMSecsSinceEpoch() const +inline QDateTime::Data::Data(Data &&other) + : d(other.d) { - switch (m_spec) { - case Qt::OffsetFromUTC: - case Qt::UTC: - return (m_msecs - (m_offsetFromUtc * 1000)); - - case Qt::LocalTime: { - // recalculate the local timezone - DaylightStatus status = daylightStatus(); - return localMSecsToEpochMSecs(m_msecs, &status); + // reset the other to a short state, if we can + if (CanBeSmall) { + Data dummy(Qt::LocalTime); + Q_ASSERT(dummy.isShort()); + other.d = dummy.d; + } else if (!isShort()) { + // can't be small, so do implicit sharing + d->ref.ref(); } +} - case Qt::TimeZone: -#ifdef QT_BOOTSTRAPPED - break; -#else - return zoneMSecsToEpochMSecs(m_msecs, m_timeZone); -#endif +inline QDateTime::Data &QDateTime::Data::operator=(const Data &other) +{ + if (d == other.d) + return *this; + + auto x = d; + d = other.d; + if (!other.isShort()) { + // check if we could shrink + ShortData sd; + sd.msecs = qintptr(other.d->m_msecs); + if (CanBeSmall && specCanBeSmall(extractSpec(other.d->m_status)) && sd.msecs == other.d->m_msecs) { + sd.status = other.d->m_status | QDateTimePrivate::ShortData; + data = sd; + } else { + // no, have to keep it big + other.d->ref.ref(); + } } - Q_UNREACHABLE(); - return 0; + + if (!(CanBeSmall && quintptr(x) & QDateTimePrivate::ShortData) && !x->ref.deref()) + delete x; + return *this; } -// Check the UTC / offsetFromUTC validity -void QDateTimePrivate::checkValidDateTime() +inline QDateTime::Data::~Data() { - switch (m_spec) { - case Qt::OffsetFromUTC: - case Qt::UTC: - // for these, a valid date and a valid time imply a valid QDateTime - if (isValidDate() && isValidTime()) - setValidDateTime(); - else - clearValidDateTime(); - break; - case Qt::TimeZone: - case Qt::LocalTime: - // for these, we need to check whether the timezone is valid and whether - // the time is valid in that timezone. Expensive, but no other option. - refreshDateTime(); - break; - } + if (!isShort() && !d->ref.deref()) + delete d; } -// Refresh the LocalTime validity and offset -void QDateTimePrivate::refreshDateTime() +inline bool QDateTime::Data::isShort() const { - switch (m_spec) { - case Qt::OffsetFromUTC: - case Qt::UTC: - // Always set by setDateTime so just return - return; - case Qt::TimeZone: - case Qt::LocalTime: - break; - } + return CanBeSmall && quintptr(d) & QDateTimePrivate::ShortData; +} - // If not valid date and time then is invalid - if (!isValidDate() || !isValidTime()) { - clearValidDateTime(); - m_offsetFromUtc = 0; - return; - } +inline void QDateTime::Data::detach() +{ + QDateTimePrivate *x; + bool wasShort = isShort(); + if (wasShort) { + // force enlarging + x = new QDateTimePrivate; + x->m_status = QDateTimePrivate::StatusFlag(data.status & ~QDateTimePrivate::ShortData); + x->m_msecs = data.msecs; + } else { + if (d->ref.load() == 1) + return; -#ifndef QT_BOOTSTRAPPED - // If not valid time zone then is invalid - if (m_spec == Qt::TimeZone && !m_timeZone.isValid()) { - clearValidDateTime(); - m_offsetFromUtc = 0; - return; + x = new QDateTimePrivate(*d); } -#endif // QT_BOOTSTRAPPED - // We have a valid date and time and a Qt::LocalTime or Qt::TimeZone that needs calculating - // LocalTime and TimeZone might fall into a "missing" DST transition hour - // Calling toEpochMSecs will adjust the returned date/time if it does - QDate testDate; - QTime testTime; - qint64 epochMSecs = 0; - if (m_spec == Qt::LocalTime) { - DaylightStatus status = daylightStatus(); - epochMSecs = localMSecsToEpochMSecs(m_msecs, &status, &testDate, &testTime); -#ifndef QT_BOOTSTRAPPED - } else { - epochMSecs = zoneMSecsToEpochMSecs(m_msecs, m_timeZone, &testDate, &testTime); -#endif // QT_BOOTSTRAPPED - } - if (timeToMSecs(testDate, testTime) == m_msecs) { - setValidDateTime(); - // Cache the offset to use in toMSecsSinceEpoch() - m_offsetFromUtc = (m_msecs - epochMSecs) / 1000; - } else { - clearValidDateTime(); - m_offsetFromUtc = 0; - } + x->ref.store(1); + if (!wasShort && !d->ref.deref()) + delete d; + d = x; +} + +inline const QDateTimePrivate *QDateTime::Data::operator->() const +{ + Q_ASSERT(!isShort()); + return d; +} + +inline QDateTimePrivate *QDateTime::Data::operator->() +{ + // should we attempt to detach here? + Q_ASSERT(!isShort()); + Q_ASSERT(d->ref.load() == 1); + return d; +} + +/***************************************************************************** + QDateTimePrivate member functions + *****************************************************************************/ + +Q_NEVER_INLINE +QDateTime::Data QDateTimePrivate::create(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec, + int offsetSeconds) +{ + QDateTime::Data result(toSpec); + setTimeSpec(result, toSpec, offsetSeconds); + setDateTime(result, toDate, toTime); + return result; } #ifndef QT_BOOTSTRAPPED +inline QDateTime::Data QDateTimePrivate::create(const QDate &toDate, const QTime &toTime, + const QTimeZone &toTimeZone) +{ + QDateTime::Data result(Qt::TimeZone); + Q_ASSERT(!result.isShort()); + + result.d->m_status = mergeSpec(result.d->m_status, Qt::TimeZone); + result.d->m_timeZone = toTimeZone; + setDateTime(result, toDate, toTime); + return result; +} + // Convert a TimeZone time expressed in zone msecs encoding into a UTC epoch msecs -qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QTimeZone &zone, - QDate *localDate, QTime *localTime) +inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QTimeZone &zone, + QDate *localDate, QTime *localTime) { // Get the effective data from QTimeZone QTimeZonePrivate::Data data = zone.d->dataForLocalTime(zoneMSecs); @@ -2958,8 +3029,8 @@ qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QTimeZone \sa isValid() */ -QDateTime::QDateTime() - : d(*defaultDateTimePrivate()) +QDateTime::QDateTime() Q_DECL_NOEXCEPT_EXPR(Data::CanBeSmall) + : d(Qt::LocalTime) { } @@ -2970,7 +3041,7 @@ QDateTime::QDateTime() */ QDateTime::QDateTime(const QDate &date) - : d(new QDateTimePrivate(date, QTime(0, 0, 0), Qt::LocalTime, 0)) + : d(QDateTimePrivate::create(date, QTime(0, 0, 0), Qt::LocalTime, 0)) { } @@ -2990,7 +3061,7 @@ QDateTime::QDateTime(const QDate &date) */ QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec) - : d(new QDateTimePrivate(date, time, spec, 0)) + : d(QDateTimePrivate::create(date, time, spec, 0)) { } @@ -3013,7 +3084,7 @@ QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec) */ QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds) - : d(new QDateTimePrivate(date, time, spec, offsetSeconds)) + : d(QDateTimePrivate::create(date, time, spec, offsetSeconds)) { } @@ -3030,7 +3101,7 @@ QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, in */ QDateTime::QDateTime(const QDate &date, const QTime &time, const QTimeZone &timeZone) - : d(new QDateTimePrivate(date, time, timeZone)) + : d(QDateTimePrivate::create(date, time, timeZone)) { } #endif // QT_BOOTSTRAPPED @@ -3038,13 +3109,22 @@ QDateTime::QDateTime(const QDate &date, const QTime &time, const QTimeZone &time /*! Constructs a copy of the \a other datetime. */ - -QDateTime::QDateTime(const QDateTime &other) +QDateTime::QDateTime(const QDateTime &other) Q_DECL_NOTHROW : d(other.d) { } /*! + \since 5.8 + Moves the content of the temporary \a other datetime to this object and + leaves \a other in an unspecified (but proper) state. +*/ +QDateTime::QDateTime(QDateTime &&other) Q_DECL_NOTHROW + : d(std::move(other.d)) +{ +} + +/*! Destroys the datetime. */ QDateTime::~QDateTime() @@ -3056,7 +3136,7 @@ QDateTime::~QDateTime() copy. */ -QDateTime &QDateTime::operator=(const QDateTime &other) +QDateTime &QDateTime::operator=(const QDateTime &other) Q_DECL_NOTHROW { d = other.d; return *this; @@ -3078,7 +3158,9 @@ QDateTime &QDateTime::operator=(const QDateTime &other) bool QDateTime::isNull() const { - return d->isNullDate() && d->isNullTime(); + auto status = getStatus(d); + return !status.testFlag(QDateTimePrivate::ValidDate) && + !status.testFlag(QDateTimePrivate::ValidTime); } /*! @@ -3095,7 +3177,8 @@ bool QDateTime::isNull() const bool QDateTime::isValid() const { - return (d->isValidDateTime()); + auto status = getStatus(d); + return status & QDateTimePrivate::ValidDateTime; } /*! @@ -3106,10 +3189,11 @@ bool QDateTime::isValid() const QDate QDateTime::date() const { - if (d->isNullDate()) + auto status = getStatus(d); + if (!status.testFlag(QDateTimePrivate::ValidDate)) return QDate(); QDate dt; - msecsToTime(d->m_msecs, &dt, 0); + msecsToTime(getMSecs(d), &dt, 0); return dt; } @@ -3121,10 +3205,11 @@ QDate QDateTime::date() const QTime QDateTime::time() const { - if (d->isNullTime()) + auto status = getStatus(d); + if (!status.testFlag(QDateTimePrivate::ValidTime)) return QTime(); QTime tm; - msecsToTime(d->m_msecs, 0, &tm); + msecsToTime(getMSecs(d), 0, &tm); return tm; } @@ -3136,7 +3221,7 @@ QTime QDateTime::time() const Qt::TimeSpec QDateTime::timeSpec() const { - return d->m_spec; + return getSpec(d); } #ifndef QT_BOOTSTRAPPED @@ -3154,7 +3239,7 @@ Qt::TimeSpec QDateTime::timeSpec() const QTimeZone QDateTime::timeZone() const { - switch (d->m_spec) { + switch (getSpec(d)) { case Qt::UTC: return QTimeZone::utc(); case Qt::OffsetFromUTC: @@ -3189,7 +3274,20 @@ QTimeZone QDateTime::timeZone() const int QDateTime::offsetFromUtc() const { - return d->m_offsetFromUtc; + if (!d.isShort()) + return d->m_offsetFromUtc; + if (!isValid()) + return 0; + + auto spec = getSpec(d); + if (spec == Qt::LocalTime) { + // we didn't cache the value, so we need to calculate it now... + qint64 msecs = getMSecs(d); + return (msecs - toMSecsSinceEpoch()) / 1000; + } + + Q_ASSERT(spec == Qt::UTC); + return 0; } /*! @@ -3215,7 +3313,7 @@ int QDateTime::offsetFromUtc() const QString QDateTime::timeZoneAbbreviation() const { - switch (d->m_spec) { + switch (getSpec(d)) { case Qt::UTC: return QTimeZonePrivate::utcQString(); case Qt::OffsetFromUTC: @@ -3224,12 +3322,12 @@ QString QDateTime::timeZoneAbbreviation() const #ifdef QT_BOOTSTRAPPED break; #else - return d->m_timeZone.d->abbreviation(d->toMSecsSinceEpoch()); + return d->m_timeZone.d->abbreviation(toMSecsSinceEpoch()); #endif // QT_BOOTSTRAPPED case Qt::LocalTime: { QString abbrev; - QDateTimePrivate::DaylightStatus status = d->daylightStatus(); - localMSecsToEpochMSecs(d->m_msecs, &status, 0, 0, &abbrev); + auto status = extractDaylightStatus(getStatus(d)); + localMSecsToEpochMSecs(getMSecs(d), &status, 0, 0, &abbrev); return abbrev; } } @@ -3249,7 +3347,7 @@ QString QDateTime::timeZoneAbbreviation() const bool QDateTime::isDaylightTime() const { - switch (d->m_spec) { + switch (getSpec(d)) { case Qt::UTC: case Qt::OffsetFromUTC: return false; @@ -3260,9 +3358,9 @@ bool QDateTime::isDaylightTime() const return d->m_timeZone.d->isDaylightTime(toMSecsSinceEpoch()); #endif // QT_BOOTSTRAPPED case Qt::LocalTime: { - QDateTimePrivate::DaylightStatus status = d->daylightStatus(); + auto status = extractDaylightStatus(getStatus(d)); if (status == QDateTimePrivate::UnknownDaylightTime) - localMSecsToEpochMSecs(d->m_msecs, &status); + localMSecsToEpochMSecs(getMSecs(d), &status); return (status == QDateTimePrivate::DaylightTime); } } @@ -3278,7 +3376,7 @@ bool QDateTime::isDaylightTime() const void QDateTime::setDate(const QDate &date) { - d->setDateTime(date, time()); + setDateTime(d, date, time()); } /*! @@ -3296,7 +3394,7 @@ void QDateTime::setDate(const QDate &date) void QDateTime::setTime(const QTime &time) { - d->setDateTime(date(), time); + setDateTime(d, date(), time); } /*! @@ -3317,9 +3415,8 @@ void QDateTime::setTime(const QTime &time) void QDateTime::setTimeSpec(Qt::TimeSpec spec) { - QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) - d->setTimeSpec(spec, 0); - d->checkValidDateTime(); + QT_PREPEND_NAMESPACE(setTimeSpec(d, spec, 0)); + checkValidDateTime(d); } /*! @@ -3339,9 +3436,8 @@ void QDateTime::setTimeSpec(Qt::TimeSpec spec) void QDateTime::setOffsetFromUtc(int offsetSeconds) { - QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) - d->setTimeSpec(Qt::OffsetFromUTC, offsetSeconds); - d->checkValidDateTime(); + QT_PREPEND_NAMESPACE(setTimeSpec(d, Qt::OffsetFromUTC, offsetSeconds)); + checkValidDateTime(d); } #ifndef QT_BOOTSTRAPPED @@ -3358,11 +3454,11 @@ void QDateTime::setOffsetFromUtc(int offsetSeconds) void QDateTime::setTimeZone(const QTimeZone &toZone) { - QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) - d->m_spec = Qt::TimeZone; + d.detach(); // always detach + d->m_status = mergeSpec(d->m_status, Qt::TimeZone); d->m_offsetFromUtc = 0; d->m_timeZone = toZone; - d->refreshDateTime(); + refreshDateTime(d); } #endif // QT_BOOTSTRAPPED @@ -3383,7 +3479,28 @@ void QDateTime::setTimeZone(const QTimeZone &toZone) */ qint64 QDateTime::toMSecsSinceEpoch() const { - return d->toMSecsSinceEpoch(); + switch (getSpec(d)) { + case Qt::UTC: + return getMSecs(d); + + case Qt::OffsetFromUTC: + return d->m_msecs - (d->m_offsetFromUtc * 1000); + + case Qt::LocalTime: { + // recalculate the local timezone + auto status = extractDaylightStatus(getStatus(d)); + return localMSecsToEpochMSecs(getMSecs(d), &status); + } + + case Qt::TimeZone: +#ifdef QT_BOOTSTRAPPED + break; +#else + return QDateTimePrivate::zoneMSecsToEpochMSecs(d->m_msecs, d->m_timeZone); +#endif + } + Q_UNREACHABLE(); + return 0; } /*! @@ -3412,7 +3529,7 @@ uint QDateTime::toTime_t() const { if (!isValid()) return uint(-1); - qint64 retval = d->toMSecsSinceEpoch() / 1000; + qint64 retval = toMSecsSinceEpoch() / 1000; if (quint64(retval) >= Q_UINT64_C(0xFFFFFFFF)) return uint(-1); return uint(retval); @@ -3434,51 +3551,67 @@ uint QDateTime::toTime_t() const */ void QDateTime::setMSecsSinceEpoch(qint64 msecs) { - QDateTimePrivate *d = this->d.data(); // detaches (and shadows d) + const auto spec = getSpec(d); + auto status = getStatus(d); - d->m_status = 0; - switch (d->m_spec) { + status &= ~QDateTimePrivate::ValidityMask; + switch (spec) { case Qt::UTC: - d->m_msecs = msecs; - d->m_status = d->m_status + status = status | QDateTimePrivate::ValidDate | QDateTimePrivate::ValidTime | QDateTimePrivate::ValidDateTime; break; case Qt::OffsetFromUTC: - d->m_msecs = msecs + (d->m_offsetFromUtc * 1000); - d->m_status = d->m_status + msecs = msecs + (d->m_offsetFromUtc * 1000); + status = status | QDateTimePrivate::ValidDate | QDateTimePrivate::ValidTime | QDateTimePrivate::ValidDateTime; break; case Qt::TimeZone: + Q_ASSERT(!d.isShort()); #ifndef QT_BOOTSTRAPPED // Docs state any LocalTime before 1970-01-01 will *not* have any DST applied // but all affected times afterwards will have DST applied. + d.detach(); if (msecs >= 0) d->m_offsetFromUtc = d->m_timeZone.d->offsetFromUtc(msecs); else d->m_offsetFromUtc = d->m_timeZone.d->standardTimeOffset(msecs); - d->m_msecs = msecs + (d->m_offsetFromUtc * 1000); - d->m_status = d->m_status + msecs = msecs + (d->m_offsetFromUtc * 1000); + status = status | QDateTimePrivate::ValidDate | QDateTimePrivate::ValidTime | QDateTimePrivate::ValidDateTime; - d->refreshDateTime(); #endif // QT_BOOTSTRAPPED break; case Qt::LocalTime: { QDate dt; QTime tm; - QDateTimePrivate::DaylightStatus status; - epochMSecsToLocalTime(msecs, &dt, &tm, &status); - d->setDateTime(dt, tm); - d->setDaylightStatus(status); - d->refreshDateTime(); + QDateTimePrivate::DaylightStatus dstStatus; + epochMSecsToLocalTime(msecs, &dt, &tm, &dstStatus); + setDateTime(d, dt, tm); + msecs = getMSecs(d); + status = mergeDaylightStatus(getStatus(d), dstStatus); break; } } + + ShortData sd; + sd.msecs = msecs; + if (d.isShort() && sd.msecs == msecs) { + // we can keep short + sd.status = status; + d.data = sd; + } else { + d.detach(); + d->m_status = status; + d->m_msecs = msecs; + } + + if (spec == Qt::LocalTime || spec == Qt::TimeZone) + refreshDateTime(d); } /*! @@ -3565,13 +3698,13 @@ QString QDateTime::toString(Qt::DateFormat format) const return QLocale().toString(*this, QLocale::LongFormat); case Qt::RFC2822Date: { buf = QLocale::c().toString(*this, QStringLiteral("dd MMM yyyy hh:mm:ss ")); - buf += toOffsetString(Qt::TextDate, d->m_offsetFromUtc); + buf += toOffsetString(Qt::TextDate, offsetFromUtc()); return buf; } default: #ifndef QT_NO_TEXTDATE case Qt::TextDate: { - const QPair<QDate, QTime> p = d->getDateTime(); + const QPair<QDate, QTime> p = getDateTime(d); const QDate &dt = p.first; const QTime &tm = p.second; //We cant use date.toString(Qt::TextDate) as we need to insert the time before the year @@ -3582,14 +3715,14 @@ QString QDateTime::toString(Qt::DateFormat format) const .arg(dt.year()); if (timeSpec() != Qt::LocalTime) { buf += QStringLiteral(" GMT"); - if (d->m_spec == Qt::OffsetFromUTC) - buf += toOffsetString(Qt::TextDate, d->m_offsetFromUtc); + if (getSpec(d) == Qt::OffsetFromUTC) + buf += toOffsetString(Qt::TextDate, offsetFromUtc()); } return buf; } #endif case Qt::ISODate: { - const QPair<QDate, QTime> p = d->getDateTime(); + const QPair<QDate, QTime> p = getDateTime(d); const QDate &dt = p.first; const QTime &tm = p.second; buf = dt.toString(Qt::ISODate); @@ -3597,12 +3730,12 @@ QString QDateTime::toString(Qt::DateFormat format) const return QString(); // failed to convert buf += QLatin1Char('T'); buf += tm.toString(Qt::ISODate); - switch (d->m_spec) { + switch (getSpec(d)) { case Qt::UTC: buf += QLatin1Char('Z'); break; case Qt::OffsetFromUTC: - buf += toOffsetString(Qt::ISODate, d->m_offsetFromUtc); + buf += toOffsetString(Qt::ISODate, offsetFromUtc()); break; default: break; @@ -3691,12 +3824,7 @@ QString QDateTime::toString(const QString& format) const } #endif //QT_NO_DATESTRING -static void massageAdjustedDateTime(Qt::TimeSpec spec, -#ifndef QT_BOOTSTRAPPED - const QTimeZone &zone, -#endif // QT_BOOTSTRAPPED - QDate *date, - QTime *time) +static inline void massageAdjustedDateTime(const QDateTimeData &d, QDate *date, QTime *time) { /* If we have just adjusted to a day with a DST transition, our given time @@ -3706,24 +3834,20 @@ static void massageAdjustedDateTime(Qt::TimeSpec spec, to its DST-ness); but for a time in spring's missing hour it'll adjust the time while picking a DST-ness. (Handling of autumn is trickier, as either DST-ness is valid, without adjusting the time. We might want to propagate - d->daylightStatus() in that case, but it's hard to do so without breaking + the daylight status in that case, but it's hard to do so without breaking (far more common) other cases; and it makes little difference, as the two answers do then differ only in DST-ness.) */ + auto spec = getSpec(d); if (spec == Qt::LocalTime) { QDateTimePrivate::DaylightStatus status = QDateTimePrivate::UnknownDaylightTime; localMSecsToEpochMSecs(timeToMSecs(*date, *time), &status, date, time); #ifndef QT_BOOTSTRAPPED } else if (spec == Qt::TimeZone) { - QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(*date, *time), zone, date, time); + QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(*date, *time), d->m_timeZone, date, time); #endif // QT_BOOTSTRAPPED } } -#ifdef QT_BOOTSTRAPPED // Avoid duplicate #if-ery in uses. -#define MASSAGEADJUSTEDDATETIME(s, z, d, t) massageAdjustedDateTime(s, d, t) -#else -#define MASSAGEADJUSTEDDATETIME(s, z, d, t) massageAdjustedDateTime(s, z, d, t) -#endif // QT_BOOTSTRAPPED /*! Returns a QDateTime object containing a datetime \a ndays days @@ -3742,12 +3866,12 @@ static void massageAdjustedDateTime(Qt::TimeSpec spec, QDateTime QDateTime::addDays(qint64 ndays) const { QDateTime dt(*this); - QPair<QDate, QTime> p = d->getDateTime(); + QPair<QDate, QTime> p = getDateTime(d); QDate &date = p.first; QTime &time = p.second; date = date.addDays(ndays); - MASSAGEADJUSTEDDATETIME(d->m_spec, d->m_timeZone, &date, &time); - dt.d->setDateTime(date, time); + massageAdjustedDateTime(dt.d, &date, &time); + setDateTime(dt.d, date, time); return dt; } @@ -3768,12 +3892,12 @@ QDateTime QDateTime::addDays(qint64 ndays) const QDateTime QDateTime::addMonths(int nmonths) const { QDateTime dt(*this); - QPair<QDate, QTime> p = d->getDateTime(); + QPair<QDate, QTime> p = getDateTime(d); QDate &date = p.first; QTime &time = p.second; date = date.addMonths(nmonths); - MASSAGEADJUSTEDDATETIME(d->m_spec, d->m_timeZone, &date, &time); - dt.d->setDateTime(date, time); + massageAdjustedDateTime(dt.d, &date, &time); + setDateTime(dt.d, date, time); return dt; } @@ -3794,15 +3918,14 @@ QDateTime QDateTime::addMonths(int nmonths) const QDateTime QDateTime::addYears(int nyears) const { QDateTime dt(*this); - QPair<QDate, QTime> p = d->getDateTime(); + QPair<QDate, QTime> p = getDateTime(d); QDate &date = p.first; QTime &time = p.second; date = date.addYears(nyears); - MASSAGEADJUSTEDDATETIME(d->m_spec, d->m_timeZone, &date, &time); - dt.d->setDateTime(date, time); + massageAdjustedDateTime(dt.d, &date, &time); + setDateTime(dt.d, date, time); return dt; } -#undef MASSAGEADJUSTEDDATETIME /*! Returns a QDateTime object containing a datetime \a s seconds @@ -3834,12 +3957,25 @@ QDateTime QDateTime::addMSecs(qint64 msecs) const return QDateTime(); QDateTime dt(*this); - if (d->m_spec == Qt::LocalTime || d->m_spec == Qt::TimeZone) + auto spec = getSpec(d); + if (spec == Qt::LocalTime || spec == Qt::TimeZone) { // Convert to real UTC first in case crosses DST transition - dt.setMSecsSinceEpoch(d->toMSecsSinceEpoch() + msecs); - else + dt.setMSecsSinceEpoch(toMSecsSinceEpoch() + msecs); + } else { // No need to convert, just add on - dt.d->m_msecs = dt.d->m_msecs + msecs; + if (d.isShort()) { + // need to check if we need to enlarge first + msecs += dt.d.data.msecs; + dt.d.data.msecs = qintptr(msecs); + if (dt.d.data.msecs != msecs) { + dt.d.detach(); + dt.d->m_msecs = msecs; + } + } else { + dt.d.detach(); + dt.d->m_msecs += msecs; + } + } return dt; } @@ -3905,7 +4041,7 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const if (!isValid() || !other.isValid()) return 0; - return other.d->toMSecsSinceEpoch() - d->toMSecsSinceEpoch(); + return other.toMSecsSinceEpoch() - toMSecsSinceEpoch(); } /*! @@ -3928,7 +4064,7 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const { - if (d->m_spec == spec && (spec == Qt::UTC || spec == Qt::LocalTime)) + if (getSpec(d) == spec && (spec == Qt::UTC || spec == Qt::LocalTime)) return *this; if (!isValid()) { @@ -3937,7 +4073,7 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const return ret; } - return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), spec, 0); + return fromMSecsSinceEpoch(toMSecsSinceEpoch(), spec, 0); } /*! @@ -3955,7 +4091,8 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const { - if (d->m_spec == Qt::OffsetFromUTC && d->m_offsetFromUtc == offsetSeconds) + if (getSpec(d) == Qt::OffsetFromUTC + && d->m_offsetFromUtc == offsetSeconds) return *this; if (!isValid()) { @@ -3964,7 +4101,7 @@ QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const return ret; } - return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds); + return fromMSecsSinceEpoch(toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds); } #ifndef QT_BOOTSTRAPPED @@ -3978,7 +4115,7 @@ QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const { - if (d->m_spec == Qt::TimeZone && d->m_timeZone == timeZone) + if (getSpec(d) == Qt::TimeZone && d->m_timeZone == timeZone) return *this; if (!isValid()) { @@ -3987,7 +4124,7 @@ QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const return ret; } - return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), timeZone); + return fromMSecsSinceEpoch(toMSecsSinceEpoch(), timeZone); } #endif // QT_BOOTSTRAPPED @@ -4000,10 +4137,9 @@ QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const bool QDateTime::operator==(const QDateTime &other) const { - if (d->m_spec == Qt::LocalTime - && other.d->m_spec == Qt::LocalTime - && d->m_status == other.d->m_status) { - return (d->m_msecs == other.d->m_msecs); + if (getSpec(d) == Qt::LocalTime + && getStatus(d) == getStatus(other.d)) { + return getMSecs(d) == getMSecs(other.d); } // Convert to UTC and compare return (toMSecsSinceEpoch() == other.toMSecsSinceEpoch()); @@ -4028,10 +4164,9 @@ bool QDateTime::operator==(const QDateTime &other) const bool QDateTime::operator<(const QDateTime &other) const { - if (d->m_spec == Qt::LocalTime - && other.d->m_spec == Qt::LocalTime - && d->m_status == other.d->m_status) { - return (d->m_msecs < other.d->m_msecs); + if (getSpec(d) == Qt::LocalTime + && getStatus(d) == getStatus(other.d)) { + return getMSecs(d) < getMSecs(other.d); } // Convert to UTC and compare return (toMSecsSinceEpoch() < other.toMSecsSinceEpoch()); @@ -4109,9 +4244,6 @@ QTime QTime::currentTime() memset(&st, 0, sizeof(SYSTEMTIME)); GetLocalTime(&st); ct.setHMS(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); -#if defined(Q_OS_WINCE) - ct.startTick = GetTickCount() % MSECS_PER_DAY; -#endif return ct; } @@ -4186,39 +4318,6 @@ qint64 QDateTime::currentMSecsSinceEpoch() Q_DECL_NOTHROW #error "What system is this?" #endif -/*! \fn QDateTime QDateTime::fromCFDate(CFDateRef date) - \since 5.5 - - Constructs a new QDateTime containing a copy of the CFDate \a date. - - \sa toCFDate() -*/ - -/*! \fn CFDateRef QDateTime::toCFDate() const - \since 5.5 - - Creates a CFDate from a QDateTime. The caller owns the CFDate object - and is responsible for releasing it. - - \sa fromCFDate() -*/ - -/*! \fn QDateTime QDateTime::fromNSDate(const NSDate *date) - \since 5.5 - - Constructs a new QDateTime containing a copy of the NSDate \a date. - - \sa toNSDate() -*/ - -/*! \fn NSDate QDateTime::toNSDate() const - \since 5.5 - - Creates an NSDate from a QDateTime. The NSDate object is autoreleased. - - \sa fromNSDate() -*/ - /*! \since 4.2 @@ -4310,7 +4409,7 @@ QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs) QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetSeconds) { QDateTime dt; - dt.d->setTimeSpec(spec, offsetSeconds); + QT_PREPEND_NAMESPACE(setTimeSpec(dt.d, spec, offsetSeconds)); dt.setMSecsSinceEpoch(msecs); return dt; } @@ -4817,7 +4916,7 @@ QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime) if (out.version() >= QDataStream::Qt_5_2) { // In 5.2 we switched to using Qt::TimeSpec and added offset support - dateAndTime = dateTime.d->getDateTime(); + dateAndTime = getDateTime(dateTime.d); out << dateAndTime << qint8(dateTime.timeSpec()); if (dateTime.timeSpec() == Qt::OffsetFromUTC) out << qint32(dateTime.offsetFromUtc()); @@ -4832,13 +4931,13 @@ QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime) // This approach is wrong and should not be used again; it breaks // the guarantee that a deserialised local datetime is the same time // of day, regardless of which timezone it was serialised in. - dateAndTime = (dateTime.isValid() ? dateTime.toUTC() : dateTime).d->getDateTime(); + dateAndTime = getDateTime((dateTime.isValid() ? dateTime.toUTC() : dateTime).d); out << dateAndTime << qint8(dateTime.timeSpec()); } else if (out.version() >= QDataStream::Qt_4_0) { // From 4.0 to 5.1 (except 5.0) we used QDateTimePrivate::Spec - dateAndTime = dateTime.d->getDateTime(); + dateAndTime = getDateTime(dateTime.d); out << dateAndTime; switch (dateTime.timeSpec()) { case Qt::UTC: @@ -4858,7 +4957,7 @@ QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime) } else { // version < QDataStream::Qt_4_0 // Before 4.0 there was no TimeSpec, only Qt::LocalTime was supported - dateAndTime = dateTime.d->getDateTime(); + dateAndTime = getDateTime(dateTime.d); out << dateAndTime; } |