diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/tools/qdatetime.cpp | 117 | ||||
-rw-r--r-- | src/corelib/tools/qdatetime.h | 3 |
2 files changed, 105 insertions, 15 deletions
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 54a4205..7628dd2 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2315,17 +2315,35 @@ void QDateTime::setTimeSpec(Qt::TimeSpec spec) } } -static uint toTime_tHelper(const QDate &utcDate, const QTime &utcTime) +qint64 toMsecsSinceEpoch_helper(qint64 jd, int msecs) { - int days = QDate(1970, 1, 1).daysTo(utcDate); - int secs = QTime().secsTo(utcTime); - if (days < 0 || (days == 0 && secs < 0)) - return uint(-1); + int days = jd - julianDayFromGregorianDate(1970, 1, 1); + qint64 retval = (qlonglong(days) * MSECS_PER_DAY) + msecs; + return retval; +} - qlonglong retval = (qlonglong(days) * SECS_PER_DAY) + secs; - if (retval >= Q_INT64_C(0xFFFFFFFF)) - return uint(-1); - return uint(retval); +/*! + \since 4.7 + + Returns the datetime as the number of milliseconds that have passed + since 1970-01-01T00:00:00.000, Coordinated Universal Time (Qt::UTC). + + On systems that do not support time zones, this function will + behave as if local time were Qt::UTC. + + The behavior for this function is undefined if the datetime stored in + this object is not valid. However, for all valid dates, this function + returns a unique value. + + \sa toTime_t(), setMsecsSinceEpoch() +*/ +qint64 QDateTime::toMsecsSinceEpoch() const +{ + QDate utcDate; + QTime utcTime; + d->getUTC(utcDate, utcTime); + + return toMsecsSinceEpoch_helper(utcDate.jd, utcTime.ds()); } /*! @@ -2335,16 +2353,63 @@ static uint toTime_tHelper(const QDate &utcDate, const QTime &utcTime) On systems that do not support time zones, this function will behave as if local time were Qt::UTC. - \sa setTime_t() + \note This function returns a 32-bit unsigned integer, so it does not + support dates before 1970, but it does support dates after + 2038-01-19T03:14:06, which may not be valid time_t values. Be careful + when passing those time_t values to system functions, which could + interpret them as negative dates. + + If the date is outside the range 1970-01-01T00:00:00 to + 2106-02-07T06:28:14, this function returns -1 cast to an unsigned integer + (i.e., 0xFFFFFFFF). + + To get an extended range, use toMsecsSinceEpoch(). + + \sa toMsecsSinceEpoch(), setTime_t() */ uint QDateTime::toTime_t() const { - QDate utcDate; - QTime utcTime; - d->getUTC(utcDate, utcTime); + qint64 retval = toMsecsSinceEpoch() / 1000; + if (quint64(retval) >= Q_UINT64_C(0xFFFFFFFF)) + return uint(-1); + return uint(retval); +} - return toTime_tHelper(utcDate, utcTime); +/*! + \since 4.7 + + Sets the date and time given the number of \a mulliseconds that have + passed since 1970-01-01T00:00:00.000, Coordinated Universal Time + (Qt::UTC). On systems that do not support time zones this function + will behave as if local time were Qt::UTC. + + Note that there are possible values for \a msecs that lie outside the + valid range of QDateTime, both negative and positive. The behavior of + this function is undefined for those values. + + \sa toMsecsSinceEpoch(), setTime_t() +*/ +void QDateTime::setMsecsSinceEpoch(qint64 msecs) +{ + detach(); + + QDateTimePrivate::Spec oldSpec = d->spec; + + int ddays = msecs / MSECS_PER_DAY; + msecs %= MSECS_PER_DAY; + if (msecs < 0) { + // negative + --ddays; + msecs += MSECS_PER_DAY; + } + + d->date = QDate(1970, 1, 1).addDays(ddays); + d->time = QTime().addMSecs(msecs); + d->spec = QDateTimePrivate::UTC; + + if (oldSpec != QDateTimePrivate::UTC) + d->spec = d->getLocal(d->date, d->time); } /*! @@ -3088,6 +3153,27 @@ QDateTime QDateTime::fromTime_t(uint seconds) } /*! + \since 4.7 + + Returns a datetime whose date and time are the number of milliseconds \a msec + that have passed since 1970-01-01T00:00:00.000, Coordinated Universal + Time (Qt::UTC). On systems that do not support time zones, the time + will be set as if local time were Qt::UTC. + + Note that there are possible values for \a msecs that lie outside the valid + range of QDateTime, both negative and positive. The behavior of this + function is undefined for those values. + + \sa toTime_t(), setTime_t() +*/ +QDateTime QDateTime::fromMsecsSinceEpoch(qint64 msecs) +{ + QDateTime d; + d.setMsecsSinceEpoch(msecs); + return d; +} + +/*! \since 4.4 \internal @@ -3841,7 +3927,8 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) { QDate fakeDate = adjustDate(date); - time_t secsSince1Jan1970UTC = toTime_tHelper(fakeDate, time); + // won't overflow because of fakeDate + time_t secsSince1Jan1970UTC = toMsecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime().msecsTo(time)) / 1000; tm *brokenDown = 0; #if defined(Q_OS_WINCE) diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index ef5968e..248793b 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -230,10 +230,12 @@ public: QDate date() const; QTime time() const; Qt::TimeSpec timeSpec() const; + qint64 toMsecsSinceEpoch() const; uint toTime_t() const; void setDate(const QDate &date); void setTime(const QTime &time); void setTimeSpec(Qt::TimeSpec spec); + void setMsecsSinceEpoch(qint64 msecs); void setTime_t(uint secsSince1Jan1970UTC); #ifndef QT_NO_DATESTRING QString toString(Qt::DateFormat f = Qt::TextDate) const; @@ -267,6 +269,7 @@ public: static QDateTime fromString(const QString &s, const QString &format); #endif static QDateTime fromTime_t(uint secsSince1Jan1970UTC); + static QDateTime fromMsecsSinceEpoch(qint64 msecs); static qint64 currentMsecsSinceEpoch(); #ifdef QT3_SUPPORT |