diff options
Diffstat (limited to 'src/corelib/tools/qdatetime.cpp')
-rw-r--r-- | src/corelib/tools/qdatetime.cpp | 115 |
1 files changed, 46 insertions, 69 deletions
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index e5fbf5af5e..505a6f863b 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -560,22 +560,6 @@ int QDate::daysInYear() const January 2000 has week number 52 in the year 1999, and 31 December 2002 has week number 1 in the year 2003. - \legalese - Copyright (c) 1989 The Regents of the University of California. - All rights reserved. - - Redistribution and use in source and binary forms are permitted - provided that the above copyright notice and this paragraph are - duplicated in all such forms and that any documentation, - advertising materials, and other materials related to such - distribution and use acknowledge that the software was developed - by the University of California, Berkeley. The name of the - University may not be used to endorse or promote products derived - from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - \sa isValid() */ @@ -585,46 +569,29 @@ int QDate::weekNumber(int *yearNumber) const return 0; int year = QDate::year(); - int yday = dayOfYear() - 1; + int yday = dayOfYear(); int wday = dayOfWeek(); - if (wday == 7) - wday = 0; - int w; - - for (;;) { - int len; - int bot; - int top; - - len = isLeapYear(year) ? 366 : 365; - /* - ** What yday (-3 ... 3) does - ** the ISO year begin on? - */ - bot = ((yday + 11 - wday) % 7) - 3; - /* - ** What yday does the NEXT - ** ISO year begin on? - */ - top = bot - (len % 7); - if (top < -3) - top += 7; - top += len; - if (yday >= top) { + + int week = (yday - wday + 10) / 7; + + if (week == 0) { + // last week of previous year + --year; + week = (yday + 365 + (QDate::isLeapYear(year) ? 1 : 0) - wday + 10) / 7; + Q_ASSERT(week == 52 || week == 53); + } else if (week == 53) { + // maybe first week of next year + int w = (yday - 365 - (QDate::isLeapYear(year + 1) ? 1 : 0) - wday + 10) / 7; + if (w > 0) { ++year; - w = 1; - break; + week = w; } - if (yday >= bot) { - w = 1 + ((yday - bot) / 7); - break; - } - --year; - yday += isLeapYear(year) ? 366 : 365; + Q_ASSERT(week == 53 || week == 1); } + if (yearNumber != 0) *yearNumber = year; - return w; + return week; } #ifndef QT_NO_TEXTDATE @@ -2473,11 +2440,12 @@ static bool epochMSecsToLocalTime(qint64 msecs, QDate *localDate, QTime *localTi } } -// Convert a LocalTime expressed in local msecs encoding into a UTC epoch msecs -// Optionally populate the returned values from mktime for the adjusted local -// date and time and daylight status. Uses daylightStatus in calculation if populated. -static qint64 localMSecsToEpochMSecs(qint64 localMsecs, QDate *localDate = 0, QTime *localTime = 0, - QDateTimePrivate::DaylightStatus *daylightStatus = 0, +// Convert a LocalTime expressed in local msecs encoding and the corresponding +// daylight status into a UTC epoch msecs. Optionally populate the returned +// values from mktime for the adjusted local date and time. +static qint64 localMSecsToEpochMSecs(qint64 localMsecs, + QDateTimePrivate::DaylightStatus *daylightStatus, + QDate *localDate = 0, QTime *localTime = 0, QString *abbreviation = 0, bool *ok = 0) { QDate dt; @@ -2713,9 +2681,11 @@ qint64 QDateTimePrivate::toMSecsSinceEpoch() const case Qt::UTC: return (m_msecs - (m_offsetFromUtc * 1000)); - case Qt::LocalTime: + case Qt::LocalTime: { // recalculate the local timezone - return localMSecsToEpochMSecs(m_msecs); + DaylightStatus status = daylightStatus(); + return localMSecsToEpochMSecs(m_msecs, &status); + } case Qt::TimeZone: #ifndef QT_BOOTSTRAPPED @@ -2785,7 +2755,7 @@ void QDateTimePrivate::refreshDateTime() qint64 epochMSecs = 0; if (m_spec == Qt::LocalTime) { DaylightStatus status = daylightStatus(); - epochMSecs = localMSecsToEpochMSecs(m_msecs, &testDate, &testTime, &status); + epochMSecs = localMSecsToEpochMSecs(m_msecs, &status, &testDate, &testTime); #ifndef QT_BOOTSTRAPPED } else { epochMSecs = zoneMSecsToEpochMSecs(m_msecs, m_timeZone, &testDate, &testTime); @@ -3223,7 +3193,7 @@ QString QDateTime::timeZoneAbbreviation() const case Qt::LocalTime: { QString abbrev; QDateTimePrivate::DaylightStatus status = d->daylightStatus(); - localMSecsToEpochMSecs(d->m_msecs, 0, 0, &status, &abbrev); + localMSecsToEpochMSecs(d->m_msecs, &status, 0, 0, &abbrev); return abbrev; } } @@ -3254,7 +3224,7 @@ bool QDateTime::isDaylightTime() const case Qt::LocalTime: { QDateTimePrivate::DaylightStatus status = d->daylightStatus(); if (status == QDateTimePrivate::UnknownDaylightTime) - localMSecsToEpochMSecs(d->m_msecs, 0, 0, &status, 0); + localMSecsToEpochMSecs(d->m_msecs, &status); return (status == QDateTimePrivate::DaylightTime); } } @@ -3469,6 +3439,7 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs) epochMSecsToLocalTime(msecs, &dt, &tm, &status); d->setDateTime(dt, tm); d->setDaylightStatus(status); + d->refreshDateTime(); break; } } @@ -3708,12 +3679,14 @@ QDateTime QDateTime::addDays(qint64 ndays) const date = date.addDays(ndays); // Result might fall into "missing" DaylightTime transition hour, // so call conversion and use the adjusted returned time - if (d->m_spec == Qt::LocalTime) - localMSecsToEpochMSecs(timeToMSecs(date, time), &date, &time); + if (d->m_spec == Qt::LocalTime) { + QDateTimePrivate::DaylightStatus status = d->daylightStatus(); + localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time); #ifndef QT_BOOTSTRAPPED - else if (d->m_spec == Qt::TimeZone) + } else if (d->m_spec == Qt::TimeZone) { QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time); #endif // QT_BOOTSTRAPPED + } dt.d->setDateTime(date, time); return dt; } @@ -3742,12 +3715,14 @@ QDateTime QDateTime::addMonths(int nmonths) const date = date.addMonths(nmonths); // Result might fall into "missing" DaylightTime transition hour, // so call conversion and use the adjusted returned time - if (d->m_spec == Qt::LocalTime) - localMSecsToEpochMSecs(timeToMSecs(date, time), &date, &time); + if (d->m_spec == Qt::LocalTime) { + QDateTimePrivate::DaylightStatus status = d->daylightStatus(); + localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time); #ifndef QT_BOOTSTRAPPED - else if (d->m_spec == Qt::TimeZone) + } else if (d->m_spec == Qt::TimeZone) { QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time); #endif // QT_BOOTSTRAPPED + } dt.d->setDateTime(date, time); return dt; } @@ -3776,12 +3751,14 @@ QDateTime QDateTime::addYears(int nyears) const date = date.addYears(nyears); // Result might fall into "missing" DaylightTime transition hour, // so call conversion and use the adjusted returned time - if (d->m_spec == Qt::LocalTime) - localMSecsToEpochMSecs(timeToMSecs(date, time), &date, &time); + if (d->m_spec == Qt::LocalTime) { + QDateTimePrivate::DaylightStatus status = d->daylightStatus(); + localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time); #ifndef QT_BOOTSTRAPPED - else if (d->m_spec == Qt::TimeZone) + } else if (d->m_spec == Qt::TimeZone) { QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time); #endif // QT_BOOTSTRAPPED + } dt.d->setDateTime(date, time); return dt; } |