summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Layt <jlayt@kde.org>2013-08-09 00:14:38 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-14 18:31:00 +0200
commite76c312eb84cb5d9971b024c411472dda4bbf8aa (patch)
treebca848d42af36d7858bbf1acefbc88e6e9496b87
parentf6e6dde369be8428b074c7135096b73248bdc8ae (diff)
QDateTime - Switch to using msecs based functions
A number of QDateTime functions directly use or modify the data stored in the private, but future changes to store msecs and status make this maintenance more complicated. Where possible simplify this code to use the standard msecs functions, standard constructors, or public api instead. This greatly simplifies the functions and the following msecs storage code changes. This is an intermim step towards storing the time in msecs. Some functions will be slower as a result of this change, optimization will take place after all the msecs changes are completed. Note this also removes a test that used valid QDates outside the range of msecs, this change in behavior will be documented in the final mscs change. Change-Id: I6ef710f24babc7024091010064082e9be0b5bbfe Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Mitch Curtis <mitch.curtis@digia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/tools/qdatetime.cpp212
-rw-r--r--src/corelib/tools/qdatetime_p.h2
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp27
3 files changed, 42 insertions, 199 deletions
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 174b694eee..31e16f1702 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -2735,15 +2735,7 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs)
void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
{
- detach();
-
- d->date = QDate(1970, 1, 1).addDays(secsSince1Jan1970UTC / SECS_PER_DAY);
- d->time = QTime(0, 0, 0).addSecs(secsSince1Jan1970UTC % SECS_PER_DAY);
-
- if (d->spec == QDateTimePrivate::OffsetFromUTC)
- utcToOffset(&d->date, &d->time, d->m_offsetFromUtc);
- else if (d->spec != QDateTimePrivate::UTC)
- utcToLocal(d->date, d->time);
+ setMSecsSinceEpoch((qint64)secsSince1Jan1970UTC * 1000);
}
#ifndef QT_NO_DATESTRING
@@ -2999,23 +2991,6 @@ QDateTime QDateTime::addYears(int nyears) const
return dt;
}
-QDateTime QDateTimePrivate::addMSecs(const QDateTime &dt, qint64 msecs)
-{
- if (!dt.isValid())
- return QDateTime();
-
- QDate utcDate;
- QTime utcTime;
- dt.d->getUTC(utcDate, utcTime);
- addMSecs(utcDate, utcTime, msecs);
- QDateTime utc(utcDate, utcTime, Qt::UTC);
-
- if (dt.timeSpec() == Qt::OffsetFromUTC)
- return utc.toOffsetFromUtc(dt.d->m_offsetFromUtc);
- else
- return utc.toTimeSpec(dt.timeSpec());
-}
-
/*!
Adds \a msecs to utcDate and \a utcTime as appropriate. It is assumed that
utcDate and utcTime are adjusted to UTC.
@@ -3064,7 +3039,7 @@ void QDateTimePrivate::addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs)
QDateTime QDateTime::addSecs(qint64 s) const
{
- return d->addMSecs(*this, s * 1000);
+ return addMSecs(s * 1000);
}
/*!
@@ -3078,7 +3053,13 @@ QDateTime QDateTime::addSecs(qint64 s) const
*/
QDateTime QDateTime::addMSecs(qint64 msecs) const
{
- return d->addMSecs(*this, msecs);
+ if (!isValid())
+ return QDateTime();
+
+ QDateTime dt(*this);
+ dt.detach();
+ dt.setMSecsSinceEpoch(toMSecsSinceEpoch() + msecs);
+ return dt;
}
/*!
@@ -3099,7 +3080,7 @@ QDateTime QDateTime::addMSecs(qint64 msecs) const
qint64 QDateTime::daysTo(const QDateTime &other) const
{
- return d->date.daysTo(other.d->date);
+ return date().daysTo(other.date());
}
/*!
@@ -3121,16 +3102,7 @@ qint64 QDateTime::daysTo(const QDateTime &other) const
qint64 QDateTime::secsTo(const QDateTime &other) const
{
- if (!isValid() || !other.isValid())
- return 0;
-
- QDate date1, date2;
- QTime time1, time2;
-
- d->getUTC(date1, time1);
- other.d->getUTC(date2, time2);
-
- return (date1.daysTo(date2) * SECS_PER_DAY) + time1.secsTo(time2);
+ return (msecsTo(other) / 1000);
}
/*!
@@ -3152,16 +3124,7 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const
if (!isValid() || !other.isValid())
return 0;
- QDate selfDate;
- QDate otherDate;
- QTime selfTime;
- QTime otherTime;
-
- d->getUTC(selfDate, selfTime);
- other.d->getUTC(otherDate, otherTime);
-
- return (static_cast<qint64>(selfDate.daysTo(otherDate)) * static_cast<qint64>(MSECS_PER_DAY))
- + static_cast<qint64>(selfTime.msecsTo(otherTime));
+ return other.toMSecsSinceEpoch() - toMSecsSinceEpoch();
}
/*!
@@ -3181,19 +3144,9 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const
QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
{
- if (spec == Qt::UTC || spec == Qt::OffsetFromUTC) {
- QDate date;
- QTime time;
- d->getUTC(date, time);
- return QDateTime(date, time, Qt::UTC, 0);
- }
-
- QDateTime ret;
- ret.d->spec = d->getLocal(ret.d->date, ret.d->time);
- return ret;
+ return fromMSecsSinceEpoch(toMSecsSinceEpoch(), spec, 0);
}
-
/*!
\since 5.2
@@ -3209,11 +3162,7 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
{
- QDate date;
- QTime time;
- d->getUTC(date, time);
- d->addMSecs(date, time, offsetSeconds * 1000);
- return QDateTime(date, time, Qt::OffsetFromUTC, offsetSeconds);
+ return fromMSecsSinceEpoch(toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds);
}
/*!
@@ -3225,16 +3174,8 @@ QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
bool QDateTime::operator==(const QDateTime &other) const
{
- if (d->spec == other.d->spec && d->m_offsetFromUtc == other.d->m_offsetFromUtc)
- return d->time == other.d->time && d->date == other.d->date;
- else {
- QDate date1, date2;
- QTime time1, time2;
-
- d->getUTC(date1, time1);
- other.d->getUTC(date2, time2);
- return time1 == time2 && date1 == date2;
- }
+ // Convert to UTC and compare
+ return (toMSecsSinceEpoch() == other.toMSecsSinceEpoch());
}
/*!
@@ -3256,19 +3197,8 @@ bool QDateTime::operator==(const QDateTime &other) const
bool QDateTime::operator<(const QDateTime &other) const
{
- if (d->spec == other.d->spec && d->spec != QDateTimePrivate::OffsetFromUTC) {
- if (d->date != other.d->date)
- return d->date < other.d->date;
- return d->time < other.d->time;
- } else {
- QDate date1, date2;
- QTime time1, time2;
- d->getUTC(date1, time1);
- other.d->getUTC(date2, time2);
- if (date1 != date2)
- return date1 < date2;
- return time1 < time2;
- }
+ // Convert to UTC and compare
+ return (toMSecsSinceEpoch() < other.toMSecsSinceEpoch());
}
/*!
@@ -3389,99 +3319,22 @@ qint64 QDateTime::currentMSecsSinceEpoch() Q_DECL_NOTHROW
#elif defined(Q_OS_UNIX)
QDate QDate::currentDate()
{
- QDate d;
- // posix compliant system
- time_t ltime;
- time(&ltime);
- struct tm *t = 0;
-
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
- // use the reentrant version of localtime() where available
- tzset();
- struct tm res;
- t = localtime_r(&ltime, &res);
-#else
- t = localtime(&ltime);
-#endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
-
- d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
- return d;
+ return QDateTime::currentDateTime().date();
}
QTime QTime::currentTime()
{
- QTime ct;
- // posix compliant system
- struct timeval tv;
- gettimeofday(&tv, 0);
- time_t ltime = tv.tv_sec;
- struct tm *t = 0;
-
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
- // use the reentrant version of localtime() where available
- tzset();
- struct tm res;
- t = localtime_r(&ltime, &res);
-#else
- t = localtime(&ltime);
-#endif
- Q_CHECK_PTR(t);
-
- ct.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
- return ct;
+ return QDateTime::currentDateTime().time();
}
QDateTime QDateTime::currentDateTime()
{
- // posix compliant system
- // we have milliseconds
- struct timeval tv;
- gettimeofday(&tv, 0);
- time_t ltime = tv.tv_sec;
- struct tm *t = 0;
-
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
- // use the reentrant version of localtime() where available
- tzset();
- struct tm res;
- t = localtime_r(&ltime, &res);
-#else
- t = localtime(&ltime);
-#endif
-
- QDateTime dt;
- dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
-
- dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
- dt.d->spec = t->tm_isdst > 0 ? QDateTimePrivate::LocalDST :
- t->tm_isdst == 0 ? QDateTimePrivate::LocalStandard :
- QDateTimePrivate::LocalUnknown;
- return dt;
+ return fromMSecsSinceEpoch(currentMSecsSinceEpoch(), Qt::LocalTime);
}
QDateTime QDateTime::currentDateTimeUtc()
{
- // posix compliant system
- // we have milliseconds
- struct timeval tv;
- gettimeofday(&tv, 0);
- time_t ltime = tv.tv_sec;
- struct tm *t = 0;
-
-#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
- // use the reentrant version of localtime() where available
- struct tm res;
- t = gmtime_r(&ltime, &res);
-#else
- t = gmtime(&ltime);
-#endif
-
- QDateTime dt;
- dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
-
- dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
- dt.d->spec = QDateTimePrivate::UTC;
- return dt;
+ return fromMSecsSinceEpoch(currentMSecsSinceEpoch(), Qt::UTC);
}
qint64 QDateTime::currentMSecsSinceEpoch() Q_DECL_NOTHROW
@@ -3568,20 +3421,13 @@ QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs)
*/
QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetSeconds)
{
- QDate newDate = QDate(1970, 1, 1);
- QTime newTime = QTime(0, 0, 0);
- QDateTimePrivate::addMSecs(newDate, newTime, msecs);
-
- switch (spec) {
- case Qt::UTC:
- return QDateTime(newDate, newTime, Qt::UTC);
- case Qt::OffsetFromUTC:
- utcToOffset(&newDate, &newTime, offsetSeconds);
- return QDateTime(newDate, newTime, Qt::OffsetFromUTC, offsetSeconds);
- default:
- utcToLocal(newDate, newTime);
- return QDateTime(newDate, newTime, Qt::LocalTime);
- }
+ QDateTime dt;
+ if (spec == Qt::OffsetFromUTC)
+ dt.setOffsetFromUtc(offsetSeconds);
+ else
+ dt.setTimeSpec(spec);
+ dt.setMSecsSinceEpoch(msecs);
+ return dt;
}
#if QT_DEPRECATED_SINCE(5, 2)
diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h
index d466637eb0..f765403d37 100644
--- a/src/corelib/tools/qdatetime_p.h
+++ b/src/corelib/tools/qdatetime_p.h
@@ -82,8 +82,6 @@ public:
// Get current date/time in UTC and put result in outDate and outTime
void getUTC(QDate &outDate, QTime &outTime) const;
- // Add msecs to given datetime and return result
- static QDateTime addMSecs(const QDateTime &dt, qint64 msecs);
// Add msecs to given datetime and put result in utcDate and utcTime
static void addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs);
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index 6c2fffb51d..85bc8abc52 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -1106,14 +1106,6 @@ void tst_QDateTime::toTimeSpec_data()
<< QDateTime(QDate(-271821, 4, 21), QTime(0, 0, 0), Qt::LocalTime);
#endif
- QTest::newRow("QDate min")
- << QDateTime(QDate::fromJulianDay(minJd()), QTime(0, 0, 0), Qt::UTC)
- << QDateTime(QDate::fromJulianDay(minJd()), QTime(1, 0, 0), Qt::LocalTime);
-
- QTest::newRow("QDate max")
- << QDateTime(QDate::fromJulianDay(maxJd()), QTime(22, 59, 59), Qt::UTC)
- << QDateTime(QDate::fromJulianDay(maxJd()), QTime(23, 59, 59), Qt::LocalTime);
-
if (europeanTimeZone) {
QTest::newRow("summer1") << QDateTime(QDate(2004, 6, 30), utcTime, Qt::UTC)
<< QDateTime(QDate(2004, 6, 30), localDaylightTime, Qt::LocalTime);
@@ -2683,6 +2675,10 @@ void tst_QDateTime::daylightTransitions() const
QVERIFY(test.isValid());
QCOMPARE(test.date(), QDate(2012, 10, 28));
QCOMPARE(test.time(), QTime(2, 0, 0));
+#ifdef Q_OS_WIN
+ // Windows uses SecondOccurrence
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_WIN
QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
// Add hour to tran FirstOccurrence to get to tran SecondOccurrence
@@ -2695,10 +2691,11 @@ void tst_QDateTime::daylightTransitions() const
QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
#endif // Q_OS_WIN
QCOMPARE(test.time(), QTime(2, 0, 0));
-#ifdef Q_OS_WIN
+#ifndef Q_OS_MAC
// Windows uses SecondOccurrence
+ // Linux mktime bug uses last calculation
QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_WIN
+#endif // Q_OS_MAC
QCOMPARE(test.toMSecsSinceEpoch(), standard2012);
// Add hour to tran SecondOccurrence to get to after tran FirstOccurrence
@@ -2706,15 +2703,17 @@ void tst_QDateTime::daylightTransitions() const
test = test.addMSecs(msecsOneHour);
QVERIFY(test.isValid());
QCOMPARE(test.date(), QDate(2012, 10, 28));
-#ifdef Q_OS_MAC
+#ifndef Q_OS_WIN
// Mac uses FirstOccurrence
+ // Linux mktime bug uses last calculation
QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_MAC
+#endif // Q_OS_WIN
QCOMPARE(test.time(), QTime(3, 0, 0));
-#ifdef Q_OS_MAC
+#ifndef Q_OS_WIN
// Mac uses FirstOccurrence
+ // Linux mktime bug uses last calculation
QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
-#endif // Q_OS_MAC
+#endif // Q_OS_WIN
QCOMPARE(test.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
} else {