QDateTime - Extend fromMSecsSinceEpoch API

Add convenience methods for fromMSecsSinceEpoch() and
fromTime_t() to enable direct creation of other time specs
than LocalTime without the overhead of unncessary conversions.

For example instead of:
  QDateTime dt = fromMSecsSinceEpoch(12345).toUtc();
the following saves two conversions:
  QDateTime dt = fromMSecsSinceEpoch(12345, Qt:UTC);

This will improve the performance of the new QTimeZone class.

[ChangeLog][QtCore][QDateTime] Added convenience methods for
fromMSecsSinceEpoch() and fromTime_t() to take time spec to be used in
returned datetime.

Change-Id: I133635bfe3d35ee496a287257e13b2d600225a38
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mitch Curtis <mitch.curtis@digia.com>
This commit is contained in:
John Layt 2013-03-01 16:36:31 +01:00 committed by The Qt Project
parent 13c16bbd06
commit ad77048d1f
3 changed files with 93 additions and 17 deletions

View File

@ -3430,16 +3430,32 @@ qint64 QDateTime::currentMSecsSinceEpoch() Q_DECL_NOTHROW
Returns a datetime whose date and time are the number of \a seconds
that have passed since 1970-01-01T00:00:00, 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.
Time (Qt::UTC) and converted to Qt::LocalTime. On systems that do not
support time zones, the time will be set as if local time were Qt::UTC.
\sa toTime_t(), setTime_t()
*/
QDateTime QDateTime::fromTime_t(uint seconds)
{
QDateTime d;
d.setTime_t(seconds);
return d;
return fromMSecsSinceEpoch((qint64)seconds * 1000, Qt::LocalTime);
}
/*!
\since 5.2
Returns a datetime whose date and time are the number of \a seconds
that have passed since 1970-01-01T00:00:00, Coordinated Universal
Time (Qt::UTC) and converted to the given \a spec.
If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be
ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0
then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds.
\sa toTime_t(), setTime_t()
*/
QDateTime QDateTime::fromTime_t(uint seconds, Qt::TimeSpec spec, int offsetSeconds)
{
return fromMSecsSinceEpoch((qint64)seconds * 1000, spec, offsetSeconds);
}
/*!
@ -3447,8 +3463,8 @@ QDateTime QDateTime::fromTime_t(uint seconds)
Returns a datetime whose date and time are the number of milliseconds, \a msecs,
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.
Time (Qt::UTC), and converted to Qt::LocalTime. 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
@ -3458,9 +3474,42 @@ QDateTime QDateTime::fromTime_t(uint seconds)
*/
QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs)
{
QDateTime d;
d.setMSecsSinceEpoch(msecs);
return d;
return fromMSecsSinceEpoch(msecs, Qt::LocalTime);
}
/*!
\since 5.2
Returns a datetime whose date and time are the number of milliseconds \a msecs
that have passed since 1970-01-01T00:00:00.000, Coordinated Universal
Time (Qt::UTC) and converted to the given \a spec.
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.
If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be
ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0
then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds.
\sa fromTime_t()
*/
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);
}
}
#if QT_DEPRECATED_SINCE(5, 2)

View File

@ -271,7 +271,12 @@ public:
#endif
// ### Qt 6: use quint64 instead of uint
static QDateTime fromTime_t(uint secsSince1Jan1970UTC);
// ### Qt 6: Merge with above with default spec = Qt::LocalTime
static QDateTime fromTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec,
int offsetFromUtc = 0);
static QDateTime fromMSecsSinceEpoch(qint64 msecs);
// ### Qt 6: Merge with above with default spec = Qt::LocalTime
static QDateTime fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetFromUtc = 0);
static qint64 currentMSecsSinceEpoch() Q_DECL_NOTHROW;
private:

View File

@ -581,20 +581,42 @@ void tst_QDateTime::fromMSecsSinceEpoch()
QFETCH(QDateTime, utc);
QFETCH(QDateTime, european);
QDateTime dt(QDateTime::fromMSecsSinceEpoch(msecs));
QDateTime dtLocal = QDateTime::fromMSecsSinceEpoch(msecs, Qt::LocalTime);
QDateTime dtUtc = QDateTime::fromMSecsSinceEpoch(msecs, Qt::UTC);
QDateTime dtOffset = QDateTime::fromMSecsSinceEpoch(msecs, Qt::OffsetFromUTC, 60*60);
QCOMPARE(dt, utc);
if (europeanTimeZone)
QCOMPARE(dt.toLocalTime(), european);
QCOMPARE(dtLocal, utc);
QCOMPARE(dt.toMSecsSinceEpoch(), msecs);
QCOMPARE(dtUtc, utc);
QCOMPARE(dtUtc.date(), utc.date());
QCOMPARE(dtUtc.time(), utc.time());
QCOMPARE(dtOffset, utc);
QCOMPARE(dtOffset.utcOffset(), 60*60);
QCOMPARE(dtOffset.time(), utc.time().addMSecs(60*60*1000));
if (europeanTimeZone) {
QCOMPARE(dtLocal.toLocalTime(), european);
QCOMPARE(dtUtc.toLocalTime(), european);
QCOMPARE(dtOffset.toLocalTime(), european);
} else {
QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo");
}
QCOMPARE(dtLocal.toMSecsSinceEpoch(), msecs);
QCOMPARE(dtUtc.toMSecsSinceEpoch(), msecs);
QCOMPARE(dtOffset.toMSecsSinceEpoch(), msecs);
if (quint64(msecs / 1000) < 0xFFFFFFFF) {
QCOMPARE(qint64(dt.toTime_t()), msecs / 1000);
QCOMPARE(qint64(dtLocal.toTime_t()), msecs / 1000);
QCOMPARE(qint64(dtUtc.toTime_t()), msecs / 1000);
QCOMPARE(qint64(dtOffset.toTime_t()), msecs / 1000);
}
QDateTime reference(QDate(1970, 1, 1), QTime(), Qt::UTC);
QCOMPARE(dt, reference.addMSecs(msecs));
QCOMPARE(dtLocal, reference.addMSecs(msecs));
QCOMPARE(dtUtc, reference.addMSecs(msecs));
QCOMPARE(dtOffset, reference.addMSecs(msecs));
}
void tst_QDateTime::toString_isoDate_data()