1 /****************************************************************************
3 ** Copyright (C) 2011 Andre Somers, Sean Harmer.
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtCore module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qplatformdefs.h"
44 #include "qdatastream.h"
46 #include "qtimespan.h"
48 #include "qcoreapplication.h"
51 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
52 #include <qt_windows.h>
59 #if defined(Q_OS_WINCE)
60 #include "qfunctions_wince.h"
64 #include <private/qcore_mac_p.h>
67 #if defined(Q_OS_SYMBIAN)
80 \brief The QTimeSpan represents a span of time
83 QTimeSpan represents a span of time, which is optionally in reference to a specific
84 point in time. A QTimeSpan behaves slightly different if it has a reference date or time
87 \section1 Constructing a QTimeSpan
88 A QTimeSpan can be created by initializing it directly with a length and optionally with
89 a reference (start) date, or by substracting two \l QDate or \l QDateTime values. By substracting
90 \l QDate or \l QDateTime values, you create a QTimeSpan with the \l QDate or \l QDateTime on the right
91 hand side of the - operator as the reference date.
94 //Creates a QTimeSpan representing the time from October 10, 1975 to now
95 QDate birthDay(1975, 10, 10);
96 QTimeSpan age = QDate::currentDate() - birthDay;
99 QTimeSpan defines a series of static methods that can be used for initializing a QTimeSpan.
100 \c second(), \c minute(), \c hour(), \c day() and \c week() all return QTimeSpan instances with the corresponding
101 length and no reference date. You can use those to create new instances. See the
102 section on \l {Date arithmetic} below.
105 //Creates a QTimeSpan representing 2 days, 4 hours and 31 minutes.
106 QTimeSpan span(2 * QTimeSpan::day() + 4 * QTimeSpan::hour() + 31 * QTimeSpan::minute());
109 Finally, a QTimeSpan can be constructed by using one of the static constructors
110 \l fromString() or \l fromTimeUnit().
112 \section1 Date arithmetic
113 A negative QTimeSpan means that the reference date lies before the referenced date. Call
114 \l normalize() to ensure that the reference date is smaller or equal than the referenced date.
116 Basic arithmetic can be done with QTimeSpan. QTimeSpans can be added up or substracted, or
117 be multiplied by a scalar factor. For this, the usual operators are implemented. The union
118 of QTimeSpans will yield the minimal QTimeSpan that covers both the original QTimeSpans,
119 while the intersection will yield the overlap between them (or an empty one if there is no
120 overlap). Please refer to the method documentation for details on what happens to a
121 reference date when using these methods.
123 QTimeSpans can also be added to or substracted from a \l QDate, \l QTime or \l QDateTime. This will yield
124 a new \l QDate, \l QTime or \l QDateTime moved by the interval described by the QTimeSpan. Note
125 that the QTimeSpan must be the right-hand argument of the operator. You can not add a \l QDate
126 to a QTimeSpan, but you can do the reverse.
129 QTimeSpan span(QTimeSpan::hour() * 5 + 45 * QTimeSpan::hinute());
130 QDateTime t1 = QDateTime::currentDateTime();
131 QDateTime t2 = t1 + span; // t2 is now the date time 5 hours and 45 minutes in the future.
134 \section1 Accessing the length of a QTimeSpan
135 There are two sets of methods that return the length of a QTimeSpan. The to* methods such
136 as \l toSeconds() and \l toMinutes() return the total time in the requested unit. That may be a
140 QTimeSpan span = QTimeSpan::hour() * 6;
141 qreal days = span.toDays(); //yields 0.25
144 On the other hand, you may be interested in a number of units at the same time. If you want
145 to know the number of days, hours and minutes in a QTimeSpan, you can use the to*Part
146 methods such as \l toDayPart() and \l toHourPart(). These functions take a \c QTimeSpan::TimeSpanFormat
147 argument to indicate the units you want to use for the presentation of the QTimeSpan.
148 This is used to calculate the number of the requested time units. You can also use the
149 parts method directly, passing pointers to ints for the units you are interested in and 0
152 \section1 Using months and years
153 It is natural to use units like months
154 and years when dealing with longer time periods, such as the age of people. The problem with
155 these units is that unlike the time units for a week or shorter, the length of a month or a
156 year is not fixed. It it dependent on the reference date. The time period '1 month' has a
157 different meaning when we are speaking of Februari or Januari. Qt does not take leap seconds
160 QTimeSpan can only use the month and year time units if a valid reference date has been
161 set. Without a valid reference date, month and year as time units are meaningless and their
162 use will result in an assert. The largest unit of time that can be expressed without a reference
163 date is a week. The time period of one month is understood to mean the period
164 from a day and time one month to the same date and time in the next. If the next month does
165 not have that date and time, one month will be taken to mean the period to the end of that
170 \o The time from Januari 2, 12 PM to Februari 2, 12 PM will be understood as exactly one month.
171 \o The time from Januari 30, 2 PM to March 1, 00:00:00.000 will also be one month, because
172 Februari does not have 30 days but 28 or 29 depending on the year.
173 \o The time from Januari 30, 2 PM to March 30, 2 PM will be 2 months.
176 The same goes for years.
178 \section1 Limitations and counterintuitive behaviour
179 QTimeSpan can be used to describe almost any length of time, ranging from milliseconds to
180 decades and beyond. QTimeSpan internally uses a 64 bit integer value to represent the interval;
181 enough for any application not dealing with geological or astronomical time scales.
183 The use of a single interval value also means that arithmetic with time periods set as months
184 or years may not always yield what you might expect. A time period set as the year describing
185 the whole of 2007 that you multiply by two, will not end up having a length of two years, but
186 of 1 year, 11 months and 30 days, as 2008 is one day longer than 2007. When months and years
187 are used, they are converted to the exact time span they describe relative to the reference
188 date set for the QTimeSpan. With another reference date, or when negated, that time span may
189 or may not describe the same number of years and months.
194 QTimeSpan QTimeSpan::second() {return QTimeSpan( Q_INT64_C(1000) );}
195 QTimeSpan QTimeSpan::minute() {return QTimeSpan( Q_INT64_C(1000) * Q_INT64_C(60) );}
196 QTimeSpan QTimeSpan::hour() {return QTimeSpan( Q_INT64_C(1000) * Q_INT64_C(60) * Q_INT64_C(60) );}
197 QTimeSpan QTimeSpan::day() {return QTimeSpan( Q_INT64_C(1000) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(24) );}
198 QTimeSpan QTimeSpan::week() {return QTimeSpan( Q_INT64_C(1000) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(24) * Q_INT64_C(7) );}
200 class QTimeSpanPrivate : public QSharedData {
205 void addUnit(QTimeSpan* self, Qt::TimeSpanUnit unit, qreal value)
207 if (unit >= Qt::Months) {
208 QTimeSpan tempSpan(self->referencedDate());
209 tempSpan.setFromTimeUnit(unit, value);
210 interval += tempSpan.toMSecs();
214 interval += value * Q_INT64_C(1000) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(24) * Q_INT64_C(7);
217 interval += value * Q_INT64_C(1000) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(24);
220 interval += value * Q_INT64_C(1000) * Q_INT64_C(60) * Q_INT64_C(60);
223 interval += value * Q_INT64_C(1000) * Q_INT64_C(60);
226 interval += value * Q_INT64_C(1000);
228 case Qt::Milliseconds:
237 //returns the number of days in the month of the indicated date. If lookback is true, and
238 //the date is exactly on the month boundary, the month before is used.
239 int daysInMonth (const QDateTime& date, bool lookBack = false) const {
240 QDateTime measureDate(date);
242 measureDate = measureDate.addMSecs(-1);
244 return measureDate.date().daysInMonth();
247 class TimePartHash: public QHash<Qt::TimeSpanUnit, int*>
250 TimePartHash(Qt::TimeSpanFormat format)
252 for (int i(Qt::Milliseconds); i <= Qt::Years; i *= 2) {
253 Qt::TimeSpanUnit u = static_cast<Qt::TimeSpanUnit>(i);
254 if (format.testFlag(u)) {
255 int* newValue = new int;
257 insert(u, newValue); //perhaps we can optimize this not to new each int individually?
269 inline bool fill(const QTimeSpan& span)
271 bool result = span.parts(value(Qt::Milliseconds),
282 inline void addUnit(const Qt::TimeSpanUnit unit)
284 if (value(unit) != 0)
287 int* newValue = new int;
289 insert(unit, newValue);
294 //returns a string representation of time in a single time unit
295 QString unitString(Qt::TimeSpanUnit unit, int num) const
298 case::Qt::Milliseconds:
299 return qApp->translate("QTimeSpanPrivate", "%n millisecond(s)", "", QCoreApplication::CodecForTr, num);
301 return qApp->translate("QTimeSpanPrivate", "%n second(s)", "", QCoreApplication::CodecForTr, num);
303 return qApp->translate("QTimeSpanPrivate", "%n minute(s)", "", QCoreApplication::CodecForTr, num);
305 return qApp->translate("QTimeSpanPrivate", "%n hour(s)", "", QCoreApplication::CodecForTr, num);
307 return qApp->translate("QTimeSpanPrivate", "%n day(s)", "", QCoreApplication::CodecForTr, num);
309 return qApp->translate("QTimeSpanPrivate", "%n week(s)", "", QCoreApplication::CodecForTr, num);
311 return qApp->translate("QTimeSpanPrivate", "%n month(s)", "", QCoreApplication::CodecForTr, num);
313 return qApp->translate("QTimeSpanPrivate", "%n year(s)", "", QCoreApplication::CodecForTr, num);
319 #ifndef QT_NO_DATESTRING
320 struct TimeFormatToken
322 Qt::TimeSpanUnit type; //Qt::NoUnit is used for string literal types
323 int length; //number of characters to use
324 QString string; //only used for string literals
327 QList<TimeFormatToken> parseFormatString(const QString& formatString, Qt::TimeSpanFormat &format) const
329 QHash<QChar, Qt::TimeSpanUnit> tokenHash;
330 tokenHash.insert(QChar('y', 0), Qt::Years);
331 tokenHash.insert(QChar('M', 0), Qt::Months);
332 tokenHash.insert(QChar('w', 0), Qt::Weeks);
333 tokenHash.insert(QChar('d', 0), Qt::Days);
334 tokenHash.insert(QChar('h', 0), Qt::Hours);
335 tokenHash.insert(QChar('m', 0), Qt::Minutes);
336 tokenHash.insert(QChar('s', 0), Qt::Seconds);
337 tokenHash.insert(QChar('z', 0), Qt::Milliseconds);
340 QList<TimeFormatToken> tokenList;
343 int length(formatString.length());
344 bool inLiteral(false);
345 while (pos < length) {
346 const QChar currentChar(formatString[pos]);
348 if (currentChar == QLatin1Char('\'')) {
349 inLiteral = false; //exit literal string mode
350 if ((pos+1)<length) {
351 if (formatString[pos+1] == QLatin1Char('\'')) {
354 TimeFormatToken token = tokenList.last();
355 token.string.append(QChar('\'', 0));
356 token.length = token.string.length();
357 tokenList[tokenList.length()-1] = token;
359 inLiteral = true; //we *are* staying in literal string mode
363 TimeFormatToken token = tokenList.last();
364 token.string.append(currentChar);
365 token.length = token.string.length();
366 tokenList[tokenList.length()-1] = token;
368 } else { //not in literal string
369 if (currentChar == QLatin1Char('\'')) {
370 inLiteral = true; //enter literal string mode
371 TimeFormatToken token;
372 token.type = Qt::NoUnit;
376 if (tokenHash.contains(currentChar)) {
377 Qt::TimeSpanUnit unit = tokenHash.value(currentChar);
379 TimeFormatToken token;
382 if ((!tokenList.isEmpty()) && (tokenList.last().type == unit))
383 token = tokenList.takeLast();
386 tokenList.append(token);
391 TimeFormatToken token;
393 token.type = Qt::NoUnit;
394 if ((!tokenList.isEmpty()) && (tokenList.last().type == Qt::NoUnit))
395 token = tokenList.takeLast();
397 token.string.append(currentChar);
398 token.length= token.string.length();
399 tokenList.append(token);
416 Constructs a null QTimeSpan
418 QTimeSpan::QTimeSpan()
419 : d(new QTimeSpanPrivate)
426 \overload QTimeSpan()
428 Constructs QTimeSpan of size \a msecs milliseconds. The reference date will
431 QTimeSpan::QTimeSpan(qint64 msecs)
432 : d(new QTimeSpanPrivate)
440 QTimeSpan::QTimeSpan(const QTimeSpan& other):
447 \overload QTimeSpan()
449 Constructs QTimeSpan of size \a msecs milliseconds from the given \a reference date
452 QTimeSpan::QTimeSpan(const QDateTime &reference, qint64 msecs)
453 : d(new QTimeSpanPrivate)
456 d->reference = reference;
461 \overload QTimeSpan()
463 Constructs QTimeSpan of size \a msecs milliseconds from the given \a reference date.
464 The reference time will be 0:00:00.000
466 QTimeSpan::QTimeSpan(const QDate &reference, quint64 msecs)
467 : d(new QTimeSpanPrivate)
470 d->reference = QDateTime(reference);
475 \overload QTimeSpan()
477 Constructs QTimeSpan of size \a msecs milliseconds from the given \a reference time.
478 The reference date will be today's date.
480 QTimeSpan::QTimeSpan(const QTime &reference, quint64 msecs)
481 : d(new QTimeSpanPrivate)
484 QDateTime todayReference(QDate::currentDate());
485 todayReference.setTime(reference);
486 d->reference = todayReference;
491 \overload QTimeSpan()
493 Constructs a QTimeSpan of the same length as \a other from the given \a reference date time.
495 QTimeSpan::QTimeSpan(const QDateTime& reference, const QTimeSpan& other)
496 : d(new QTimeSpanPrivate)
498 d->reference = reference;
499 d->interval = other.d->interval;
505 Constructs a QTimeSpan of the same length as \a other from the given \a reference date.
506 The reference time will be 00:00:00.000
508 QTimeSpan::QTimeSpan(const QDate& reference, const QTimeSpan& other)
509 : d(new QTimeSpanPrivate)
511 d->reference = QDateTime(reference);
512 d->interval = other.d->interval;
518 Constructs a QTimeSpan of the same length as \a other from the given \a reference time.
519 The reference date will be today's date.
521 QTimeSpan::QTimeSpan(const QTime& reference, const QTimeSpan& other)
522 : d(new QTimeSpanPrivate)
524 QDateTime todayReference(QDate::currentDate());
525 todayReference.setTime(reference);
526 d->reference = todayReference;
527 d->interval = other.d->interval;
534 QTimeSpan::~QTimeSpan()
539 Returns true if the time span is 0; that is, if no time is spanned by
540 this instance. There may or may not be a valid reference date.
542 \sa isNull() hasValidReference()
544 bool QTimeSpan::isEmpty() const
546 return d->interval == 0;
550 Returns true if the time span is 0; that is, if no time is spanned by
551 this instance and there is no valid reference date.
555 bool QTimeSpan::isNull() const
557 return isEmpty() && (!hasValidReference());
563 QTimeSpan& QTimeSpan::operator=(const QTimeSpan& other) {
572 Returns a new QTimeSpan instance initialized to \a interval number of
573 units \a unit. The default reference date is invalid.
575 Note that you can only construct a valid QTimeSpan using the Months or Years
576 time units if you supply a valid \a reference date.
578 \sa setFromTimeUnit()
580 QTimeSpan QTimeSpan::fromTimeUnit(Qt::TimeSpanUnit unit, qreal interval, const QDateTime& reference )
582 switch (unit){ //note: fall through is intentional!
593 case Qt::Milliseconds:
596 if (reference.isValid()) {
597 QTimeSpan result(reference);
598 result.setFromTimeUnit(unit, interval);
601 Q_ASSERT_X(false, "static constructor", "Can not construct QTimeSpan from Month or Year TimeSpanUnit without a valid reference date.");
605 return QTimeSpan(reference, qint64(interval));
609 Returns the number of the requested units indicated by \a unit when formatted
614 int QTimeSpan::part(Qt::TimeSpanUnit unit, Qt::TimeSpanFormat format) const
616 if (!format.testFlag(unit))
619 if (!hasValidReference()) {
620 Q_ASSERT_X(!(unit == Qt::Months || unit == Qt::Years),
621 "part", "Can not calculate Month or Year part without a reference date");
623 if (format.testFlag(Qt::Months) || format.testFlag(Qt::Years)) {
624 qWarning() << "Unsetting Qt::Months and Qt::Years flags from format. Not supported without a reference date";
625 //should this assert instead?
626 format&= (Qt::AllUnits ^ (Qt::Months | Qt::Years));
630 //build up hash with pointers to ints for the units that are set in format, and 0's for those that are not.
631 QTimeSpanPrivate::TimePartHash partsHash(format);
632 bool result = partsHash.fill(*this);
635 //what to do? Assert perhaps?
636 qWarning() << "Result is invalid!";
640 int val = *(partsHash.value(unit));
644 #define CHECK_INT_LIMIT(interval, unitFactor) if (interval >= (qint64(unitFactor) * qint64(std::numeric_limits<int>::max()) ) ) {qWarning() << "out of range" << unitFactor; return false;}
647 Retreives a breakup of the length of the QTimeSpan in different time units.
649 While \l part() allows you to retreive the value of a single unit for a specific
650 representation of time, this method allows you to retreive all these values
651 with a single call. The units that you want to use in the representation of the
652 time span are defined implicitly by the pointers you pass. Passing a valid pointer
653 for a time unit will include that unit in the representation, while passing 0
654 for that pointer will exclude it.
656 The passed integer pointers will be set to the correct value so that together
657 they represent the whole time span. This function will then return true.
658 If it is impossible to represent the whole time span in the requested units,
659 this function returns false.
661 The \a fractionalSmallestUnit qreal pointer can optionally be passed in to
662 retreive the value for the smallest time unit passed in as a fractional number.
663 For instance, if your time span contains 4 minutes and 30 seconds, but the
664 smallest time unit you pass in an integer pointer for is the minute unit, then
665 the minute integer will be set to 4 and the \a fractionalSmallestUnit will be set
668 A negative QTimeSpan will result in all the parts of the representation to be
669 negative, while a positive QTimeSpan will result in an all positive
672 Note that months and years are only valid as units for time spans that have a valid
673 reference date. Requesting the number of months or years for time spans without
674 a valid reference date will return false.
676 If this function returns false, the value of the passed in pointers is undefined.
680 bool QTimeSpan::parts(int *msecondsPtr,
688 qreal *fractionalSmallestUnit) const
690 /* \todo We should probably cache the results of this operation. However, that requires keeping a dirty flag
691 in the private data store, or a copy of the reference date, interval and last used parts. Is that worth it?
694 // Has the user asked for a fractional component? If yes, find which unit it corresponds to.
695 Qt::TimeSpanUnit smallestUnit = Qt::NoUnit;
696 if (fractionalSmallestUnit) {
698 smallestUnit = Qt::Years;
700 smallestUnit = Qt::Months;
702 smallestUnit = Qt::Weeks;
704 smallestUnit = Qt::Days;
706 smallestUnit = Qt::Hours;
708 smallestUnit = Qt::Minutes;
710 smallestUnit = Qt::Seconds;
712 smallestUnit = Qt::Milliseconds;
717 if (yearsPtr || monthsPtr) { //deal with months and years
718 //we can not deal with months or years if there is no valid reference date
719 if (!hasValidReference()) {
720 qWarning() << "Can not request month or year parts of a QTimeSpan without a valid reference date.";
724 QDate startDate = ts.startDate().date();
725 QDate endDate = ts.endDate().date();
728 int years = endDate.year() - startDate.year();
729 if (endDate.month() < startDate.month()) {
731 } else if (endDate.month() == startDate.month()) {
732 if (endDate.day() < startDate.day())
739 QDate newStartDate(startDate);
740 unitFactor = Q_INT64_C(365) * Q_INT64_C(24) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000);
741 newStartDate = newStartDate.addYears(years);
743 ts = QDateTime(endDate, ts.endDate().time()) - QDateTime(newStartDate, ts.startDate().time());
745 if (smallestUnit == Qt::Years) {
746 if (QDate::isLeapYear(newStartDate.year()))
747 unitFactor = Q_INT64_C(366) * Q_INT64_C(24) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000);
748 *fractionalSmallestUnit = static_cast<qreal>(years)
749 + (static_cast<qreal>(ts.toMSecs()) / static_cast<qreal>(unitFactor));
756 int months = endDate.month() - startDate.month();
759 if (endDate.day() < startDate.day())
762 newStartDate = newStartDate.addMonths(months);
763 ts = QDateTime(endDate, ts.endDate().time()) - QDateTime(newStartDate, ts.startDate().time());
766 months += years * 12;
770 if (smallestUnit == Qt::Months) {
771 unitFactor = Q_INT64_C(24) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000); //one day
772 unitFactor *= d->daysInMonth(QDateTime(newStartDate), isNegative());
773 *fractionalSmallestUnit = static_cast<qreal>(months)
774 + (static_cast<qreal>(ts.toMSecs()) / static_cast<qreal>(unitFactor));
781 //from here on, we use ts as the time span!
782 qint64 intervalLeft = ts.toMSecs();
785 unitFactor = Q_INT64_C(7) * Q_INT64_C(24) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000);
786 CHECK_INT_LIMIT(intervalLeft, unitFactor)
788 *weeksPtr = intervalLeft / unitFactor;
789 if (smallestUnit == Qt::Weeks) {
790 QTimeSpan leftOverTime(referencedDate(), -intervalLeft);
791 leftOverTime.normalize();
792 *fractionalSmallestUnit = leftOverTime.toTimeUnit(smallestUnit);
798 intervalLeft = intervalLeft % unitFactor;
802 unitFactor = (Q_INT64_C(24) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000));
803 CHECK_INT_LIMIT(intervalLeft, unitFactor)
805 *daysPtr = intervalLeft / unitFactor;
806 if (smallestUnit == Qt::Days) {
807 QTimeSpan leftOverTime(referencedDate(), -intervalLeft);
808 leftOverTime.normalize();
809 *fractionalSmallestUnit = leftOverTime.toTimeUnit(smallestUnit);
815 intervalLeft = intervalLeft % unitFactor;
819 unitFactor = (Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000));
820 CHECK_INT_LIMIT(intervalLeft, unitFactor)
822 *hoursPtr = intervalLeft / unitFactor;
823 if (smallestUnit == Qt::Hours) {
824 QTimeSpan leftOverTime(referencedDate(), -intervalLeft);
825 leftOverTime.normalize();
826 *fractionalSmallestUnit = leftOverTime.toTimeUnit(smallestUnit);
832 intervalLeft = intervalLeft % unitFactor;
836 unitFactor = (Q_INT64_C(60) * Q_INT64_C(1000));
837 CHECK_INT_LIMIT(intervalLeft, unitFactor)
839 *minutesPtr = intervalLeft / unitFactor;
840 if (smallestUnit == Qt::Minutes) {
841 QTimeSpan leftOverTime(referencedDate(), -intervalLeft);
842 leftOverTime.normalize();
843 *fractionalSmallestUnit = leftOverTime.toTimeUnit(smallestUnit);
848 if (*minutesPtr != 0 )
849 intervalLeft = intervalLeft % unitFactor;
853 unitFactor = (Q_INT64_C(1000));
854 CHECK_INT_LIMIT(intervalLeft, unitFactor)
856 *secondsPtr = intervalLeft / unitFactor;
857 if (smallestUnit == Qt::Seconds) {
858 QTimeSpan leftOverTime(referencedDate(), -intervalLeft);
859 leftOverTime.normalize();
860 *fractionalSmallestUnit = leftOverTime.toTimeUnit(smallestUnit);
865 if (*secondsPtr > 0 )
866 intervalLeft = intervalLeft % unitFactor;
871 CHECK_INT_LIMIT(intervalLeft, unitFactor)
873 *msecondsPtr = intervalLeft;
874 if (fractionalSmallestUnit) {
875 *fractionalSmallestUnit = qreal(intervalLeft);
883 Sets a part of the time span in the given format.
885 setPart allows you to adapt the current time span interval unit-by-unit based on
886 any time format. Where \l setFromTimeUnit resets the complete time interval, setPart
887 only sets a specific part in a chosen format.
890 If you have a time span representing 3 weeks, 2 days, 4 hours, 31 minutes
891 and 12 seconds, you can change the number of hours to 2 by just calling
893 span.setPart(Qt::Hours, 2, Qt::Weeks | Qt::Days | Qt::Hours | Qt::Minutes | Qt::Seconds);
896 Note that just like with any other function, you can not use the Months and Years
897 units without using a reference date.
899 void QTimeSpan::setPart(Qt::TimeSpanUnit unit, int interval, Qt::TimeSpanFormat format)
901 if (!format.testFlag(unit)) {
902 qWarning() << "Can not set a unit that is not part of the format. Ignoring.";
906 QTimeSpanPrivate::TimePartHash partsHash(format);
907 bool result = partsHash.fill(*this);
910 qWarning() << "Retreiving parts failed, cannot set parts. Ignoring.";
914 d->addUnit(this, unit, interval - *(partsHash.value(unit) ) );
918 Returns \c Qt::TimeSpanUnit representing the order of magnitude of the time span.
919 That is, the largest unit that can be used to display the time span that
920 will result in a non-zero value.
922 If the QTimeSpan does not have a valid reference date, the largest
923 possible time unit that will be returned is Qt::Weeks. Otherwise,
924 the largest possible time unit is Qt::Years.
926 Qt::TimeSpanUnit QTimeSpan::magnitude()
928 qint64 mag = d->interval;
932 return Qt::Milliseconds;
933 if (mag < (Q_INT64_C(60) * Q_INT64_C(1000)))
935 if (mag < (Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000)))
937 if (mag < (Q_INT64_C(24) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000)))
939 if (mag < (Q_INT64_C(7) * Q_INT64_C(24) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000)))
942 //those the simple cases. The rest is dependent on if there is a reference date
943 if (hasValidReference()) {
944 //simple test. If bigger than 366 (not 365!) then we are certain of dealing with years
945 if (mag > (Q_INT64_C(366) * Q_INT64_C(24) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000)))
947 //we need a more complicated test
950 parts(0, 0, 0, 0, 0, 0, &months, &years);
961 Returns \c true if there is a valid reference date set, false otherwise.
963 bool QTimeSpan::hasValidReference() const
965 return d->reference.isValid();
969 Returns the reference date. Note that the reference date may be invalid.
971 QDateTime QTimeSpan::referenceDate() const
977 Sets the reference date.
979 If there currently is a reference date, the referenced date will
980 not be affected. That means that the length of the time span will
981 change. If there currently is no reference date set, the interval
982 will not be affected and this function will have the same
983 effect as \l moveReferenceDate().
985 \sa moveReferenceDate() setReferencedDate() moveReferencedDate()
987 void QTimeSpan::setReferenceDate(const QDateTime &referenceDate)
989 if (d->reference.isValid() && referenceDate.isValid()) {
990 *this = referencedDate() - referenceDate;
992 d->reference = referenceDate;
997 Moves the time span to align the time spans reference date with the
998 new reference date \a referenceDate.
1000 Note that the length of the time span will not be modified, so the
1001 referenced date will shift as well. If no reference date was set
1002 before, it is set now and the referenced date will become valid.
1004 \sa setReferenceDate() setReferencedDate() moveReferencedDate()
1006 void QTimeSpan::moveReferenceDate(const QDateTime &referenceDate)
1008 d->reference = referenceDate;
1012 Sets the referenced date.
1014 If there currently is a reference date, that reference date will
1015 not be affected. This implies that the length of the time span changes.
1016 If there currently is no reference date set, the interval
1017 will not be affected and this function will have the same
1018 effect as \l moveReferencedDate().
1020 \sa setReferenceDate() moveReferenceDate() moveReferencedDate()
1023 void QTimeSpan::setReferencedDate(const QDateTime &referencedDate)
1025 if (d->reference.isValid()) {
1026 *this = referencedDate - d->reference;
1028 d->reference = referencedDate.addMSecs(-(d->interval));
1033 Moves the time span to align the time spans referenced date with the
1034 new referenced date.
1036 Note that the length of the time span will not be modified, so the
1037 reference date will shift as well. If no reference date was set
1038 before, it is set now.
1040 \sa setReferenceDate() setReferencedDate() moveReferencedDate()
1042 void QTimeSpan::moveReferencedDate(const QDateTime &referencedDate)
1044 d->reference = referencedDate.addMSecs(-(d->interval));
1048 Returns the referenced date and time.
1050 The referenced QDateTime is the "other end" of the QTimeSpan from
1053 An invalid QDateTime will be returned if no valid reference date
1056 QDateTime QTimeSpan::referencedDate() const
1058 if (!(d->reference.isValid()))
1061 QDateTime dt(d->reference);
1062 dt = dt.addMSecs(d->interval);
1066 // Comparison operators
1068 Returns true if this QTimeSpan and \a other have both the same
1069 reference date and the same length.
1071 Note that two QTimeSpan objects that span the same period, but
1072 where one is positive and the other is negative are \b not considdered
1073 equal. If you need to compare those, compare the normalized
1078 bool QTimeSpan::operator==(const QTimeSpan &other) const
1080 return ((d->interval == other.d->interval)
1081 && (d->reference == other.d->reference));
1085 Returns true if the interval of this QTimeSpan is shorter than
1086 the interval of the \a other QTimeSpan.
1088 bool QTimeSpan::operator<(const QTimeSpan &other) const
1090 return d->interval < other.d->interval;
1094 Returns true if the interval of this QTimeSpan is shorter or equal
1095 than the interval of the \a other QTimeSpan.
1097 bool QTimeSpan::operator<=(const QTimeSpan &other) const
1099 return d->interval <= other.d->interval;
1103 Returns true if the interval of this QTimeSpan is equal
1104 to the interval of the \a other QTimeSpan. That is, if they have the
1107 The default value of \a normalize is false. If normalize is true, the
1108 absolute values of the interval lengths are compared instead of the
1112 QTimeSpan s1 = 2 * QTimeSpan::day();
1113 QTimeSpan s2 = -2 * QTimeSpan::day();
1114 qDebug() << s1.matchesLength(s2); //returns false
1115 qDebug() << s1.matchesLength(s2, true); //returns true
1118 bool QTimeSpan::matchesLength(const QTimeSpan &other, bool normalize) const
1121 return d->interval == other.d->interval;
1123 return qAbs(d->interval) == qAbs(other.d->interval);
1127 // Arithmetic operators
1129 Adds the interval of the \a other QTimeSpan to the interval of
1130 this QTimeSpan. The reference date of the \a other QTimeSpan is
1133 QTimeSpan & QTimeSpan::operator+=(const QTimeSpan &other)
1135 d->interval += other.d->interval;
1140 Adds the number of milliseconds \a msecs to the interval of
1141 this QTimeSpan. The reference date of the QTimeSpan is
1144 QTimeSpan & QTimeSpan::operator+=(qint64 msecs)
1146 d->interval += msecs;
1151 Substracts the interval of the \a other QTimeSpan from the interval of
1152 this QTimeSpan. The reference date of the \a other QTimeSpan is
1153 ignored while the reference date of this QTimeSpan is not affected.
1155 QTimeSpan & QTimeSpan::operator-=(const QTimeSpan &other)
1157 d->interval -= (other.d->interval);
1162 Substracts the number of milliseconds \a msecs from the interval of
1163 this QTimeSpan. The reference date of the QTimeSpan is
1166 QTimeSpan & QTimeSpan::operator-=(qint64 msecs)
1168 d->interval -= msecs;
1173 Multiplies the interval described by this QTimeSpan by the
1174 given \a factor. The reference date of the QTimeSpan is not
1177 QTimeSpan & QTimeSpan::operator*=(qreal factor)
1179 d->interval *= factor;
1184 Multiplies the interval described by this QTimeSpan by the
1185 given \a factor. The reference date of the QTimeSpan is not
1188 QTimeSpan & QTimeSpan::operator*=(int factor)
1190 d->interval *= factor;
1195 Divides the interval described by this QTimeSpan by the
1196 given \a factor. The reference date of the QTimeSpan is not
1199 QTimeSpan & QTimeSpan::operator/=(qreal factor)
1201 d->interval /= factor;
1206 Divides the interval described by this QTimeSpan by the
1207 given \a factor. The reference date of the QTimeSpan is not
1210 QTimeSpan & QTimeSpan::operator/=(int factor)
1212 d->interval /= factor;
1217 Modifies this QTimeSpan to be the union of this QTimeSpan with \a other.
1219 The union of two QTimeSpans is defined as the minimum QTimeSpan that
1220 encloses both QTimeSpans. The QTimeSpans need not be overlapping.
1222 \warning Only works if both QTimeSpans have a valid reference date.
1227 QTimeSpan& QTimeSpan::operator|=(const QTimeSpan& other) // Union
1229 Q_ASSERT_X((hasValidReference() && other.hasValidReference()),
1230 "assignment-or operator", "Both participating time spans need a valid reference date");
1232 //do we need to check for self-assignment?
1234 QDateTime start = qMin(startDate(), other.startDate());
1235 QDateTime end = qMax(endDate(), other.endDate());
1237 *this = end - start;
1242 Modifies this QTimeSpan to be the intersection of this QTimeSpan and \a other.
1244 The intersection of two QTimeSpans is defined as the maximum QTimeSpan that
1245 both QTimeSpans have in common. If the QTimeSpans don't overlap, a null QTimeSpan
1246 will be returned. The returned QTimeSpan will be positive.
1248 \warning Only works if both QTimeSpans have a valid reference date.
1253 QTimeSpan& QTimeSpan::operator&=(const QTimeSpan &other) // Intersection
1255 Q_ASSERT_X((hasValidReference() && other.hasValidReference()),
1256 "assignment-or operator", "Both participating time spans need a valid reference date");
1258 //do we need to check for self-assignment?
1260 const QTimeSpan* first = this;
1261 const QTimeSpan* last = &other;
1262 if (other.startDate() < startDate()) {
1267 //check if there is overlap at all. If not, reset the interval to 0
1268 if (!(first->endDate() > last->startDate()) ) {
1273 *this = qMin(first->endDate(), last->endDate()) - last->startDate();
1278 Returns true if this QTimeSpan overlaps with the \a other QTimeSpan.
1279 If one or both of the QTimeSpans do not have a valid reference date, this
1280 function returns false.
1282 bool QTimeSpan::overlaps(const QTimeSpan &other) const
1284 if (!hasValidReference() || !other.hasValidReference())
1287 const QTimeSpan* first = this;
1288 const QTimeSpan* last = &other;
1289 if (other.startDate() < startDate()) {
1294 return (first->endDate() > last->startDate());
1298 Returns a new QTimeSpan that represents the intersection of this QTimeSpan with \a other.
1300 The intersection of two QTimeSpans is defined as the maximum QTimeSpan that
1301 both QTimeSpans have in common. If the QTimeSpans don't overlap, a null QTimeSpan
1302 will be returned. Any valid returned QTimeSpan will be positive.
1304 \warning Only works if both QTimeSpans have a valid reference date.
1309 QTimeSpan QTimeSpan::overlapped(const QTimeSpan &other) const
1311 Q_ASSERT_X((hasValidReference() && other.hasValidReference()),
1312 "assignment-or operator", "Both participating time spans need a valid reference date");
1314 const QTimeSpan* first = this;
1315 const QTimeSpan* last = &other;
1316 if (other.startDate() < startDate()) {
1321 //check if there is overlap at all. If not, reset the interval to 0
1322 if (!(first->endDate() >= last->startDate()) ) {
1326 return qMin(first->endDate(), last->endDate()) - last->startDate();
1330 Returns a new QTimeSpan that represents the union of this QTimeSpan with \a other.
1332 The union of two QTimeSpans is defined as the minimum QTimeSpan that
1333 encloses both QTimeSpans. The QTimeSpans need not be overlapping.
1335 \warning Only works if both QTimeSpans have a valid reference date.
1339 QTimeSpan QTimeSpan::united(const QTimeSpan &other) const
1341 Q_ASSERT_X((hasValidReference() && other.hasValidReference()),
1342 "assignment-or operator", "Both participating time spans need a valid reference date");
1344 QDateTime start = qMin(startDate(), other.startDate());
1345 QDateTime end = qMax(endDate(), other.endDate());
1347 return ( end - start );
1351 Determines if the given \a dateTime lies within the time span. The begin
1352 and end times are taken to be contained in the time span in this function.
1354 If the time span does not have a valid reference date, this function
1357 bool QTimeSpan::contains(const QDateTime &dateTime) const
1359 if (!hasValidReference())
1362 return ((startDate() <= dateTime)
1363 && (endDate()) >= dateTime);
1367 Determines if the given date lies within the time span. The begin
1368 and end times are taken to be contained in the time span in this function.
1369 Just like in the QTimeSpan constructors that take a QDate, the time will assumed
1372 If the time span does not have a valid reference date, this function
1375 bool QTimeSpan::contains(const QDate &date) const
1378 return contains(dt);
1382 Determines if the given \a time lies within this QTimeSpan. The begin
1383 and end times are taken to be contained in the time span in this function.
1384 Just like in the QTimeSpan constructors that take a QTime, the date
1385 will be set to today.
1387 If the time span does not have a valid reference date, this function
1390 bool QTimeSpan::contains(const QTime &time) const
1392 QDateTime dt(QDate::currentDate());
1394 return contains(dt);
1398 Determines if the \a other QTimeSpan lies within this time span. Another
1399 time span is contained if its start time is the same or later then the
1400 start time of this time span, and its end time is the same or earlier
1401 than the end time of this time span.
1403 If either time span does not have a valid reference date, this function
1406 bool QTimeSpan::contains(const QTimeSpan &other) const
1408 if (!(hasValidReference() && other.hasValidReference()))
1411 return ((startDate() <= other.startDate())
1412 && (endDate()) >= other.endDate());
1416 Returns a new QTimeSpan representing the same time span as this QTimeSpan, but
1417 that is guaranteed to be positive; that is, to have the reference date before or
1418 equal to the referenced date.
1423 QTimeSpan QTimeSpan::normalized() const
1425 QTimeSpan ts(*this);
1431 Modifies this QTimeSpan to represent the same time span, but
1432 that is guaranteed to be positive; that is, to have the reference date before or
1433 equal to the referenced date. If there is no valid reference date, the interval
1434 will just be made positive.
1439 void QTimeSpan::normalize()
1441 if (d->interval < 0) {
1442 if (hasValidReference())
1443 d->reference = referencedDate();
1445 d->interval = qAbs(d->interval);
1450 Returns a copy of this QTimeSpan that is guaranteed to be positive; that is,
1451 to have the reference date before or equal to the referenced date. The reference
1452 date is not modified. That implies that if there is a reference date, and the
1453 QTimeSpan is negative, the returned QTimeSpan will describe the time span \i after
1454 the reference date instead of the time span \i before.
1456 If there is no valid reference date, the interval will just be made positive.
1461 QTimeSpan QTimeSpan::abs() const
1463 QTimeSpan result(*this);
1464 result.d->interval = qAbs(result.d->interval);
1470 Returns true if the interval is negative.
1473 bool QTimeSpan::isNegative() const
1475 return d->interval < 0;
1479 \fn QTimeSpan::isNormal() const
1481 Returns true if the interval is normal, that is: not negative.
1486 Returns the first date of the spanned time period. If there is no valid
1487 reference date, an invalid QDateTime will be returned.
1489 QDateTime QTimeSpan::startDate() const
1492 return referencedDate();
1494 return referenceDate();
1498 Returns the last date of the spanned time period. If there is no valid
1499 reference date, an invalid QDateTime will be returned.
1501 QDateTime QTimeSpan::endDate() const
1504 return referenceDate();
1506 return referencedDate();
1510 Returns the duration of the QTimeSpan expressed in milliseconds. This
1511 value may be negative.
1513 qint64 QTimeSpan::toMSecs() const
1519 Returns the duration of the QTimeSpan expressed in the given TimeSpanUnit. This
1520 value may be negative.
1522 qreal QTimeSpan::toTimeUnit(Qt::TimeSpanUnit unit) const
1524 qreal interval = qreal(d->interval);
1525 switch (unit){ //fall through is intentional
1536 case Qt::Milliseconds:
1539 Q_ASSERT_X(hasValidReference(), "toTimeUnit", "Can not convert to time units that depend on the reference date (month and year).");
1543 if (unit == Qt::Months) {
1544 succes = parts(0, 0, 0, 0, 0, 0, &intResult, 0, &result);
1545 } else if (unit == Qt::Years) {
1546 succes = parts(0, 0, 0, 0, 0, 0, 0, &intResult, &result);
1559 Sets the length of this QTimeSpan from the given number of milliseconds \msecs.
1560 The reference date is not affected.
1562 void QTimeSpan::setFromMSecs(qint64 msecs)
1564 d->interval = msecs;
1568 Sets the length of this QTimeSpan from the \a interval number of TimeSpanUnits \a unit.
1569 The reference date is not affected.
1571 void QTimeSpan::setFromTimeUnit(Qt::TimeSpanUnit unit, qreal interval)
1574 case Qt::Weeks: //fall through of cases is intentional!
1584 case Qt::Milliseconds:
1587 setFromMonths(interval);
1590 setFromYears(interval);
1593 Q_ASSERT_X(false, "setFromTimeUnit", "Can not set a QTimeSpan duration from unknown TimeSpanUnit.");
1596 d->interval = qint64(interval);
1600 Sets the interval of the time span as a number of \a months.
1602 \warning This function can only be used if a valid reference date has been set.
1604 The setFromMonths method deals with fractional months in the following way: first,
1605 the whole number of months is extracted and added to the reference date. The fractional
1606 part of the number of months is then multiplied with the number of days in the month
1607 in which that date falls. If the number of months is negative and adding a whole month
1608 yields a date exactly on a month boundary, the number of days in the month before is
1610 That number is used as the number of days and is added to the interval.
1613 QTimeSpan ts(QDate(2010,01,01));
1614 ts.setFromMonths(1.5); // ts's referenced date is now Februari 15, 0:00:00
1615 ts.setFromMonths(2.5); // ts's referenced date is now March 16, 12:00:00
1616 QTimeSpan ts2(QDate(2008,01,01)); //2008 is a leap year
1617 ts2.setFromMonths(1.5); // ts2's referenced date is now Februari 15, 12:00:00
1618 QTimeSpan ts3(QDate(2008,03,01)); //2008 is a leap year
1619 ts3.setFromMonths(-0.5); // ts3's referenced date is now Februari 15: 12:00:00 //
1622 void QTimeSpan::setFromMonths(qreal months)
1624 Q_ASSERT_X(hasValidReference(), "setFromMonths", "Can not set interval from time unit month if there is no reference date.");
1626 int fullMonths = int(months);
1627 qreal fractionalMonth = months - fullMonths;
1629 QDateTime endDate = d->reference;
1630 endDate = endDate.addMonths(fullMonths);
1632 int days = d->daysInMonth(endDate, fractionalMonth < 0);
1634 QTimeSpan tmp = endDate - d->reference;
1635 qreal fractionalDays = fractionalMonth * days;
1636 d->interval = tmp.toMSecs() + qint64(fractionalDays * 24.0 * 60.0 * 60.0 * 1000.0);
1640 Sets the interval of the time span as a number of \a years.
1642 \warning This function can only be used if a valid reference date has been set.
1644 The setFromYears method deals with fractional years in the following way: first,
1645 the whole number of years is extracted and added to the reference date. The fractional
1646 part of the number of years is then multiplied with the number of days in the year
1647 in which that date falls. That number is used as the number of days and is added to the
1649 If the number of years is negative and adding the whole years yields a date exactly on
1650 a year boundary, the number of days in the year before is used instead.
1652 void QTimeSpan::setFromYears(qreal years)
1654 Q_ASSERT_X(hasValidReference(), "setFromYears", "Can not set interval from time unit year if there is no reference date.");
1656 int fullYears = int(years);
1657 qreal fractionalYear = years - fullYears;
1659 QDateTime endDate = d->reference;
1660 endDate = endDate.addYears(fullYears);
1663 QDateTime measureDate(endDate);
1664 if (fractionalYear < 0)
1665 measureDate = measureDate.addMSecs(-1);
1667 if (QDate::isLeapYear(measureDate.date().year()))
1668 days += 1.0; //februari has an extra day this year...
1671 QTimeSpan tmp = endDate - d->reference;
1672 qreal fractionalDays = fractionalYear * days;
1673 d->interval = tmp.toMSecs() + qint64(fractionalDays * 24.0 * 60.0 * 60.0 * 1000.0);
1676 #ifndef QT_NO_DATASTREAM
1680 This operator allows you to stream a QTimeSpan into a QDataStream.
1681 \sa operator>>(QDataStream &stream, QTimeSpan &span)
1683 QDataStream & operator<<(QDataStream &stream, const QTimeSpan & span)
1685 stream << span.d->reference << span.d->interval;
1692 This operator allows you to stream a QTimeSpan out of a QDataStream.
1693 \sa operator>>(QDataStream &stream, QTimeSpan &span)
1695 QDataStream & operator>>(QDataStream &stream, QTimeSpan &span)
1697 stream >> span.d->reference >> span.d->interval;
1703 Adds two QTimeSpan instances.
1705 The values of the intervals of the QTimeSpans are added up with normal
1706 arithmetic. Negative values will work as expected.
1708 If the \a left argument has a reference date, that reference will be used.
1709 If only the \a right argument has a reference date, then that reference
1710 date will be used as the new reference date.
1712 The above can have suprising consequences:
1714 // s1 and s2 are two QTimeSpan objects
1715 QTimeSpan s12 = s1 + s2;
1716 QTimeSpan s21 = s2 + s1;
1719 //may or may not happen, depending on the reference dates of s1 and s2.
1724 QTimeSpan operator+(const QTimeSpan &left, const QTimeSpan &right)
1726 QTimeSpan result(left);
1729 // only keep the right reference date if the left argument does not have one
1730 if (!left.hasValidReference() && right.hasValidReference())
1731 result.setReferenceDate(right.referenceDate());
1737 Substracts one QTimeSpan from another QTimeSpan.
1739 The value of the interval of the \a right QTimeSpan is substracted from the
1740 \a left QTimeSpan with normal arithmetic. Negative values will work as expected.
1742 If the \a left argument has a reference date, that reference will be kept.
1743 If only the \a right argument has a reference date, then that reference
1744 date will be used as the new reference date.
1748 QTimeSpan operator-(const QTimeSpan &left, const QTimeSpan &right)
1750 QTimeSpan result(left);
1753 // only keep the right reference date if the left argument does not have one
1754 if (!left.hasValidReference() && right.hasValidReference())
1755 result.setReferenceDate(right.referenceDate());
1761 Multiply a QTimeSpan by a scalar factor.
1763 Returns a new QTimeSpan object that has the same reference date as the
1764 \a left QTimeSpan, but with an interval length that is multiplied by the
1767 QTimeSpan operator*(const QTimeSpan &left, qreal right)
1769 QTimeSpan result(left);
1775 Multiply a QTimeSpan by a scalar factor.
1778 QTimeSpan operator*(const QTimeSpan &left, int right)
1780 QTimeSpan result(left);
1786 Divide a QTimeSpan by a scalar factor.
1788 Returns a new QTimeSpan object that has the same reference date as the
1789 \a left QTimeSpan, but with an interval length that is devided by the
1792 QTimeSpan operator/(const QTimeSpan &left, qreal right)
1794 QTimeSpan result(left);
1800 Divide a QTimeSpan by a scalar factor.
1803 QTimeSpan operator/(const QTimeSpan &left, int right)
1805 QTimeSpan result(left);
1811 Devides two QTimeSpans. The devision works on the interval lengths of
1812 the two QTimeSpan objects as you would expect from normal artithmatic.
1814 qreal operator/(const QTimeSpan &left, const QTimeSpan &right)
1816 return (qreal(left.toMSecs()) / qreal(right.toMSecs()));
1820 Returns a QTimeSpan object with the same reference date as the \a right
1821 hand argument, but with a negated interval. Note that unlike with the
1822 \l normalize() method, this function will result in a QTimeSpan that
1823 describes a different period if the QTimeSpan has a reference date because
1824 the reference date is not modified.
1828 QTimeSpan operator-(const QTimeSpan &right) // Unary negation
1830 QTimeSpan result(right);
1831 result.setFromMSecs(-result.toMSecs());
1836 Returns the union of the two QTimeSpans.
1840 QTimeSpan operator|(const QTimeSpan &left, const QTimeSpan &right) // Union
1842 QTimeSpan result(left);
1848 Returns the intersection of the two QTimeSpans.
1852 QTimeSpan operator&(const QTimeSpan &left, const QTimeSpan &right) // Intersection
1854 QTimeSpan result(left);
1860 // Operators that use QTimeSpan and other date/time classes
1862 Creates a new QTimeSpan object that describes the period between the two
1863 QDateTime objects. The \a right hand object will be used as the reference date,
1864 so that substracting a date in the past from a date representing now will yield
1865 a positive QTimeSpan.
1867 Note that while substracting two dates will result in a QTimeSpan describing
1868 the time between those dates, there is no pendant operation for adding two dates.
1870 Substractions involving an invalid QDateTime, will result in a time span with
1871 an interval length 0. If the right-hand QDateTime is valid, it will still be
1872 used as the reference date.
1874 QTimeSpan operator-(const QDateTime &left, const QDateTime &right)
1876 QTimeSpan result(right);
1877 if (left.isValid() && right.isValid())
1878 result = QTimeSpan(right, right.msecsTo(left));
1884 Creates a new QTimeSpan object that describes the period between the two
1885 QDate objects. The \a right hand object will be used as the reference date,
1886 so that substracting a date in the past from a date representing now will yield
1887 a positive QTimeSpan.
1889 Note that while substracting two dates will result in a QTimeSpan describing
1890 the time between those dates, there is no pendant operation for adding two dates.
1894 QTimeSpan operator-(const QDate &left, const QDate &right)
1896 QTimeSpan result = QDateTime(left) - QDateTime(right);
1901 Creates a new QTimeSpan object that describes the period between the two
1902 QTime objects. The \a right hand time will be used as the reference time,
1903 so that substracting a time in the past from a time representing now will yield
1904 a positive QTimeSpan.
1906 Note that that both times will be assumed to be on the current date.
1908 Also observe that while substracting two times will result in a QTimeSpan describing
1909 the time between those, there is no pendant operation for adding two times.
1911 QTimeSpan operator-(const QTime &left, const QTime &right)
1913 return QDateTime(QDate::currentDate(), left) - QDateTime(QDate::currentDate(), right);
1917 Returns the date described by the \a left hand date, shifted by the interval
1918 described in the QTimeSpan \a right. The reference date of the QTimeSpan, if set, is
1921 No rounding takes place. If a QTimeSpan describes 1 day, 23 hours and 59 minutes,
1922 adding that QTimeSpan to a QDate respresenting April 1 will still yield April 2.
1925 QDate operator+(const QDate &left, const QTimeSpan &right)
1928 return (dt + right).date();
1932 Returns the date and time described by the \a left hand QDateTime, shifted by
1933 the interval described in the QTimeSpan \a right. The reference date of the QTimeSpan, if set,
1936 QDateTime operator+(const QDateTime &left, const QTimeSpan &right)
1938 QDateTime result(left);
1939 result = result.addMSecs(right.toMSecs());
1944 Returns the time described by the \a left hand QTime, shifted by
1945 the interval described in the QTimeSpan \right. The reference date of the QTimeSpan, if set,
1948 \note that since QTimeSpan works with dates and times, the time returned will never
1949 be bigger than 23:59:59.999. The time will wrap to the next date. Use QDateTime objects
1950 if you need to keep track of that.
1954 QTime operator+(const QTime &left, const QTimeSpan &right)
1956 QDateTime dt(QDate::currentDate(), left);
1957 dt = dt.addMSecs(right.toMSecs());
1962 Returns the date described by the \a left hand date, shifted by the negated interval
1963 described in the QTimeSpan \a right. The reference date of the QTimeSpan, if set, is
1966 No rounding takes place. If a QTimeSpan describes 1 day, 23 hours and 59 minutes,
1967 adding that QTimeSpan to a QDate respresenting April 1 will still yield April 2.
1971 QDate operator-(const QDate &left, const QTimeSpan &right)
1974 return (dt - right).date();
1978 Returns the date and time described by the \a left hand QDateTime, shifted by
1979 the negated interval described in the QTimeSpan \a right. The reference date of the
1980 QTimeSpan, if set, is ignored.
1982 QDateTime operator-(const QDateTime &left, const QTimeSpan &right)
1984 QDateTime result(left);
1985 result = result.addMSecs( -(right.toMSecs()) );
1990 Returns the time described by the \a left hand QTime, shifted by
1991 the negated interval described in the QTimeSpan \a right. The reference date of
1992 the QTimeSpan, if set, is ignored.
1994 \note that since QTimeSpan works with dates and times, the time returned will never
1995 be bigger than 23:59:59.999. The time will wrap to the next date. Use QDateTimes
1996 if you need to keep track of that.
1998 QTime operator-(const QTime &left, const QTimeSpan &right)
2000 QDateTime dt(QDate::currentDate(), left);
2001 dt = dt.addMSecs( -(right.toMSecs()) );
2005 #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
2007 Operator to stream QTimeSpan objects to a debug stream.
2009 QDebug operator<<(QDebug debug, const QTimeSpan &ts)
2011 debug << "QTimeSpan(Reference Date =" << ts.referenceDate()
2012 << "msecs =" << ts.toMSecs() << ")";
2017 //String conversions
2018 #ifndef QT_NO_DATESTRING
2020 Returns an approximate representation of the time span length
2022 When representing the lenght of a time span, it is often not nessecairy to be
2023 completely accurate. For instance, when dispaying the age of a person, it is
2024 often enough to just state the number of years, or possibly the number of years
2025 and the number of months. Similary, when displaying how long a certain operation
2026 the user of your application started will run, it is useless to display the
2027 number of seconds left if the operation will run for hours more.
2029 toApproximateString() provides functionality to display the length of the
2030 QTimeSpan in such an approximate way. It will format the time using one or two
2031 neighbouring time units, chosen from the units set in \a format. The first
2032 time unit that will be used is the unit that represents the biggest portion
2033 of time in the span. The second time unit will be the time unit directly under
2034 that. The second unit will only be used if it is not 0, and if the first number
2035 is smaller than the indicated \a suppresSecondUnitLimit.
2037 The \a suppressSecondUnitLimit argument can be used to suppres, for instance,
2038 the number of seconds when the operation will run for more than five minutes
2039 more. The idea is that for an approximate representation of the time length,
2040 it is no longer relevant to display the second unit if the first respresents
2041 a time span that is perhaps an order of magnitude larger already.
2043 If you set \a suppressSecondUnitLimit to a negative number, the second unit will
2044 always be displayed, unless no valid unit for it could be found.
2046 \sa magnitude() toString()
2048 QString QTimeSpan::toApproximateString(int suppresSecondUnitLimit, Qt::TimeSpanFormat format)
2050 if (format==Qt::NoUnit)
2053 //retreive the time unit to use as the primairy unit
2055 int secondairy = -1;
2057 Qt::TimeSpanUnit primairyUnit = magnitude();
2058 while (!format.testFlag(primairyUnit ) && primairyUnit > Qt::NoUnit)
2059 primairyUnit = Qt::TimeSpanUnit(primairyUnit / 2);
2062 Qt::TimeSpanUnit secondairyUnit = Qt::NoUnit;
2063 if (primairyUnit > 1) {
2064 secondairyUnit = Qt::TimeSpanUnit(primairyUnit / 2);
2068 while (!format.testFlag(secondairyUnit) && secondairyUnit > Qt::NoUnit)
2069 secondairyUnit = Qt::TimeSpanUnit(secondairyUnit / 2);
2072 //build up hash with pointers to ints for the units that are set in format, and 0's for those that are not.
2074 QTimeSpanPrivate::TimePartHash partsHash(format);
2075 bool result = partsHash.fill(*this);
2078 qDebug() << "false result from parts function";
2082 primairy = *(partsHash.value(primairyUnit));
2083 if (secondairyUnit > 0) {
2084 secondairy = *(partsHash.value(secondairyUnit));
2092 && primairy < suppresSecondUnitLimit)
2093 || (suppresSecondUnitLimit < 0
2094 && secondairyUnit > Qt::NoUnit) )
2096 //we will display with two units
2097 return d->unitString(primairyUnit, primairy) + QLatin1String(", ") + d->unitString(secondairyUnit, secondairy);
2100 //we will display with only the primairy unit
2101 return d->unitString(primairyUnit, primairy);
2105 Returns a string representation of the duration of this time span in the requested \a format
2107 This function returns a representation of only the \i length of this time span. If
2108 you need the reference or referenced dates, access those using one of the provided
2109 methods and output them directly.
2111 The format parameter determines the format of the result string. The duration will be
2112 expressed in the units you use in the format.
2120 \o The number of years
2123 \o The number of months
2126 \o The number of weeks
2129 \o The number of days
2132 \o The number of hours
2135 \o The number of minutes
2138 \o The number of seconds
2141 \o The number of milliseconds
2144 Use a letter repeatingly to force leading zeros.
2146 Note that you can not use years or months if the QTimeSpan does not have a valid reference
2149 Characters in the string that don't represent a time unit, are used as literal strings in the
2150 output. Everything between single quotes will always be used as a literal string. This makes
2151 it possible to use the characters used for the time span format also as literal output. To use a
2152 single quote in the output, put two consecutive single quotes within a single quote literal
2153 string block. To just put a single quote in a the output, you need four consequtive single
2156 \sa toApproximateString()
2158 QString QTimeSpan::toString(const QString &format) const
2160 Qt::TimeSpanFormat tsFormat = Qt::NoUnit;
2161 QList<QTimeSpanPrivate::TimeFormatToken> tokenList = d->parseFormatString(format, tsFormat);
2163 QTimeSpanPrivate::TimePartHash partsHash(tsFormat);
2164 bool result = partsHash.fill(*this);
2169 QString formattedString;
2170 foreach(QTimeSpanPrivate::TimeFormatToken token, tokenList) {
2171 if (token.type == 0) {
2172 formattedString.append(token.string);
2174 Qt::TimeSpanUnit unit(token.type);
2175 formattedString.append (QString(QString::fromLatin1("%1"))
2176 .arg(*partsHash.value(unit),
2183 return formattedString;
2187 Returns a time span represented by the \a string using the \a format given, or an empty
2188 time span if the string cannot be parsed.
2190 The optional \a reference argument will be used as the reference date for the string.
2192 \note You can only use months or years if you also pass a valid reference.
2194 QTimeSpan QTimeSpan::fromString(const QString &string, const QString &format, const QDateTime &reference)
2198 There are at least two possible ways of parsing a string. On the one hand, you could use
2199 the lengths of string literals to determine the positions in the string where you expect
2200 the different parts of the string. On the other hand, you could use the actual contents
2201 of the literals as delimiters to figure out what parts of the string refer to what
2202 unit of time. In that case, the length of the time units would only matter if they are
2203 not surrounded by a string literal. Both seem useful. Perhaps we need two different
2206 The code here implements the first option. The overloaded version below implements a
2207 more flexible regexp based approach.
2210 //stage one: parse the format string
2211 QTimeSpan span(reference);
2212 Qt::TimeSpanFormat tsFormat = Qt::NoUnit;
2213 QList<QTimeSpanPrivate::TimeFormatToken> tokenList = span.d->parseFormatString(format, tsFormat);
2215 //prepare the temporaries
2216 QTimeSpanPrivate::TimePartHash partsHash(tsFormat);
2217 QString input(string);
2219 //extract the values from the input string into our temporary structure
2220 foreach(const QTimeSpanPrivate::TimeFormatToken token, tokenList) {
2221 if (token.type == Qt::NoUnit) {
2222 input = input.remove(0, token.length);
2224 QString part = input.left(token.length);
2225 input = input.remove(0, token.length);
2227 bool success(false);
2228 part = part.trimmed();
2229 int value = part.toInt(&success, 10);
2233 *(partsHash.value(token.type)) = value;
2237 //construct the time span from the temporary data
2238 //we must set the number of years and months first; for the rest order is not important
2239 if (partsHash.value(Qt::Years)) {
2240 span.d->addUnit(&span, Qt::Years, *(partsHash.value(Qt::Years)));
2241 delete partsHash.value(Qt::Years);
2242 partsHash.insert(Qt::Years, 0);
2244 if (partsHash.value(Qt::Months)) {
2245 span.d->addUnit(&span, Qt::Months, *(partsHash.value(Qt::Months)));
2246 delete partsHash.value(Qt::Months);
2247 partsHash.insert(Qt::Months, 0);
2250 //add the rest of the units
2251 QHashIterator<Qt::TimeSpanUnit, int*> it(partsHash);
2252 while (it.hasNext()) {
2255 span.d->addUnit(&span, it.key(), *(it.value()));
2256 qDebug() << "Added unit" << it.key() << "with value" << *(it.value()) << "new value" << span.d->interval;
2264 Returns a time span represented by the \a string using the \a patern given, or an empty
2265 time span if the \a string cannot be parsed. Each pair of capturing parenthesis can
2266 extract a time unit. The order in which the units appear is given by the list of
2267 arguments unit1 to unit8. Captures for which the corresponding type is set to
2268 Qt::NoUnit will be ignored.
2270 The \a reference argument will be used as the reference date for the string.
2272 \note You can only use months or years if you also pass a valid \a reference.
2274 QTimeSpan QTimeSpan::fromString(const QString &string, const QRegExp &pattern, const QDateTime &reference,
2275 Qt::TimeSpanUnit unit1, Qt::TimeSpanUnit unit2, Qt::TimeSpanUnit unit3,
2276 Qt::TimeSpanUnit unit4, Qt::TimeSpanUnit unit5, Qt::TimeSpanUnit unit6,
2277 Qt::TimeSpanUnit unit7, Qt::TimeSpanUnit unit8)
2279 if (pattern.indexIn(string) < 0)
2282 QTimeSpanPrivate::TimePartHash partsHash(Qt::NoUnit);
2284 QList<Qt::TimeSpanUnit> unitList;
2285 unitList << unit1 << unit2 << unit3 << unit4 << unit5 << unit6 << unit7 << unit8;
2287 for (int i(0); i < qMin(pattern.captureCount(), 8 ); ++i) {
2288 if (unitList.at(i) > Qt::NoUnit) {
2289 partsHash.addUnit(unitList.at(i));
2290 QString capture = pattern.cap(i + 1);
2292 int value = capture.toInt(&ok, 10);
2296 *(partsHash.value(unitList.at(i))) = value;
2300 //create the time span to return
2301 QTimeSpan span(reference);
2303 //construct the time span from the temporary data
2304 //we must set the number of years and months first; for the rest order is not important
2305 if (partsHash.value(Qt::Years)) {
2306 span.d->addUnit(&span, Qt::Years, *(partsHash.value(Qt::Years)));
2307 delete partsHash.value(Qt::Years);
2308 partsHash.insert(Qt::Years, 0);
2310 if (partsHash.value(Qt::Months)) {
2311 span.d->addUnit(&span, Qt::Months, *(partsHash.value(Qt::Months)));
2312 delete partsHash.value(Qt::Months);
2313 partsHash.insert(Qt::Months, 0);
2316 //add the rest of the units
2317 QHashIterator<Qt::TimeSpanUnit, int*> it(partsHash);
2318 while (it.hasNext()) {
2321 span.d->addUnit(&span, it.key(), *(it.value()));