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>
This commit is contained in:
parent
f6e6dde369
commit
e76c312eb8
@ -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(<ime);
|
||||
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(<ime, &res);
|
||||
#else
|
||||
t = localtime(<ime);
|
||||
#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(<ime, &res);
|
||||
#else
|
||||
t = localtime(<ime);
|
||||
#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(<ime, &res);
|
||||
#else
|
||||
t = localtime(<ime);
|
||||
#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(<ime, &res);
|
||||
#else
|
||||
t = gmtime(<ime);
|
||||
#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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user