Fix to make QTimeSpan compile with MSVC
[qt:qt.git] / src / corelib / tools / qtimespan.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Andre Somers, Sean Harmer.
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
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
14 ** this package.
15 **
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.
23 **
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.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qplatformdefs.h"
43 #include "qregexp.h"
44 #include "qdatastream.h"
45 #include "qlocale.h"
46 #include "qtimespan.h"
47 #include "qdebug.h"
48 #include "qcoreapplication.h"
49 #include "QtGlobal"
50
51 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
52 #include <qt_windows.h>
53 #endif
54 #ifndef Q_WS_WIN
55 #include <locale.h>
56 #endif
57
58 #include <time.h>
59 #if defined(Q_OS_WINCE)
60 #include "qfunctions_wince.h"
61 #endif
62
63 #if defined(Q_WS_MAC)
64 #include <private/qcore_mac_p.h>
65 #endif
66
67 #if defined(Q_OS_SYMBIAN)
68 #include <e32std.h>
69 #endif
70
71 #if defined(Q_WS_WIN)
72 #undef max
73 #endif
74
75 #include <limits>
76 #include <math.h>
77
78 /*!
79     \class QTimeSpan
80     \brief The QTimeSpan represents a span of time
81     \since 4.8
82
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
85     or not.
86
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.
92
93     \code
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;
97     \endcode
98
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.
103
104     \code
105     //Creates a QTimeSpan representing 2 days, 4 hours and 31 minutes.
106     QTimeSpan span(2 * QTimeSpan::day() + 4 * QTimeSpan::hour() + 31 * QTimeSpan::minute());
107     \endcode
108
109     Finally, a QTimeSpan can be constructed by using one of the static constructors
110     \l fromString() or \l fromTimeUnit().
111
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.
115
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.
122
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.
127
128     \code
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.
132     \endcode
133
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
137     fractional number.
138
139     \code
140     QTimeSpan span = QTimeSpan::hour() * 6;
141     qreal days = span.toDays(); //yields 0.25
142     \endcode
143
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
150     for the other units.
151
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
158     into account.
159
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
166     month.
167
168     \b Examples:
169     \list
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.
174     \endlist
175
176     The same goes for years.
177
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.
182
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.
190 */
191
192 QT_BEGIN_NAMESPACE
193
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) );}
199
200 class QTimeSpanPrivate : public QSharedData {
201 public:
202     qint64 interval;
203     QDateTime reference;
204
205     void addUnit(QTimeSpan* self, Qt::TimeSpanUnit unit, qreal value)
206     {
207         if (unit >= Qt::Months) {
208             QTimeSpan tempSpan(self->referencedDate());
209             tempSpan.setFromTimeUnit(unit, value);
210             interval += tempSpan.toMSecs();
211         } else {
212             switch (unit) {
213             case Qt::Weeks:
214                 interval += value * Q_INT64_C(1000) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(24) * Q_INT64_C(7);
215                 break;
216             case Qt::Days:
217                 interval += value * Q_INT64_C(1000) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(24);
218                 break;
219             case Qt::Hours:
220                 interval += value * Q_INT64_C(1000) * Q_INT64_C(60) * Q_INT64_C(60);
221                 break;
222             case Qt::Minutes:
223                 interval += value * Q_INT64_C(1000) * Q_INT64_C(60);
224                 break;
225             case Qt::Seconds:
226                 interval += value * Q_INT64_C(1000);
227                 break;
228             case Qt::Milliseconds:
229                 interval += value;
230                 break;
231             default:
232                 break;
233             }
234         }
235     }
236
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);
241         if (lookBack)
242             measureDate = measureDate.addMSecs(-1);
243
244         return measureDate.date().daysInMonth();
245     }
246
247     class TimePartHash: public QHash<Qt::TimeSpanUnit, int*>
248     {
249     public:
250         TimePartHash(Qt::TimeSpanFormat format)
251         {
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;
256                     *newValue = 0;
257                     insert(u, newValue); //perhaps we can optimize this not to new each int individually?
258                 } else {
259                     insert(u, 0);
260                 }
261             }
262         }
263
264         ~TimePartHash()
265         {
266             qDeleteAll(*this);
267         }
268
269         inline bool fill(const QTimeSpan& span)
270         {
271             bool result = span.parts(value(Qt::Milliseconds),
272                                 value(Qt::Seconds),
273                                 value(Qt::Minutes),
274                                 value(Qt::Hours),
275                                 value(Qt::Days),
276                                 value(Qt::Weeks),
277                                 value(Qt::Months),
278                                 value(Qt::Years));
279             return result;
280         }
281
282         inline void addUnit(const Qt::TimeSpanUnit unit)
283         {
284             if (value(unit) != 0)
285                 return;
286
287             int* newValue = new int;
288             *newValue = 0;
289             insert(unit, newValue);
290         }
291
292     };
293
294     //returns a string representation of time in a single time unit
295     QString unitString(Qt::TimeSpanUnit unit, int num) const
296     {
297         switch (unit) {
298         case::Qt::Milliseconds:
299             return qApp->translate("QTimeSpanPrivate", "%n millisecond(s)", "", QCoreApplication::CodecForTr, num);
300         case::Qt::Seconds:
301             return qApp->translate("QTimeSpanPrivate", "%n second(s)", "", QCoreApplication::CodecForTr, num);
302         case::Qt::Minutes:
303             return qApp->translate("QTimeSpanPrivate", "%n minute(s)", "", QCoreApplication::CodecForTr, num);
304         case::Qt::Hours:
305             return qApp->translate("QTimeSpanPrivate", "%n hour(s)", "", QCoreApplication::CodecForTr, num);
306         case::Qt::Days:
307             return qApp->translate("QTimeSpanPrivate", "%n day(s)", "", QCoreApplication::CodecForTr, num);
308         case::Qt::Weeks:
309             return qApp->translate("QTimeSpanPrivate", "%n week(s)", "", QCoreApplication::CodecForTr, num);
310         case::Qt::Months:
311             return qApp->translate("QTimeSpanPrivate", "%n month(s)", "", QCoreApplication::CodecForTr, num);
312         case::Qt::Years:
313             return qApp->translate("QTimeSpanPrivate", "%n year(s)", "", QCoreApplication::CodecForTr, num);
314         default:
315             return QString();
316         }
317     }
318
319 #ifndef QT_NO_DATESTRING
320     struct TimeFormatToken
321     {
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
325     };
326
327     QList<TimeFormatToken> parseFormatString(const QString& formatString, Qt::TimeSpanFormat &format) const
328     {
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);
338
339
340         QList<TimeFormatToken> tokenList;
341         format = Qt::NoUnit;
342         int pos(0);
343         int length(formatString.length());
344         bool inLiteral(false);
345         while (pos < length) {
346             const QChar currentChar(formatString[pos]);
347             if (inLiteral) {
348                 if (currentChar == QLatin1Char('\'')) {
349                     inLiteral = false; //exit literal string mode
350                     if ((pos+1)<length) {
351                         if (formatString[pos+1] == QLatin1Char('\'')) {
352                             ++pos;
353
354                             TimeFormatToken token = tokenList.last();
355                             token.string.append(QChar('\'', 0));
356                             token.length = token.string.length();
357                             tokenList[tokenList.length()-1] = token;
358
359                             inLiteral = true; //we *are* staying in literal string mode
360                         }
361                     }
362                 } else {
363                     TimeFormatToken token = tokenList.last();
364                     token.string.append(currentChar);
365                     token.length = token.string.length();
366                     tokenList[tokenList.length()-1] = token;
367                 }
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;
373                     token.length = 0;
374                     tokenList << token;
375                 } else {
376                     if (tokenHash.contains(currentChar)) {
377                         Qt::TimeSpanUnit unit = tokenHash.value(currentChar);
378
379                         TimeFormatToken token;
380                         token.length = 0;
381                         token.type = unit;
382                         if ((!tokenList.isEmpty()) && (tokenList.last().type == unit))
383                             token = tokenList.takeLast();
384
385                         token.length+=1;
386                         tokenList.append(token);
387
388                         format |= unit;
389                     } else {
390                         //ignore character?
391                         TimeFormatToken token;
392                         token.length = 0;
393                         token.type = Qt::NoUnit;
394                         if ((!tokenList.isEmpty()) && (tokenList.last().type == Qt::NoUnit))
395                             token = tokenList.takeLast();
396
397                         token.string.append(currentChar);
398                         token.length= token.string.length();
399                         tokenList.append(token);
400                     }
401                 }
402             }
403
404             ++pos;
405         }
406
407         return tokenList;
408     }
409 #endif
410
411 };
412
413 /*!
414     Default constructor
415
416     Constructs a null QTimeSpan
417 */
418 QTimeSpan::QTimeSpan()
419     : d(new QTimeSpanPrivate)
420 {
421     d->interval = 0;
422 }
423
424 /*!
425     Constructor
426     \overload QTimeSpan()
427
428     Constructs QTimeSpan of size \a msecs milliseconds. The reference date will
429     be invalid.
430 */
431 QTimeSpan::QTimeSpan(qint64 msecs)
432     : d(new QTimeSpanPrivate)
433 {
434     d->interval = msecs;
435 }
436
437 /*!
438     Copy Constructor
439 */
440 QTimeSpan::QTimeSpan(const QTimeSpan& other):
441         d(other.d)
442 {
443 }
444
445 /*!
446     Constructor
447     \overload QTimeSpan()
448
449     Constructs QTimeSpan of size \a msecs milliseconds from the given \a reference date
450     and time.
451 */
452 QTimeSpan::QTimeSpan(const QDateTime &reference, qint64 msecs)
453     : d(new QTimeSpanPrivate)
454 {
455     d->interval = msecs;
456     d->reference = reference;
457 }
458
459 /*!
460     Constructor
461     \overload QTimeSpan()
462
463     Constructs QTimeSpan of size \a msecs milliseconds from the given \a reference date.
464     The reference time will be 0:00:00.000
465 */
466 QTimeSpan::QTimeSpan(const QDate &reference, quint64 msecs)
467     : d(new QTimeSpanPrivate)
468 {
469     d->interval = msecs;
470     d->reference = QDateTime(reference);
471 }
472
473 /*!
474     Constructor
475     \overload QTimeSpan()
476
477     Constructs QTimeSpan of size \a msecs milliseconds from the given \a reference time.
478     The reference date will be today's date.
479 */
480 QTimeSpan::QTimeSpan(const QTime &reference, quint64 msecs)
481     : d(new QTimeSpanPrivate)
482 {
483     d->interval = msecs;
484     QDateTime todayReference(QDate::currentDate());
485     todayReference.setTime(reference);
486     d->reference = todayReference;
487 }
488
489 /*!
490     Constructor
491     \overload QTimeSpan()
492
493     Constructs a QTimeSpan of the same length as \a other from the given \a reference date time.
494 */
495 QTimeSpan::QTimeSpan(const QDateTime& reference, const QTimeSpan& other)
496     : d(new QTimeSpanPrivate)
497 {
498     d->reference = reference;
499     d->interval = other.d->interval;
500 }
501
502 /*!
503     Constructor
504
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
507 */
508 QTimeSpan::QTimeSpan(const QDate& reference, const QTimeSpan& other)
509     : d(new QTimeSpanPrivate)
510 {
511     d->reference = QDateTime(reference);
512     d->interval = other.d->interval;
513 }
514
515 /*!
516     Constructor
517
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.
520 */
521 QTimeSpan::QTimeSpan(const QTime& reference, const QTimeSpan& other)
522     : d(new QTimeSpanPrivate)
523 {
524     QDateTime todayReference(QDate::currentDate());
525     todayReference.setTime(reference);
526     d->reference = todayReference;
527     d->interval = other.d->interval;
528 }
529
530
531 /*!
532     Destructor
533 */
534 QTimeSpan::~QTimeSpan()
535 {
536 }
537
538 /*!
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.
541
542     \sa isNull() hasValidReference()
543 */
544 bool QTimeSpan::isEmpty() const
545 {
546     return d->interval == 0;
547 }
548
549 /*!
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.
552
553     \sa isEmpty()
554 */
555 bool QTimeSpan::isNull() const
556 {
557     return isEmpty() && (!hasValidReference());
558 }
559
560 /*!
561   Assignment operator
562 */
563 QTimeSpan& QTimeSpan::operator=(const QTimeSpan& other) {
564     if (&other == this)
565         return *this;
566
567     d = other.d;
568     return *this;
569 }
570
571 /*!
572     Returns a new QTimeSpan instance initialized to \a interval number of
573     units \a unit. The default reference date is invalid.
574
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.
577
578     \sa setFromTimeUnit()
579 */
580 QTimeSpan QTimeSpan::fromTimeUnit(Qt::TimeSpanUnit unit, qreal interval, const QDateTime& reference )
581 {
582     switch (unit){ //note: fall through is intentional!
583     case Qt::Weeks:
584         interval *= 7.0;
585     case Qt::Days:
586         interval *= 24.0;
587     case Qt::Hours:
588         interval *= 60.0;
589     case Qt::Minutes:
590         interval *= 60.0;
591     case Qt::Seconds:
592         interval *= 1000.0;
593     case Qt::Milliseconds:
594         break;
595     default:
596         if (reference.isValid()) {
597             QTimeSpan result(reference);
598             result.setFromTimeUnit(unit, interval);
599             return result;
600         }
601         Q_ASSERT_X(false, "static constructor", "Can not construct QTimeSpan from Month or Year TimeSpanUnit without a valid reference date.");
602         return QTimeSpan();
603     }
604
605     return QTimeSpan(reference, qint64(interval));
606 }
607
608 /*!
609     Returns the number of the requested units indicated by \a unit when formatted
610     as \a format.
611
612     \sa parts()
613 */
614 int QTimeSpan::part(Qt::TimeSpanUnit unit, Qt::TimeSpanFormat format) const
615 {
616     if (!format.testFlag(unit))
617         return 0;
618
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");
622
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));
627         }
628     }
629
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);
633
634     if (!result) {
635         //what to do? Assert perhaps?
636         qWarning() << "Result is invalid!";
637         return 0;
638     }
639
640     int val = *(partsHash.value(unit));
641     return val;
642 }
643
644 #define CHECK_INT_LIMIT(interval, unitFactor) if (interval >= (qint64(unitFactor) * qint64(std::numeric_limits<int>::max()) ) ) {qWarning() << "out of range" << unitFactor; return false;}
645
646 /*!
647   Retreives a breakup of the length of the QTimeSpan in different time units.
648
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.
655
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.
660
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
666   to 4.5.
667
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
670   representation.
671
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.
675
676   If this function returns false, the value of the passed in pointers is undefined.
677
678   \sa part()
679 */
680 bool QTimeSpan::parts(int *msecondsPtr,
681                       int *secondsPtr,
682                       int *minutesPtr,
683                       int *hoursPtr,
684                       int *daysPtr,
685                       int *weeksPtr,
686                       int *monthsPtr,
687                       int *yearsPtr,
688                       qreal *fractionalSmallestUnit) const
689 {
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?
692     */
693
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) {
697         if (yearsPtr)
698             smallestUnit = Qt::Years;
699         if (monthsPtr)
700             smallestUnit = Qt::Months;
701         if (weeksPtr)
702             smallestUnit = Qt::Weeks;
703         if (daysPtr)
704             smallestUnit = Qt::Days;
705         if (hoursPtr)
706             smallestUnit = Qt::Hours;
707         if (minutesPtr)
708             smallestUnit = Qt::Minutes;
709         if (secondsPtr)
710             smallestUnit = Qt::Seconds;
711         if (msecondsPtr)
712             smallestUnit = Qt::Milliseconds;
713     }
714
715     QTimeSpan ts(*this);
716     qint64 unitFactor;
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.";
721             return false;
722         }
723
724         QDate startDate = ts.startDate().date();
725         QDate endDate = ts.endDate().date();
726
727         //Deal with years
728         int years = endDate.year() - startDate.year();
729         if (endDate.month() < startDate.month()) {
730             years--;
731         } else if (endDate.month() == startDate.month()) {
732             if (endDate.day() < startDate.day())
733                 years--;
734         }
735
736         if (yearsPtr)
737             *yearsPtr = years;
738
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);
742
743         ts = QDateTime(endDate, ts.endDate().time()) - QDateTime(newStartDate, ts.startDate().time());
744
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));
750
751             return true;
752         }
753
754         //Deal with months
755         if (monthsPtr) {
756             int months = endDate.month() - startDate.month();
757             if (months < 0)
758                 months += 12;
759             if (endDate.day() < startDate.day())
760                 months--;
761
762             newStartDate = newStartDate.addMonths(months);
763             ts = QDateTime(endDate, ts.endDate().time()) - QDateTime(newStartDate, ts.startDate().time());
764
765             if (!yearsPtr)
766                 months += years * 12;
767
768             *monthsPtr = months;
769
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));
775
776                 return true;
777             }
778         }
779     }
780
781     //from here on, we use ts as the time span!
782     qint64 intervalLeft = ts.toMSecs();
783
784     if (weeksPtr) {
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)
787
788         *weeksPtr = intervalLeft / unitFactor;
789         if (smallestUnit == Qt::Weeks) {
790             QTimeSpan leftOverTime(referencedDate(), -intervalLeft);
791             leftOverTime.normalize();
792             *fractionalSmallestUnit = leftOverTime.toTimeUnit(smallestUnit);
793
794             return true;
795         }
796
797         if (*weeksPtr != 0)
798                         intervalLeft = intervalLeft % unitFactor;
799     }
800
801     if (daysPtr) {
802         unitFactor = (Q_INT64_C(24) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000));
803         CHECK_INT_LIMIT(intervalLeft, unitFactor)
804
805         *daysPtr = intervalLeft / unitFactor;
806         if (smallestUnit == Qt::Days) {
807             QTimeSpan leftOverTime(referencedDate(), -intervalLeft);
808             leftOverTime.normalize();
809             *fractionalSmallestUnit = leftOverTime.toTimeUnit(smallestUnit);
810
811             return true;
812         }
813
814         if (*daysPtr != 0 )
815             intervalLeft = intervalLeft % unitFactor;
816     }
817
818     if (hoursPtr) {
819         unitFactor = (Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000));
820         CHECK_INT_LIMIT(intervalLeft, unitFactor)
821
822         *hoursPtr = intervalLeft / unitFactor;
823         if (smallestUnit == Qt::Hours) {
824             QTimeSpan leftOverTime(referencedDate(), -intervalLeft);
825             leftOverTime.normalize();
826             *fractionalSmallestUnit = leftOverTime.toTimeUnit(smallestUnit);
827
828             return true;
829         }
830
831         if (*hoursPtr != 0 )
832             intervalLeft = intervalLeft % unitFactor;
833     }
834
835     if (minutesPtr) {
836         unitFactor = (Q_INT64_C(60) * Q_INT64_C(1000));
837         CHECK_INT_LIMIT(intervalLeft, unitFactor)
838
839         *minutesPtr = intervalLeft / unitFactor;
840         if (smallestUnit == Qt::Minutes) {
841             QTimeSpan leftOverTime(referencedDate(), -intervalLeft);
842             leftOverTime.normalize();
843             *fractionalSmallestUnit = leftOverTime.toTimeUnit(smallestUnit);
844
845             return true;
846         }
847
848         if (*minutesPtr != 0 )
849             intervalLeft = intervalLeft % unitFactor;
850     }
851
852     if (secondsPtr) {
853         unitFactor = (Q_INT64_C(1000));
854         CHECK_INT_LIMIT(intervalLeft, unitFactor)
855
856         *secondsPtr = intervalLeft / unitFactor;
857         if (smallestUnit == Qt::Seconds) {
858             QTimeSpan leftOverTime(referencedDate(), -intervalLeft);
859             leftOverTime.normalize();
860             *fractionalSmallestUnit = leftOverTime.toTimeUnit(smallestUnit);
861
862             return true;
863         }
864
865         if (*secondsPtr > 0 )
866             intervalLeft = intervalLeft % unitFactor;
867     }
868
869     if (msecondsPtr) {
870         unitFactor = 1;
871         CHECK_INT_LIMIT(intervalLeft, unitFactor)
872
873         *msecondsPtr = intervalLeft;
874         if (fractionalSmallestUnit) {
875             *fractionalSmallestUnit = qreal(intervalLeft);
876         }
877     }
878
879     return true;
880 }
881
882 /*!
883   Sets a part of the time span in the given format.
884
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.
888
889   \b Example:
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
892   \code
893   span.setPart(Qt::Hours, 2, Qt::Weeks | Qt::Days | Qt::Hours | Qt::Minutes | Qt::Seconds);
894   \endcode
895
896   Note that just like with any other function, you can not use the Months and Years
897   units without using a reference date.
898 */
899 void QTimeSpan::setPart(Qt::TimeSpanUnit unit, int interval, Qt::TimeSpanFormat format)
900 {
901     if (!format.testFlag(unit)) {
902         qWarning() << "Can not set a unit that is not part of the format. Ignoring.";
903         return;
904     }
905
906     QTimeSpanPrivate::TimePartHash partsHash(format);
907     bool result = partsHash.fill(*this);
908
909     if (!result) {
910         qWarning() << "Retreiving parts failed, cannot set parts. Ignoring.";
911         return;
912     }
913
914     d->addUnit(this, unit, interval - *(partsHash.value(unit) ) );
915 }
916
917 /*!
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.
921
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.
925 */
926 Qt::TimeSpanUnit QTimeSpan::magnitude()
927 {
928     qint64 mag = d->interval;
929     mag = qAbs(mag);
930
931     if (mag < 1000)
932         return Qt::Milliseconds;
933     if (mag < (Q_INT64_C(60) * Q_INT64_C(1000)))
934         return Qt::Seconds;
935     if (mag < (Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000)))
936         return Qt::Minutes;
937     if (mag < (Q_INT64_C(24) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000)))
938         return Qt::Hours;
939     if (mag < (Q_INT64_C(7) * Q_INT64_C(24) * Q_INT64_C(60) * Q_INT64_C(60) * Q_INT64_C(1000)))
940         return Qt::Days;
941
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)))
946             return Qt::Years;
947         //we need a more complicated test
948         int years = 0;
949         int months = 0;
950         parts(0, 0, 0, 0, 0, 0, &months, &years);
951         if (years > 0)
952             return Qt::Years;
953         if (months > 0)
954             return Qt::Months;
955     }
956
957     return Qt::Weeks;
958 }
959
960 /*!
961   Returns \c true if there is a valid reference date set, false otherwise.
962 */
963 bool QTimeSpan::hasValidReference() const
964 {
965     return d->reference.isValid();
966 }
967
968 /*!
969   Returns the reference date. Note that the reference date may be invalid.
970 */
971 QDateTime QTimeSpan::referenceDate() const
972 {
973     return d->reference;
974 }
975
976 /*!
977   Sets the reference date.
978
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().
984
985   \sa moveReferenceDate() setReferencedDate() moveReferencedDate()
986 */
987 void QTimeSpan::setReferenceDate(const QDateTime &referenceDate)
988 {
989     if (d->reference.isValid() && referenceDate.isValid()) {
990         *this = referencedDate() - referenceDate;
991     } else {
992         d->reference = referenceDate;
993     }
994 }
995
996 /*!
997   Moves the time span to align the time spans reference date with the
998   new reference date \a referenceDate.
999
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.
1003
1004   \sa setReferenceDate() setReferencedDate() moveReferencedDate()
1005 */
1006 void QTimeSpan::moveReferenceDate(const QDateTime &referenceDate)
1007 {
1008     d->reference = referenceDate;
1009 }
1010
1011 /*!
1012   Sets the referenced date.
1013
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().
1019
1020   \sa setReferenceDate() moveReferenceDate() moveReferencedDate()
1021
1022 */
1023 void QTimeSpan::setReferencedDate(const QDateTime &referencedDate)
1024 {
1025     if (d->reference.isValid()) {
1026         *this = referencedDate - d->reference;
1027     } else {
1028         d->reference = referencedDate.addMSecs(-(d->interval));
1029     }
1030 }
1031
1032 /*!
1033   Moves the time span to align the time spans referenced date with the
1034   new referenced date.
1035
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.
1039
1040   \sa setReferenceDate() setReferencedDate() moveReferencedDate()
1041 */
1042 void QTimeSpan::moveReferencedDate(const QDateTime &referencedDate)
1043 {
1044     d->reference = referencedDate.addMSecs(-(d->interval));
1045 }
1046
1047 /*!
1048   Returns the referenced date and time.
1049
1050   The referenced QDateTime is the "other end" of the QTimeSpan from
1051   the reference date.
1052
1053   An invalid QDateTime will be returned if no valid reference date
1054   has been set.
1055 */
1056 QDateTime QTimeSpan::referencedDate() const
1057 {
1058     if (!(d->reference.isValid()))
1059         return QDateTime();
1060
1061     QDateTime dt(d->reference);
1062     dt = dt.addMSecs(d->interval);
1063     return dt;
1064 }
1065
1066 // Comparison operators
1067 /*!
1068   Returns true if this QTimeSpan and \a other have both the same
1069   reference date and the same length.
1070
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
1074   versions.
1075
1076   \sa matchesLength()
1077 */
1078 bool QTimeSpan::operator==(const QTimeSpan &other) const
1079 {
1080     return ((d->interval == other.d->interval)
1081             && (d->reference == other.d->reference));
1082 }
1083
1084 /*!
1085   Returns true if the interval of this QTimeSpan is shorter than
1086   the interval of the \a other QTimeSpan.
1087 */
1088 bool QTimeSpan::operator<(const QTimeSpan &other) const
1089 {
1090     return d->interval < other.d->interval;
1091 }
1092
1093 /*!
1094   Returns true if the interval of this QTimeSpan is shorter or equal
1095   than the interval of the \a other QTimeSpan.
1096 */
1097 bool QTimeSpan::operator<=(const QTimeSpan &other) const
1098 {
1099     return d->interval <= other.d->interval;
1100 }
1101
1102 /*!
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
1105   same length.
1106
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
1109   real values.
1110
1111   \code
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
1116   \endcode
1117 */
1118 bool QTimeSpan::matchesLength(const QTimeSpan &other, bool normalize) const
1119 {
1120     if (!normalize) {
1121         return d->interval == other.d->interval;
1122     } else {
1123         return qAbs(d->interval) == qAbs(other.d->interval);
1124     }
1125 }
1126
1127 // Arithmetic operators
1128 /*!
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
1131   ignored.
1132 */
1133 QTimeSpan & QTimeSpan::operator+=(const QTimeSpan &other)
1134 {
1135     d->interval += other.d->interval;
1136     return *this;
1137 }
1138
1139 /*!
1140   Adds the number of milliseconds \a msecs to the interval of
1141   this QTimeSpan. The reference date of the QTimeSpan is
1142   not affected.
1143 */
1144 QTimeSpan & QTimeSpan::operator+=(qint64 msecs)
1145 {
1146     d->interval += msecs;
1147     return *this;
1148 }
1149
1150 /*!
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.
1154 */
1155 QTimeSpan & QTimeSpan::operator-=(const QTimeSpan &other)
1156 {
1157     d->interval -= (other.d->interval);
1158     return *this;
1159 }
1160
1161 /*!
1162   Substracts the number of milliseconds \a msecs from the interval of
1163   this QTimeSpan. The reference date of the QTimeSpan is
1164   not affected.
1165 */
1166 QTimeSpan & QTimeSpan::operator-=(qint64 msecs)
1167 {
1168     d->interval -= msecs;
1169     return *this;
1170 }
1171
1172 /*!
1173   Multiplies the interval described by this QTimeSpan by the
1174   given \a factor. The reference date of the QTimeSpan is not
1175   affected.
1176 */
1177 QTimeSpan & QTimeSpan::operator*=(qreal factor)
1178 {
1179     d->interval *= factor;
1180     return *this;
1181 }
1182
1183 /*!
1184   Multiplies the interval described by this QTimeSpan by the
1185   given \a factor. The reference date of the QTimeSpan is not
1186   affected.
1187 */
1188 QTimeSpan & QTimeSpan::operator*=(int factor)
1189 {
1190     d->interval *= factor;
1191     return *this;
1192 }
1193
1194 /*!
1195   Divides the interval described by this QTimeSpan by the
1196   given \a factor. The reference date of the QTimeSpan is not
1197   affected.
1198 */
1199 QTimeSpan & QTimeSpan::operator/=(qreal factor)
1200 {
1201     d->interval /= factor;
1202     return *this;
1203 }
1204
1205 /*!
1206   Divides the interval described by this QTimeSpan by the
1207   given \a factor. The reference date of the QTimeSpan is not
1208   affected.
1209 */
1210 QTimeSpan & QTimeSpan::operator/=(int factor)
1211 {
1212     d->interval /= factor;
1213     return *this;
1214 }
1215
1216 /*!
1217   Modifies this QTimeSpan to be the union of this QTimeSpan with \a other.
1218
1219   The union of two QTimeSpans is defined as the minimum QTimeSpan that
1220   encloses both QTimeSpans. The QTimeSpans need not be overlapping.
1221
1222   \warning Only works if both QTimeSpans have a valid reference date.
1223   \sa operator&=()
1224   \sa operator|()
1225   \sa united()
1226 */
1227 QTimeSpan& QTimeSpan::operator|=(const QTimeSpan& other) // Union
1228 {
1229     Q_ASSERT_X((hasValidReference() && other.hasValidReference()),
1230                    "assignment-or operator", "Both participating time spans need a valid reference date");
1231
1232     //do we need to check for self-assignment?
1233
1234     QDateTime start = qMin(startDate(), other.startDate());
1235     QDateTime end = qMax(endDate(), other.endDate());
1236
1237     *this = end - start;
1238     return *this;
1239 }
1240
1241 /*!
1242   Modifies this QTimeSpan to be the intersection of this QTimeSpan and \a other.
1243
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.
1247
1248   \warning Only works if both QTimeSpans have a valid reference date.
1249   \sa operator&=()
1250   \sa operator&()
1251   \sa overlapped()
1252 */
1253 QTimeSpan& QTimeSpan::operator&=(const QTimeSpan &other) // Intersection
1254 {
1255     Q_ASSERT_X((hasValidReference() && other.hasValidReference()),
1256                    "assignment-or operator", "Both participating time spans need a valid reference date");
1257
1258     //do we need to check for self-assignment?
1259
1260     const QTimeSpan* first = this;
1261     const QTimeSpan* last = &other;
1262     if (other.startDate() < startDate()) {
1263         first = &other;
1264         last = this;
1265     }
1266
1267     //check if there is overlap at all. If not, reset the interval to 0
1268     if  (!(first->endDate() > last->startDate()) ) {
1269         d->interval = 0;
1270         return *this;
1271     }
1272
1273     *this = qMin(first->endDate(), last->endDate()) - last->startDate();
1274     return *this;
1275 }
1276
1277 /*!
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.
1281 */
1282 bool QTimeSpan::overlaps(const QTimeSpan &other) const
1283 {
1284     if (!hasValidReference() || !other.hasValidReference())
1285         return false;
1286
1287     const QTimeSpan* first = this;
1288     const QTimeSpan* last = &other;
1289     if (other.startDate() < startDate()) {
1290         first = &other;
1291         last = this;
1292     }
1293
1294     return (first->endDate() > last->startDate());
1295 }
1296
1297 /*!
1298   Returns a new QTimeSpan that represents the intersection of this QTimeSpan with \a other.
1299
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.
1303
1304   \warning Only works if both QTimeSpans have a valid reference date.
1305   \sa operator&=()
1306   \sa operator&()
1307
1308 */
1309 QTimeSpan QTimeSpan::overlapped(const QTimeSpan &other) const
1310 {
1311     Q_ASSERT_X((hasValidReference() && other.hasValidReference()),
1312                    "assignment-or operator", "Both participating time spans need a valid reference date");
1313
1314     const QTimeSpan* first = this;
1315     const QTimeSpan* last = &other;
1316     if (other.startDate() < startDate()) {
1317         first = &other;
1318         last = this;
1319     }
1320
1321     //check if there is overlap at all. If not, reset the interval to 0
1322     if (!(first->endDate() >= last->startDate()) ) {
1323         return QTimeSpan();
1324     }
1325
1326     return qMin(first->endDate(), last->endDate()) - last->startDate();
1327 }
1328
1329 /*!
1330   Returns a new QTimeSpan that represents the union of this QTimeSpan with \a other.
1331
1332   The union of two QTimeSpans is defined as the minimum QTimeSpan that
1333   encloses both QTimeSpans. The QTimeSpans need not be overlapping.
1334
1335   \warning Only works if both QTimeSpans have a valid reference date.
1336   \sa operator|=()
1337   \sa operator|()
1338 */
1339 QTimeSpan QTimeSpan::united(const QTimeSpan &other) const
1340 {
1341     Q_ASSERT_X((hasValidReference() && other.hasValidReference()),
1342                    "assignment-or operator", "Both participating time spans need a valid reference date");
1343
1344     QDateTime start = qMin(startDate(), other.startDate());
1345     QDateTime end = qMax(endDate(), other.endDate());
1346
1347     return ( end - start );
1348 }
1349
1350 /*!
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.
1353
1354   If the time span does not have a valid reference date, this function
1355   returns false.
1356 */
1357 bool QTimeSpan::contains(const QDateTime &dateTime) const
1358 {
1359     if (!hasValidReference())
1360         return false;
1361
1362     return ((startDate() <= dateTime)
1363             && (endDate()) >= dateTime);
1364 }
1365
1366 /*!
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
1370   to be 00:00:00.000.
1371
1372   If the time span does not have a valid reference date, this function
1373   returns false.
1374 */
1375 bool QTimeSpan::contains(const QDate &date) const
1376 {
1377     QDateTime dt(date);
1378     return contains(dt);
1379 }
1380
1381 /*!
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.
1386
1387   If the time span does not have a valid reference date, this function
1388   returns false.
1389 */
1390 bool QTimeSpan::contains(const QTime &time) const
1391 {
1392     QDateTime dt(QDate::currentDate());
1393     dt.setTime(time);
1394     return contains(dt);
1395 }
1396
1397 /*!
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.
1402
1403   If either time span does not have a valid reference date, this function
1404   returns false.
1405 */
1406 bool QTimeSpan::contains(const QTimeSpan &other) const
1407 {
1408     if (!(hasValidReference() && other.hasValidReference()))
1409         return false;
1410
1411     return ((startDate() <= other.startDate())
1412                 && (endDate()) >= other.endDate());
1413 }
1414
1415 /*!
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.
1419
1420   \sa normalize()
1421   \sa abs()
1422   */
1423 QTimeSpan QTimeSpan::normalized() const
1424 {
1425     QTimeSpan ts(*this);
1426     ts.normalize();
1427     return ts;
1428 }
1429
1430 /*!
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.
1435
1436   \sa normalized()
1437   \sa abs()
1438   */
1439 void QTimeSpan::normalize()
1440 {
1441     if (d->interval < 0) {
1442         if (hasValidReference())
1443             d->reference = referencedDate();
1444
1445         d->interval = qAbs(d->interval);
1446     }
1447 }
1448
1449 /*!
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.
1455
1456   If there is no valid reference date, the interval will just be made positive.
1457
1458   \sa normalize()
1459   \sa normalized()
1460   */
1461 QTimeSpan QTimeSpan::abs() const
1462 {
1463     QTimeSpan result(*this);
1464     result.d->interval = qAbs(result.d->interval);
1465
1466     return result;
1467 }
1468
1469 /*!
1470   Returns true if the interval is negative.
1471   \sa isNormal()
1472   */
1473 bool QTimeSpan::isNegative() const
1474 {
1475     return d->interval < 0;
1476 }
1477
1478 /*!
1479   \fn QTimeSpan::isNormal() const
1480
1481   Returns true if the interval is normal, that is: not negative.
1482   \sa isNegative()
1483   */
1484
1485 /*!
1486   Returns the first date of the spanned time period. If there is no valid
1487   reference date, an invalid QDateTime will be returned.
1488   */
1489 QDateTime QTimeSpan::startDate() const
1490 {
1491     if (isNegative())
1492         return referencedDate();
1493
1494     return referenceDate();
1495 }
1496
1497 /*!
1498   Returns the last date of the spanned time period. If there is no valid
1499   reference date, an invalid QDateTime will be returned.
1500   */
1501 QDateTime QTimeSpan::endDate() const
1502 {
1503     if (isNegative())
1504         return referenceDate();
1505
1506     return referencedDate();
1507 }
1508
1509 /*!
1510   Returns the duration of the QTimeSpan expressed in milliseconds. This
1511   value may be negative.
1512 */
1513 qint64 QTimeSpan::toMSecs() const
1514 {
1515     return d->interval;
1516 }
1517
1518 /*!
1519   Returns the duration of the QTimeSpan expressed in the given TimeSpanUnit. This
1520   value may be negative.
1521 */
1522 qreal QTimeSpan::toTimeUnit(Qt::TimeSpanUnit unit) const
1523 {
1524     qreal interval = qreal(d->interval);
1525     switch (unit){ //fall through is intentional
1526     case Qt::Weeks:
1527         interval /= 7.0;
1528     case Qt::Days:
1529         interval /= 24.0;
1530     case Qt::Hours:
1531         interval /= 60.0;
1532     case Qt::Minutes:
1533         interval /= 60.0;
1534     case Qt::Seconds:
1535         interval /= 1000.0;
1536     case Qt::Milliseconds:
1537         break;
1538     default:
1539         Q_ASSERT_X(hasValidReference(), "toTimeUnit", "Can not convert to time units that depend on the reference date (month and year).");
1540         qreal result(0.0);
1541         int intResult(0);
1542         bool succes(false);
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);
1547         }
1548
1549         if (!succes)
1550             return 0.0;
1551
1552         return result;
1553     }
1554
1555     return interval;
1556 }
1557
1558 /*!
1559   Sets the length of this QTimeSpan from the given number of milliseconds \msecs.
1560   The reference date is not affected.
1561  */
1562 void QTimeSpan::setFromMSecs(qint64 msecs)
1563 {
1564     d->interval = msecs;
1565 }
1566
1567 /*!
1568   Sets the length of this QTimeSpan from the \a interval number of TimeSpanUnits \a unit.
1569   The reference date is not affected.
1570  */
1571 void QTimeSpan::setFromTimeUnit(Qt::TimeSpanUnit unit, qreal interval)
1572 {
1573     switch (unit){
1574     case Qt::Weeks: //fall through of cases is intentional!
1575         interval *= 7.0;
1576     case Qt::Days:
1577         interval *= 24.0;
1578     case Qt::Hours:
1579         interval *= 60.0;
1580     case Qt::Minutes:
1581         interval *= 60.0;
1582     case Qt::Seconds:
1583         interval *= 1000.0;
1584     case Qt::Milliseconds:
1585         break;
1586     case Qt::Months:
1587         setFromMonths(interval);
1588         return;
1589     case Qt::Years:
1590         setFromYears(interval);
1591         return;
1592     default:
1593         Q_ASSERT_X(false, "setFromTimeUnit", "Can not set a QTimeSpan duration from unknown TimeSpanUnit.");
1594     }
1595
1596     d->interval = qint64(interval);
1597 }
1598
1599 /*!
1600   Sets the interval of the time span as a number of \a months.
1601
1602   \warning This function can only be used if a valid reference date has been set.
1603
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
1609   used instead.
1610   That number is used as the number of days and is added to the interval.
1611
1612   \code
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 //
1620   \endcode
1621   */
1622 void QTimeSpan::setFromMonths(qreal months)
1623 {
1624     Q_ASSERT_X(hasValidReference(), "setFromMonths", "Can not set interval from time unit month if there is no reference date.");
1625
1626     int fullMonths = int(months);
1627     qreal fractionalMonth = months - fullMonths;
1628
1629     QDateTime endDate = d->reference;
1630     endDate = endDate.addMonths(fullMonths);
1631
1632     int days = d->daysInMonth(endDate, fractionalMonth < 0);
1633
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);
1637 }
1638
1639 /*!
1640   Sets the interval of the time span as a number of \a years.
1641
1642   \warning This function can only be used if a valid reference date has been set.
1643
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
1648   interval.
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.
1651   */
1652 void QTimeSpan::setFromYears(qreal years)
1653 {
1654     Q_ASSERT_X(hasValidReference(), "setFromYears", "Can not set interval from time unit year if there is no reference date.");
1655
1656     int fullYears = int(years);
1657     qreal fractionalYear = years - fullYears;
1658
1659     QDateTime endDate = d->reference;
1660     endDate = endDate.addYears(fullYears);
1661
1662     qreal days = 365.0;
1663     QDateTime measureDate(endDate);
1664     if (fractionalYear < 0)
1665         measureDate = measureDate.addMSecs(-1);
1666
1667     if (QDate::isLeapYear(measureDate.date().year()))
1668         days += 1.0; //februari has an extra day this year...
1669
1670
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);
1674 }
1675
1676 #ifndef QT_NO_DATASTREAM
1677 /*!
1678   Streaming operator.
1679
1680   This operator allows you to stream a QTimeSpan into a QDataStream.
1681   \sa operator>>(QDataStream &stream, QTimeSpan &span)
1682   */
1683 QDataStream & operator<<(QDataStream &stream, const QTimeSpan & span)
1684 {
1685     stream << span.d->reference << span.d->interval;
1686     return stream;
1687 }
1688
1689 /*!
1690   Streaming operator.
1691
1692   This operator allows you to stream a QTimeSpan out of a QDataStream.
1693   \sa operator>>(QDataStream &stream, QTimeSpan &span)
1694   */
1695 QDataStream & operator>>(QDataStream &stream, QTimeSpan &span)
1696 {
1697     stream >> span.d->reference >> span.d->interval;
1698     return stream;
1699 }
1700 #endif
1701
1702 /*!
1703   Adds two QTimeSpan instances.
1704
1705   The values of the intervals of the QTimeSpans are added up with normal
1706   arithmetic. Negative values will work as expected.
1707
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.
1711
1712   The above can have suprising consequences:
1713   \code
1714   // s1 and s2 are two QTimeSpan objects
1715   QTimeSpan s12 = s1 + s2;
1716   QTimeSpan s21 = s2 + s1;
1717
1718   if (s12 == s21) {
1719     //may or may not happen, depending on the reference dates of s1 and s2.
1720   }
1721   \endcode
1722   \sa operator-()
1723 */
1724 QTimeSpan operator+(const QTimeSpan &left, const QTimeSpan &right)
1725 {
1726     QTimeSpan result(left);
1727     result += right;
1728
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());
1732
1733     return result;
1734 }
1735
1736 /*!
1737   Substracts one QTimeSpan from another QTimeSpan.
1738
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.
1741
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.
1745
1746   \sa operator+()
1747 */
1748 QTimeSpan operator-(const QTimeSpan &left, const QTimeSpan &right)
1749 {
1750     QTimeSpan result(left);
1751     result -= right;
1752
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());
1756
1757     return result;
1758 }
1759
1760 /*!
1761   Multiply a QTimeSpan by a scalar factor.
1762
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
1765   \a right argument.
1766 */
1767 QTimeSpan operator*(const QTimeSpan &left, qreal right)
1768 {
1769     QTimeSpan result(left);
1770     result*=right;
1771     return result;
1772 }
1773
1774 /*!
1775   Multiply a QTimeSpan by a scalar factor.
1776   \overload
1777 */
1778 QTimeSpan operator*(const QTimeSpan &left, int right)
1779 {
1780     QTimeSpan result(left);
1781     result*=right;
1782     return result;
1783 }
1784
1785 /*!
1786   Divide a QTimeSpan by a scalar factor.
1787
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
1790   \a right argument.
1791 */
1792 QTimeSpan operator/(const QTimeSpan &left, qreal right)
1793 {
1794     QTimeSpan result(left);
1795     result/=right;
1796     return result;
1797 }
1798
1799 /*!
1800   Divide a QTimeSpan by a scalar factor.
1801   \overload
1802 */
1803 QTimeSpan operator/(const QTimeSpan &left, int right)
1804 {
1805     QTimeSpan result(left);
1806     result/=right;
1807     return result;
1808 }
1809
1810 /*!
1811   Devides two QTimeSpans. The devision works on the interval lengths of
1812   the two QTimeSpan objects as you would expect from normal artithmatic.
1813 */
1814 qreal operator/(const QTimeSpan &left, const QTimeSpan &right)
1815 {
1816     return (qreal(left.toMSecs()) / qreal(right.toMSecs()));
1817 }
1818
1819 /*!
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.
1825
1826   \sa normalize()
1827 */
1828 QTimeSpan operator-(const QTimeSpan &right) // Unary negation
1829 {
1830     QTimeSpan result(right);
1831     result.setFromMSecs(-result.toMSecs());
1832     return result;
1833 }
1834
1835 /*!
1836   Returns the union of the two QTimeSpans.
1837
1838   \sa united()
1839 */
1840 QTimeSpan operator|(const QTimeSpan &left, const QTimeSpan &right)  // Union
1841 {
1842     QTimeSpan result(left);
1843     result|=right;
1844     return result;
1845 }
1846
1847 /*!
1848   Returns the intersection of the two QTimeSpans.
1849
1850   \sa overlapped()
1851 */
1852 QTimeSpan operator&(const QTimeSpan &left, const QTimeSpan &right)  // Intersection
1853 {
1854     QTimeSpan result(left);
1855     result&=right;
1856
1857  return result;
1858 }
1859
1860 // Operators that use QTimeSpan and other date/time classes
1861 /*!
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.
1866
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.
1869
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.
1873 */
1874 QTimeSpan operator-(const QDateTime &left, const QDateTime &right)
1875 {
1876     QTimeSpan result(right);
1877     if (left.isValid() && right.isValid())
1878         result = QTimeSpan(right, right.msecsTo(left));
1879
1880     return result;
1881 }
1882
1883 /*!
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.
1888
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.
1891
1892   \overload
1893 */
1894 QTimeSpan operator-(const QDate &left, const QDate &right)
1895 {
1896     QTimeSpan result = QDateTime(left) - QDateTime(right);
1897     return result;
1898 }
1899
1900 /*!
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.
1905
1906   Note that that both times will be assumed to be on the current date.
1907
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.
1910 */
1911 QTimeSpan operator-(const QTime &left, const QTime &right)
1912 {
1913     return QDateTime(QDate::currentDate(), left) - QDateTime(QDate::currentDate(), right);
1914 }
1915
1916 /*!
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
1919   ignored.
1920
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.
1923   \overload
1924 */
1925 QDate operator+(const QDate &left, const QTimeSpan &right)
1926 {
1927     QDateTime dt(left);
1928     return (dt + right).date();
1929 }
1930
1931 /*!
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,
1934   is ignored.
1935 */
1936 QDateTime operator+(const QDateTime &left, const QTimeSpan &right)
1937 {
1938     QDateTime result(left);
1939     result = result.addMSecs(right.toMSecs());
1940     return result;
1941 }
1942
1943 /*!
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,
1946   is ignored.
1947
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.
1951
1952   \overload
1953 */
1954 QTime operator+(const QTime &left, const QTimeSpan &right)
1955 {
1956     QDateTime dt(QDate::currentDate(), left);
1957     dt = dt.addMSecs(right.toMSecs());
1958     return dt.time();
1959 }
1960
1961 /*!
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
1964   ignored.
1965
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.
1968
1969   \overload
1970 */
1971 QDate operator-(const QDate &left, const QTimeSpan &right)
1972 {
1973     QDateTime dt(left);
1974     return (dt - right).date();
1975 }
1976
1977 /*!
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.
1981 */
1982 QDateTime operator-(const QDateTime &left, const QTimeSpan &right)
1983 {
1984     QDateTime result(left);
1985     result = result.addMSecs( -(right.toMSecs()) );
1986     return result;
1987 }
1988
1989 /*!
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.
1993
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.
1997 */
1998 QTime operator-(const QTime &left, const QTimeSpan &right)
1999 {
2000     QDateTime dt(QDate::currentDate(), left);
2001     dt = dt.addMSecs( -(right.toMSecs()) );
2002     return dt.time();
2003 }
2004
2005 #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
2006 /*!
2007   Operator to stream QTimeSpan objects to a debug stream.
2008 */
2009 QDebug operator<<(QDebug debug, const QTimeSpan &ts)
2010 {
2011     debug << "QTimeSpan(Reference Date =" << ts.referenceDate()
2012           << "msecs =" << ts.toMSecs() << ")";
2013     return debug;
2014 }
2015 #endif
2016
2017 //String conversions
2018 #ifndef QT_NO_DATESTRING
2019 /*!
2020   Returns an approximate representation of the time span length
2021
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.
2028
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.
2036
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.
2042
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.
2045
2046   \sa magnitude() toString()
2047 */
2048 QString QTimeSpan::toApproximateString(int suppresSecondUnitLimit, Qt::TimeSpanFormat format)
2049 {
2050     if (format==Qt::NoUnit)
2051         return QString();
2052
2053     //retreive the time unit to use as the primairy unit
2054     int primairy = -1;
2055     int secondairy = -1;
2056
2057     Qt::TimeSpanUnit primairyUnit = magnitude();
2058     while (!format.testFlag(primairyUnit ) && primairyUnit > Qt::NoUnit)
2059         primairyUnit = Qt::TimeSpanUnit(primairyUnit / 2);
2060
2061
2062     Qt::TimeSpanUnit secondairyUnit = Qt::NoUnit;
2063     if (primairyUnit > 1) {
2064         secondairyUnit = Qt::TimeSpanUnit(primairyUnit / 2);
2065     } else {
2066         primairy = 0;
2067     }
2068     while (!format.testFlag(secondairyUnit) && secondairyUnit > Qt::NoUnit)
2069         secondairyUnit = Qt::TimeSpanUnit(secondairyUnit / 2);
2070
2071
2072     //build up hash with pointers to ints for the units that are set in format, and 0's for those that are not.
2073     if (primairy < 0) {
2074         QTimeSpanPrivate::TimePartHash partsHash(format);
2075         bool result = partsHash.fill(*this);
2076
2077         if (!result) {
2078             qDebug() << "false result from parts function";
2079             return QString();
2080         }
2081
2082         primairy = *(partsHash.value(primairyUnit));
2083         if (secondairyUnit > 0) {
2084             secondairy = *(partsHash.value(secondairyUnit));
2085         } else {
2086             secondairy = 0;
2087         }
2088     }
2089
2090     if ((primairy > 0
2091          && secondairy > 0
2092          && primairy < suppresSecondUnitLimit)
2093         || (suppresSecondUnitLimit < 0
2094          && secondairyUnit > Qt::NoUnit) )
2095     {
2096         //we will display with two units
2097         return d->unitString(primairyUnit, primairy) + QLatin1String(", ") + d->unitString(secondairyUnit, secondairy);
2098     }
2099
2100     //we will display with only the primairy unit
2101     return d->unitString(primairyUnit, primairy);
2102 }
2103
2104 /*!
2105   Returns a string representation of the duration of this time span in the requested \a format
2106
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.
2110
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.
2113
2114   \table
2115   \header
2116       \o character
2117       \o meaning
2118   \row
2119       \o y
2120       \o The number of years
2121   \row
2122       \o M
2123       \o The number of months
2124   \row
2125       \o w
2126       \o The number of weeks
2127   \row
2128       \o d
2129       \o The number of days
2130   \row
2131       \o h
2132       \o The number of hours
2133   \row
2134       \o m
2135       \o The number of minutes
2136   \row
2137       \o s
2138       \o The number of seconds
2139   \row
2140       \o z
2141       \o The number of milliseconds
2142   \endtable
2143
2144   Use a letter repeatingly to force leading zeros.
2145
2146   Note that you can not use years or months if the QTimeSpan does not have a valid reference
2147   date.
2148
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
2154   quotes.
2155
2156   \sa toApproximateString()
2157 */
2158 QString QTimeSpan::toString(const QString &format) const
2159 {
2160     Qt::TimeSpanFormat tsFormat = Qt::NoUnit;
2161     QList<QTimeSpanPrivate::TimeFormatToken> tokenList = d->parseFormatString(format, tsFormat);
2162
2163     QTimeSpanPrivate::TimePartHash partsHash(tsFormat);
2164     bool result = partsHash.fill(*this);
2165
2166     if (!result)
2167         return QString();
2168
2169     QString formattedString;
2170     foreach(QTimeSpanPrivate::TimeFormatToken token, tokenList) {
2171         if (token.type == 0) {
2172             formattedString.append(token.string);
2173         } else {
2174             Qt::TimeSpanUnit unit(token.type);
2175             formattedString.append (QString(QString::fromLatin1("%1"))
2176                                     .arg(*partsHash.value(unit),
2177                                          token.length,
2178                                          10,
2179                                          QChar('0', 0) ) );
2180         }
2181     }
2182
2183     return formattedString;
2184 }
2185
2186 /*!
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.
2189
2190   The optional \a reference argument will be used as the reference date for the string.
2191
2192   \note You can only use months or years if you also pass a valid reference.
2193   */
2194 QTimeSpan QTimeSpan::fromString(const QString &string, const QString &format, const QDateTime &reference)
2195 {
2196     /*
2197
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
2204      modes for this?
2205
2206      The code here implements the first option. The overloaded version below implements a
2207      more flexible regexp based approach.
2208      */
2209
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);
2214
2215     //prepare the temporaries
2216     QTimeSpanPrivate::TimePartHash partsHash(tsFormat);
2217     QString input(string);
2218
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);
2223         } else {
2224             QString part = input.left(token.length);
2225             input = input.remove(0, token.length);
2226
2227             bool success(false);
2228             part = part.trimmed();
2229             int value = part.toInt(&success, 10);
2230             if (!success)
2231                 return QTimeSpan();
2232
2233             *(partsHash.value(token.type)) = value;
2234         }
2235     }
2236
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);
2243     }
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);
2248     }
2249
2250     //add the rest of the units
2251     QHashIterator<Qt::TimeSpanUnit, int*> it(partsHash);
2252     while (it.hasNext()) {
2253         it.next();
2254         if (it.value()) {
2255             span.d->addUnit(&span, it.key(), *(it.value()));
2256             qDebug() << "Added unit" << it.key() << "with value" << *(it.value()) << "new value" << span.d->interval;
2257         }
2258     }
2259
2260     return span;
2261 }
2262
2263 /*!
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.
2269
2270   The \a reference argument will be used as the reference date for the string.
2271
2272   \note You can only use months or years if you also pass a valid \a reference.
2273   */
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)
2278 {
2279     if (pattern.indexIn(string) < 0)
2280         return QTimeSpan();
2281
2282     QTimeSpanPrivate::TimePartHash partsHash(Qt::NoUnit);
2283
2284     QList<Qt::TimeSpanUnit> unitList;
2285     unitList << unit1 << unit2 << unit3 << unit4 << unit5 << unit6 << unit7 << unit8;
2286
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);
2291             bool ok(false);
2292             int value = capture.toInt(&ok, 10);
2293             if (!ok)
2294                 return QTimeSpan();
2295
2296             *(partsHash.value(unitList.at(i))) = value;
2297         }
2298     }
2299
2300     //create the time span to return
2301     QTimeSpan span(reference);
2302
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);
2309     }
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);
2314     }
2315
2316     //add the rest of the units
2317     QHashIterator<Qt::TimeSpanUnit, int*> it(partsHash);
2318     while (it.hasNext()) {
2319         it.next();
2320         if (it.value())
2321             span.d->addUnit(&span, it.key(), *(it.value()));
2322     }
2323
2324     return span;
2325 }
2326 #endif
2327
2328 QT_END_NAMESPACE