1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtCore module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qplatformdefs.h"
43 #include "private/qdatetime_p.h"
45 #include "qdatastream.h"
48 #include "qdatetime.h"
57 # include <qt_windows.h>
59 # include "qfunctions_wince.h"
63 //#define QDATETIMEPARSER_DEBUG
64 #if defined (QDATETIMEPARSER_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
65 # define QDTPDEBUG qDebug() << QString("%1:%2").arg(__FILE__).arg(__LINE__)
66 # define QDTPDEBUGN qDebug
68 # define QDTPDEBUG if (false) qDebug()
69 # define QDTPDEBUGN if (false) qDebug
73 #include <private/qcore_mac_p.h>
80 MSECS_PER_DAY = 86400000,
82 MSECS_PER_HOUR = 3600000,
84 MSECS_PER_MIN = 60000,
85 JULIAN_DAY_FOR_EPOCH = 2440588 // result of julianDayFromDate(1970, 1, 1)
88 static inline QDate fixedDate(int y, int m, int d)
90 QDate result(y, m, 1);
91 result.setDate(y, m, qMin(d, result.daysInMonth()));
95 static inline qint64 julianDayFromDate(qint64 year, int month, int day)
98 // Algorithm from Henry F. Fliegel and Thomas C. Van Flandern
103 return (1461 * (year + 4800 + (month - 14) / 12)) / 4
104 + (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12
105 - (3 * ((year + 4900 + (month - 14) / 12) / 100)) / 4
109 static void getDateFromJulianDay(qint64 julianDay, int *year, int *month, int *day)
113 // Gregorian calendar
114 // This algorithm is from Henry F. Fliegel and Thomas C. Van Flandern
115 qint64 ell, n, i, j; //TODO These will need to be bigger to prevent overflow!!!
116 ell = julianDay + 68569;
117 n = (4 * ell) / 146097;
118 ell = ell - (146097 * n + 3) / 4;
119 i = (4000 * (ell + 1)) / 1461001;
120 ell = ell - (1461 * i) / 4 + 31;
121 j = (80 * ell) / 2447;
122 d = ell - (2447 * j) / 80;
124 m = j + 2 - (12 * ell);
125 y = 100 * (n - 49) + i + ell;
139 static const char monthDays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
141 #ifndef QT_NO_TEXTDATE
142 static const char * const qt_shortMonthNames[] = {
143 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
144 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
146 #ifndef QT_NO_DATESTRING
147 static QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* dd = 0);
150 /*****************************************************************************
151 QDate member functions
152 *****************************************************************************/
157 \enum QDate::MonthNameType
159 This enum describes the types of the string representation used
162 \value DateFormat This type of name can be used for date-to-string formatting.
163 \value StandaloneFormat This type is used when you need to enumerate months or weekdays.
164 Usually standalone names are represented in singular forms with
165 capitalized first letter.
171 \brief The QDate class provides date functions.
174 A QDate object contains a calendar date, i.e. year, month, and day
175 numbers, in the Gregorian calendar. It can read the current date
176 from the system clock. It provides functions for comparing dates,
177 and for manipulating dates. For example, it is possible to add
178 and subtract days, months, and years to dates.
180 A QDate object is typically created either by giving the year,
181 month, and day numbers explicitly. Note that QDate interprets two
182 digit years as is, i.e., years 0 - 99. A QDate can also be
183 constructed with the static function currentDate(), which creates
184 a QDate object containing the system clock's date. An explicit
185 date can also be set using setDate(). The fromString() function
186 returns a QDate given a string and a date format which is used to
187 interpret the date within the string.
189 The year(), month(), and day() functions provide access to the
190 year, month, and day numbers. Also, dayOfWeek() and dayOfYear()
191 functions are provided. The same information is provided in
192 textual format by the toString(), shortDayName(), longDayName(),
193 shortMonthName(), and longMonthName() functions.
195 QDate provides a full set of operators to compare two QDate
196 objects where smaller means earlier, and larger means later.
198 You can increment (or decrement) a date by a given number of days
199 using addDays(). Similarly you can use addMonths() and addYears().
200 The daysTo() function returns the number of days between two
203 The daysInMonth() and daysInYear() functions return how many days
204 there are in this date's month and year, respectively. The
205 isLeapYear() function indicates whether a date is in a leap year.
211 There is no year 0. Dates in that year are considered invalid. The
212 year -1 is the year "1 before Christ" or "1 before current era."
213 The day before 1 January 1 CE is 31 December 1 BCE.
215 \section2 Range of Valid Dates
217 Dates are stored internally as a Julian Day number, an interger count of
218 every day in a contiguous range, with 24 November 4714 BCE in the Gregorian
219 calendar being Julian Day 0 (1 January 4713 BCE in the Julian calendar).
220 As well as being an efficient and accurate way of storing an absolute date,
221 it is suitable for converting a Date into other calendar systems such as
222 Hebrew, Islamic or Chinese. The Julian Day number can be obtained using
223 QDate::toJulianDay() and can be set using QDate::fromJulianDay().
225 The range of dates able to be stored by QDate as a Julian Day number is
226 limited for convenience from std::numeric_limits<qint64>::min() / 2 to
227 std::numeric_limits<qint64>::max() / 2, which on most platforms means
228 from around 2.5 quadrillion BCE to around 2.5 quadrillion CE, effectively
229 covering the full range of astronomical time. The range of Julian Days
230 able to be accurately converted to and from valid YMD form Dates is
231 restricted to 1 January 4800 BCE to 31 December 1400000 CE due to
232 shortcomings in the available conversion formulas. Conversions outside this
233 range are not guaranteed to be correct. This may change in the future.
235 \sa QTime, QDateTime, QDateEdit, QDateTimeEdit, QCalendarWidget
241 Constructs a null date. Null dates are invalid.
243 \sa isNull(), isValid()
247 Constructs a date with year \a y, month \a m and day \a d.
249 If the specified date is invalid, the date is not set and
250 isValid() returns false.
252 \warning Years 0 to 99 are interpreted as is, i.e., years
258 QDate::QDate(int y, int m, int d)
265 \fn bool QDate::isNull() const
267 Returns true if the date is null; otherwise returns false. A null
270 \note The behavior of this function is equivalent to isValid().
277 \fn bool isValid() const
279 Returns true if this date is valid; otherwise returns false.
286 Returns the year of this date. Negative numbers indicate years
287 before 1 CE, such that year -44 is 44 BCE.
289 Returns 0 if the date is invalid.
294 int QDate::year() const
300 getDateFromJulianDay(jd, &y, 0, 0);
305 Returns the number corresponding to the month of this date, using
306 the following convention:
323 Returns 0 if the date is invalid.
328 int QDate::month() const
334 getDateFromJulianDay(jd, 0, &m, 0);
339 Returns the day of the month (1 to 31) of this date.
341 Returns 0 if the date is invalid.
343 \sa year(), month(), dayOfWeek()
346 int QDate::day() const
352 getDateFromJulianDay(jd, 0, 0, &d);
357 Returns the weekday (1 = Monday to 7 = Sunday) for this date.
359 Returns 0 if the date is invalid.
361 \sa day(), dayOfYear(), Qt::DayOfWeek
364 int QDate::dayOfWeek() const
372 return ((jd + 1) % 7) + 7;
376 Returns the day of the year (1 to 365 or 366 on leap years) for
379 Returns 0 if the date is invalid.
381 \sa day(), dayOfWeek()
384 int QDate::dayOfYear() const
389 return jd - julianDayFromDate(year(), 1, 1) + 1;
393 Returns the number of days in the month (28 to 31) for this date.
395 Returns 0 if the date is invalid.
397 \sa day(), daysInYear()
400 int QDate::daysInMonth() const
406 getDateFromJulianDay(jd, &y, &m, 0);
407 if (m == 2 && isLeapYear(y))
409 else if (m < 1 || m > 12)
416 Returns the number of days in the year (365 or 366) for this date.
418 Returns 0 if the date is invalid.
420 \sa day(), daysInMonth()
423 int QDate::daysInYear() const
429 getDateFromJulianDay(jd, &y, 0, 0);
430 return isLeapYear(y) ? 366 : 365;
434 Returns the week number (1 to 53), and stores the year in
435 *\a{yearNumber} unless \a yearNumber is null (the default).
437 Returns 0 if the date is invalid.
439 In accordance with ISO 8601, weeks start on Monday and the first
440 Thursday of a year is always in week 1 of that year. Most years
441 have 52 weeks, but some have 53.
443 *\a{yearNumber} is not always the same as year(). For example, 1
444 January 2000 has week number 52 in the year 1999, and 31 December
445 2002 has week number 1 in the year 2003.
448 Copyright (c) 1989 The Regents of the University of California.
451 Redistribution and use in source and binary forms are permitted
452 provided that the above copyright notice and this paragraph are
453 duplicated in all such forms and that any documentation,
454 advertising materials, and other materials related to such
455 distribution and use acknowledge that the software was developed
456 by the University of California, Berkeley. The name of the
457 University may not be used to endorse or promote products derived
458 from this software without specific prior written permission.
459 THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
460 IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
461 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
466 int QDate::weekNumber(int *yearNumber) const
471 int year = QDate::year();
472 int yday = dayOfYear() - 1;
473 int wday = dayOfWeek();
483 len = isLeapYear(year) ? 366 : 365;
485 ** What yday (-3 ... 3) does
486 ** the ISO year begin on?
488 bot = ((yday + 11 - wday) % 7) - 3;
490 ** What yday does the NEXT
491 ** ISO year begin on?
493 top = bot - (len % 7);
503 w = 1 + ((yday - bot) / 7);
507 yday += isLeapYear(year) ? 366 : 365;
514 #ifndef QT_NO_TEXTDATE
518 Returns the short name of the \a month for the representation specified
521 The months are enumerated using the following convention:
538 The month names will be localized according to the system's locale
541 Returns an empty string if the date is invalid.
543 \sa toString(), longMonthName(), shortDayName(), longDayName()
546 QString QDate::shortMonthName(int month, QDate::MonthNameType type)
548 if (month < 1 || month > 12)
552 case QDate::DateFormat:
553 return QLocale::system().monthName(month, QLocale::ShortFormat);
554 case QDate::StandaloneFormat:
555 return QLocale::system().standaloneMonthName(month, QLocale::ShortFormat);
565 Returns the long name of the \a month for the representation specified
568 The months are enumerated using the following convention:
585 The month names will be localized according to the system's locale
588 Returns an empty string if the date is invalid.
590 \sa toString(), shortMonthName(), shortDayName(), longDayName()
593 QString QDate::longMonthName(int month, MonthNameType type)
595 if (month < 1 || month > 12)
599 case QDate::DateFormat:
600 return QLocale::system().monthName(month, QLocale::LongFormat);
601 case QDate::StandaloneFormat:
602 return QLocale::system().standaloneMonthName(month, QLocale::LongFormat);
612 Returns the short name of the \a weekday for the representation specified
615 The days are enumerated using the following convention:
627 The day names will be localized according to the system's locale
630 Returns an empty string if the date is invalid.
632 \sa toString(), shortMonthName(), longMonthName(), longDayName()
635 QString QDate::shortDayName(int weekday, MonthNameType type)
637 if (weekday < 1 || weekday > 7)
641 case QDate::DateFormat:
642 return QLocale::system().dayName(weekday, QLocale::ShortFormat);
643 case QDate::StandaloneFormat:
644 return QLocale::system().standaloneDayName(weekday, QLocale::ShortFormat);
654 Returns the long name of the \a weekday for the representation specified
657 The days are enumerated using the following convention:
669 The day names will be localized according to the system's locale
672 Returns an empty string if the date is invalid.
674 \sa toString(), shortDayName(), shortMonthName(), longMonthName()
677 QString QDate::longDayName(int weekday, MonthNameType type)
679 if (weekday < 1 || weekday > 7)
683 case QDate::DateFormat:
684 return QLocale::system().dayName(weekday, QLocale::LongFormat);
685 case QDate::StandaloneFormat:
686 return QLocale::system().standaloneDayName(weekday, QLocale::LongFormat);
690 return QLocale::system().dayName(weekday, QLocale::LongFormat);
692 #endif //QT_NO_TEXTDATE
694 #ifndef QT_NO_DATESTRING
697 \fn QString QDate::toString(Qt::DateFormat format) const
701 Returns the date as a string. The \a format parameter determines
702 the format of the string.
704 If the \a format is Qt::TextDate, the string is formatted in
705 the default way. QDate::shortDayName() and QDate::shortMonthName()
706 are used to generate the string, so the day and month names will
707 be localized names. An example of this formatting is
710 If the \a format is Qt::ISODate, the string format corresponds
711 to the ISO 8601 extended specification for representations of
712 dates and times, taking the form YYYY-MM-DD, where YYYY is the
713 year, MM is the month of the year (between 01 and 12), and DD is
714 the day of the month between 01 and 31.
716 If the \a format is Qt::SystemLocaleShortDate or
717 Qt::SystemLocaleLongDate, the string format depends on the locale
718 settings of the system. Identical to calling
719 QLocale::system().toString(date, QLocale::ShortFormat) or
720 QLocale::system().toString(date, QLocale::LongFormat).
722 If the \a format is Qt::DefaultLocaleShortDate or
723 Qt::DefaultLocaleLongDate, the string format depends on the
724 default application locale. This is the locale set with
725 QLocale::setDefault(), or the system locale if no default locale
726 has been set. Identical to calling QLocale().toString(date,
727 QLocale::ShortFormat) or QLocale().toString(date,
728 QLocale::LongFormat).
730 If the date is invalid, an empty string will be returned.
732 \warning The Qt::ISODate format is only valid for years in the
733 range 0 to 9999. This restriction may apply to locale-aware
734 formats as well, depending on the locale settings.
736 \sa shortDayName(), shortMonthName()
738 QString QDate::toString(Qt::DateFormat f) const
743 getDateFromJulianDay(jd, &y, &m, &d);
745 case Qt::SystemLocaleDate:
746 case Qt::SystemLocaleShortDate:
747 case Qt::SystemLocaleLongDate:
748 return QLocale::system().toString(*this, f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
749 : QLocale::ShortFormat);
751 case Qt::DefaultLocaleShortDate:
752 case Qt::DefaultLocaleLongDate:
753 return QLocale().toString(*this, f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
754 : QLocale::ShortFormat);
756 #ifndef QT_NO_TEXTDATE
759 return QString::fromLatin1("%0 %1 %2 %3")
760 .arg(shortDayName(dayOfWeek()))
761 .arg(shortMonthName(m))
768 if (year() < 0 || year() > 9999)
770 QString month(QString::number(m).rightJustified(2, QLatin1Char('0')));
771 QString day(QString::number(d).rightJustified(2, QLatin1Char('0')));
772 return QString::number(y) + QLatin1Char('-') + month + QLatin1Char('-') + day;
778 Returns the date as a string. The \a format parameter determines
779 the format of the result string.
781 These expressions may be used:
784 \header \li Expression \li Output
785 \row \li d \li the day as number without a leading zero (1 to 31)
786 \row \li dd \li the day as number with a leading zero (01 to 31)
788 \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
789 Uses QDate::shortDayName().
791 \li the long localized day name (e.g. 'Monday' to 'Sunday').
792 Uses QDate::longDayName().
793 \row \li M \li the month as number without a leading zero (1 to 12)
794 \row \li MM \li the month as number with a leading zero (01 to 12)
796 \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
797 Uses QDate::shortMonthName().
799 \li the long localized month name (e.g. 'January' to 'December').
800 Uses QDate::longMonthName().
801 \row \li yy \li the year as two digit number (00 to 99)
802 \row \li yyyy \li the year as four digit number. If the year is negative,
803 a minus sign is prepended in addition.
806 All other input characters will be ignored. Any sequence of characters that
807 are enclosed in singlequotes will be treated as text and not be used as an
808 expression. Two consecutive singlequotes ("''") are replaced by a singlequote
811 Example format strings (assuming that the QDate is the 20 July
815 \header \li Format \li Result
816 \row \li dd.MM.yyyy \li 20.07.1969
817 \row \li ddd MMMM d yy \li Sun July 20 69
818 \row \li 'The day is' dddd \li The day is Sunday
821 If the datetime is invalid, an empty string will be returned.
823 \warning The Qt::ISODate format is only valid for years in the
824 range 0 to 9999. This restriction may apply to locale-aware
825 formats as well, depending on the locale settings.
827 \sa QDateTime::toString(), QTime::toString()
830 QString QDate::toString(const QString& format) const
834 return fmtDateTime(format, 0, this);
836 #endif //QT_NO_DATESTRING
839 \fn bool QDate::setYMD(int y, int m, int d)
841 \deprecated in 5.0, use setDate() instead.
843 Sets the date's year \a y, month \a m, and day \a d.
845 If \a y is in the range 0 to 99, it is interpreted as 1900 to
848 Use setDate() instead.
854 Sets the date's \a year, \a month, and \a day. Returns true if
855 the date is valid; otherwise returns false.
857 If the specified date is invalid, the QDate object is set to be
860 Note that any date before 4800 BCE or after about 1.4 million CE
861 may not be accurately stored.
865 bool QDate::setDate(int year, int month, int day)
867 if (isValid(year, month, day))
868 jd = julianDayFromDate(year, month, day);
878 Extracts the date's year, month, and day, and assigns them to
879 *\a year, *\a month, and *\a day. The pointers may be null.
881 Returns 0 if the date is invalid.
883 Note that any date before 4800 BCE or after about 1.4 million CE
884 may not be accurately stored.
886 \sa year(), month(), day(), isValid()
888 void QDate::getDate(int *year, int *month, int *day)
891 getDateFromJulianDay(jd, year, month, day);
903 Returns a QDate object containing a date \a ndays later than the
904 date of this object (or earlier if \a ndays is negative).
906 Returns a null date if the current date is invalid or the new date is
909 \sa addMonths(), addYears(), daysTo()
912 QDate QDate::addDays(qint64 ndays) const
920 // this is basically "d.jd = jd + ndays" with checks for integer overflow
921 // Due to limits on minJd() and maxJd() we know diff will never overflow
927 if ((quint64)qAbs(ndays) <= diff)
934 Returns a QDate object containing a date \a nmonths later than the
935 date of this object (or earlier if \a nmonths is negative).
937 \note If the ending day/month combination does not exist in the
938 resulting month/year, this function will return a date that is the
941 \sa addDays(), addYears()
944 QDate QDate::addMonths(int nmonths) const
952 getDateFromJulianDay(jd, &y, &m, &d);
955 bool increasing = nmonths > 0;
957 while (nmonths != 0) {
958 if (nmonths < 0 && nmonths + 12 <= 0) {
961 } else if (nmonths < 0) {
968 } else if (nmonths - 12 >= 0) {
971 } else if (m == 12) {
984 // was there a sign change?
985 if ((old_y > 0 && y <= 0) ||
986 (old_y < 0 && y >= 0))
987 // yes, adjust the date by +1 or -1 years
988 y += increasing ? +1 : -1;
990 return fixedDate(y, m, d);
994 Returns a QDate object containing a date \a nyears later than the
995 date of this object (or earlier if \a nyears is negative).
997 \note If the ending day/month combination does not exist in the
998 resulting year (i.e., if the date was Feb 29 and the final year is
999 not a leap year), this function will return a date that is the
1000 latest valid date (that is, Feb 28).
1002 \sa addDays(), addMonths()
1005 QDate QDate::addYears(int nyears) const
1011 getDateFromJulianDay(jd, &y, &m, &d);
1016 // was there a sign change?
1017 if ((old_y > 0 && y <= 0) ||
1018 (old_y < 0 && y >= 0))
1019 // yes, adjust the date by +1 or -1 years
1020 y += nyears > 0 ? +1 : -1;
1022 return fixedDate(y, m, d);
1026 Returns the number of days from this date to \a d (which is
1027 negative if \a d is earlier than this date).
1029 Returns 0 if either date is invalid.
1032 \snippet code/src_corelib_tools_qdatetime.cpp 0
1037 qint64 QDate::daysTo(const QDate &d) const
1039 if (isNull() || d.isNull())
1042 // Due to limits on minJd() and maxJd() we know this will never overflow
1048 \fn bool QDate::operator==(const QDate &d) const
1050 Returns true if this date is equal to \a d; otherwise returns
1056 \fn bool QDate::operator!=(const QDate &d) const
1058 Returns true if this date is different from \a d; otherwise
1063 \fn bool QDate::operator<(const QDate &d) const
1065 Returns true if this date is earlier than \a d; otherwise returns
1070 \fn bool QDate::operator<=(const QDate &d) const
1072 Returns true if this date is earlier than or equal to \a d;
1073 otherwise returns false.
1077 \fn bool QDate::operator>(const QDate &d) const
1079 Returns true if this date is later than \a d; otherwise returns
1084 \fn bool QDate::operator>=(const QDate &d) const
1086 Returns true if this date is later than or equal to \a d;
1087 otherwise returns false.
1091 \fn QDate::currentDate()
1092 Returns the current date, as reported by the system clock.
1094 \sa QTime::currentTime(), QDateTime::currentDateTime()
1097 #ifndef QT_NO_DATESTRING
1099 \fn QDate QDate::fromString(const QString &string, Qt::DateFormat format)
1101 Returns the QDate represented by the \a string, using the
1102 \a format given, or an invalid date if the string cannot be
1105 Note for Qt::TextDate: It is recommended that you use the
1106 English short month names (e.g. "Jan"). Although localized month
1107 names can also be used, they depend on the user's locale settings.
1109 QDate QDate::fromString(const QString& s, Qt::DateFormat f)
1117 int year(s.mid(0, 4).toInt());
1118 int month(s.mid(5, 2).toInt());
1119 int day(s.mid(8, 2).toInt());
1120 if (year && month && day)
1121 return QDate(year, month, day);
1124 case Qt::SystemLocaleDate:
1125 case Qt::SystemLocaleShortDate:
1126 case Qt::SystemLocaleLongDate:
1127 return fromString(s, QLocale::system().dateFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
1128 : QLocale::ShortFormat));
1129 case Qt::LocaleDate:
1130 case Qt::DefaultLocaleShortDate:
1131 case Qt::DefaultLocaleLongDate:
1132 return fromString(s, QLocale().dateFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
1133 : QLocale::ShortFormat));
1135 #ifndef QT_NO_TEXTDATE
1136 case Qt::TextDate: {
1137 QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts);
1139 if (parts.count() != 4) {
1143 QString monthName = parts.at(1);
1145 // Assume that English monthnames are the default
1146 for (int i = 0; i < 12; ++i) {
1147 if (monthName == QLatin1String(qt_shortMonthNames[i])) {
1152 // If English names can't be found, search the localized ones
1154 for (int i = 1; i <= 12; ++i) {
1155 if (monthName == QDate::shortMonthName(i)) {
1161 if (month < 1 || month > 12) {
1166 int day = parts.at(2).toInt(&ok);
1171 int year = parts.at(3).toInt(&ok);
1176 return QDate(year, month, day);
1186 \fn QDate::fromString(const QString &string, const QString &format)
1188 Returns the QDate represented by the \a string, using the \a
1189 format given, or an invalid date if the string cannot be parsed.
1191 These expressions may be used for the format:
1194 \header \li Expression \li Output
1195 \row \li d \li The day as a number without a leading zero (1 to 31)
1196 \row \li dd \li The day as a number with a leading zero (01 to 31)
1198 \li The abbreviated localized day name (e.g. 'Mon' to 'Sun').
1199 Uses QDate::shortDayName().
1201 \li The long localized day name (e.g. 'Monday' to 'Sunday').
1202 Uses QDate::longDayName().
1203 \row \li M \li The month as a number without a leading zero (1 to 12)
1204 \row \li MM \li The month as a number with a leading zero (01 to 12)
1206 \li The abbreviated localized month name (e.g. 'Jan' to 'Dec').
1207 Uses QDate::shortMonthName().
1209 \li The long localized month name (e.g. 'January' to 'December').
1210 Uses QDate::longMonthName().
1211 \row \li yy \li The year as two digit number (00 to 99)
1212 \row \li yyyy \li The year as four digit number. If the year is negative,
1213 a minus sign is prepended in addition.
1216 All other input characters will be treated as text. Any sequence
1217 of characters that are enclosed in single quotes will also be
1218 treated as text and will not be used as an expression. For example:
1220 \snippet code/src_corelib_tools_qdatetime.cpp 1
1222 If the format is not satisfied, an invalid QDate is returned. The
1223 expressions that don't expect leading zeroes (d, M) will be
1224 greedy. This means that they will use two digits even if this
1225 will put them outside the accepted range of values and leaves too
1226 few digits for other sections. For example, the following format
1227 string could have meant January 30 but the M will grab two
1228 digits, resulting in an invalid date:
1230 \snippet code/src_corelib_tools_qdatetime.cpp 2
1232 For any field that is not represented in the format the following
1236 \header \li Field \li Default value
1237 \row \li Year \li 1900
1238 \row \li Month \li 1
1242 The following examples demonstrate the default values:
1244 \snippet code/src_corelib_tools_qdatetime.cpp 3
1246 \sa QDateTime::fromString(), QTime::fromString(), QDate::toString(),
1247 QDateTime::toString(), QTime::toString()
1250 QDate QDate::fromString(const QString &string, const QString &format)
1253 #ifndef QT_BOOTSTRAPPED
1254 QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
1255 if (dt.parseFormat(format))
1256 dt.fromString(string, &date, 0);
1263 #endif // QT_NO_DATESTRING
1268 Returns true if the specified date (\a year, \a month, and \a
1269 day) is valid; otherwise returns false.
1272 \snippet code/src_corelib_tools_qdatetime.cpp 4
1274 \sa isNull(), setDate()
1277 bool QDate::isValid(int year, int month, int day)
1279 // there is no year 0 in the Gregorian calendar
1283 return (day > 0 && month > 0 && month <= 12) &&
1284 (day <= monthDays[month] || (day == 29 && month == 2 && isLeapYear(year)));
1288 \fn bool QDate::isLeapYear(int year)
1290 Returns true if the specified \a year is a leap year; otherwise
1294 bool QDate::isLeapYear(int y)
1296 // No year 0 in Gregorian calendar, so -1, -5, -9 etc are leap years
1300 return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
1303 /*! \fn static QDate QDate::fromJulianDay(qint64 jd)
1305 Converts the Julian day \a jd to a QDate.
1310 /*! \fn int QDate::toJulianDay() const
1312 Converts the date to a Julian day.
1317 /*****************************************************************************
1318 QTime member functions
1319 *****************************************************************************/
1325 \brief The QTime class provides clock time functions.
1328 A QTime object contains a clock time, i.e. the number of hours,
1329 minutes, seconds, and milliseconds since midnight. It can read the
1330 current time from the system clock and measure a span of elapsed
1331 time. It provides functions for comparing times and for
1332 manipulating a time by adding a number of milliseconds.
1334 QTime uses the 24-hour clock format; it has no concept of AM/PM.
1335 Unlike QDateTime, QTime knows nothing about time zones or
1336 daylight savings time (DST).
1338 A QTime object is typically created either by giving the number
1339 of hours, minutes, seconds, and milliseconds explicitly, or by
1340 using the static function currentTime(), which creates a QTime
1341 object that contains the system's local time. Note that the
1342 accuracy depends on the accuracy of the underlying operating
1343 system; not all systems provide 1-millisecond accuracy.
1345 The hour(), minute(), second(), and msec() functions provide
1346 access to the number of hours, minutes, seconds, and milliseconds
1347 of the time. The same information is provided in textual format by
1348 the toString() function.
1350 QTime provides a full set of operators to compare two QTime
1351 objects. One time is considered smaller than another if it is
1352 earlier than the other.
1354 The time a given number of seconds or milliseconds later than a
1355 given time can be found using the addSecs() or addMSecs()
1356 functions. Correspondingly, the number of seconds or milliseconds
1357 between two times can be found using secsTo() or msecsTo().
1359 QTime can be used to measure a span of elapsed time using the
1360 start(), restart(), and elapsed() functions.
1362 \sa QDate, QDateTime
1368 Constructs a null time object. A null time can be a QTime(0, 0, 0, 0)
1369 (i.e., midnight) object, except that isNull() returns true and isValid()
1372 \sa isNull(), isValid()
1376 Constructs a time with hour \a h, minute \a m, seconds \a s and
1379 \a h must be in the range 0 to 23, \a m and \a s must be in the
1380 range 0 to 59, and \a ms must be in the range 0 to 999.
1385 QTime::QTime(int h, int m, int s, int ms)
1387 setHMS(h, m, s, ms);
1392 \fn bool QTime::isNull() const
1394 Returns true if the time is null (i.e., the QTime object was
1395 constructed using the default constructor); otherwise returns
1396 false. A null time is also an invalid time.
1402 Returns true if the time is valid; otherwise returns false. For example,
1403 the time 23:30:55.746 is valid, but 24:12:30 is invalid.
1408 bool QTime::isValid() const
1410 return mds > NullTime && mds < MSECS_PER_DAY;
1415 Returns the hour part (0 to 23) of the time.
1417 Returns -1 if the time is invalid.
1419 \sa minute(), second(), msec()
1422 int QTime::hour() const
1427 return ds() / MSECS_PER_HOUR;
1431 Returns the minute part (0 to 59) of the time.
1433 Returns -1 if the time is invalid.
1435 \sa hour(), second(), msec()
1438 int QTime::minute() const
1443 return (ds() % MSECS_PER_HOUR) / MSECS_PER_MIN;
1447 Returns the second part (0 to 59) of the time.
1449 Returns -1 if the time is invalid.
1451 \sa hour(), minute(), msec()
1454 int QTime::second() const
1459 return (ds() / 1000)%SECS_PER_MIN;
1463 Returns the millisecond part (0 to 999) of the time.
1465 Returns -1 if the time is invalid.
1467 \sa hour(), minute(), second()
1470 int QTime::msec() const
1478 #ifndef QT_NO_DATESTRING
1482 Returns the time as a string. Milliseconds are not included. The
1483 \a format parameter determines the format of the string.
1485 If \a format is Qt::TextDate, the string format is HH:MM:SS; e.g. 1
1486 second before midnight would be "23:59:59".
1488 If \a format is Qt::ISODate, the string format corresponds to the
1489 ISO 8601 extended specification for representations of dates,
1490 which is also HH:MM:SS. (However, contrary to ISO 8601, dates
1491 before 15 October 1582 are handled as Julian dates, not Gregorian
1492 dates. See \l{QDate G and J} {Use of Gregorian and Julian
1493 Calendars}. This might change in a future version of Qt.)
1495 If the \a format is Qt::SystemLocaleShortDate or
1496 Qt::SystemLocaleLongDate, the string format depends on the locale
1497 settings of the system. Identical to calling
1498 QLocale::system().toString(time, QLocale::ShortFormat) or
1499 QLocale::system().toString(time, QLocale::LongFormat).
1501 If the \a format is Qt::DefaultLocaleShortDate or
1502 Qt::DefaultLocaleLongDate, the string format depends on the
1503 default application locale. This is the locale set with
1504 QLocale::setDefault(), or the system locale if no default locale
1505 has been set. Identical to calling QLocale().toString(time,
1506 QLocale::ShortFormat) or QLocale().toString(time,
1507 QLocale::LongFormat).
1509 If the time is invalid, an empty string will be returned.
1512 QString QTime::toString(Qt::DateFormat format) const
1518 case Qt::SystemLocaleDate:
1519 case Qt::SystemLocaleShortDate:
1520 case Qt::SystemLocaleLongDate:
1521 return QLocale::system().toString(*this, format == Qt::SystemLocaleLongDate ? QLocale::LongFormat
1522 : QLocale::ShortFormat);
1523 case Qt::LocaleDate:
1524 case Qt::DefaultLocaleShortDate:
1525 case Qt::DefaultLocaleLongDate:
1526 return QLocale().toString(*this, format == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
1527 : QLocale::ShortFormat);
1532 return QString::fromLatin1("%1:%2:%3")
1533 .arg(hour(), 2, 10, QLatin1Char('0'))
1534 .arg(minute(), 2, 10, QLatin1Char('0'))
1535 .arg(second(), 2, 10, QLatin1Char('0'));
1540 Returns the time as a string. The \a format parameter determines
1541 the format of the result string.
1543 These expressions may be used:
1546 \header \li Expression \li Output
1548 \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
1550 \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
1552 \li the hour without a leading zero (0 to 23, even with AM/PM display)
1554 \li the hour with a leading zero (00 to 23, even with AM/PM display)
1555 \row \li m \li the minute without a leading zero (0 to 59)
1556 \row \li mm \li the minute with a leading zero (00 to 59)
1557 \row \li s \li the second without a leading zero (0 to 59)
1558 \row \li ss \li the second with a leading zero (00 to 59)
1559 \row \li z \li the milliseconds without leading zeroes (0 to 999)
1560 \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
1562 \li use AM/PM display. \e AP will be replaced by either "AM" or "PM".
1564 \li use am/pm display. \e ap will be replaced by either "am" or "pm".
1565 \row \li t \li the timezone (for example "CEST")
1568 All other input characters will be ignored. Any sequence of characters that
1569 are enclosed in singlequotes will be treated as text and not be used as an
1570 expression. Two consecutive singlequotes ("''") are replaced by a singlequote
1573 Example format strings (assuming that the QTime is 14:13:09.042)
1576 \header \li Format \li Result
1577 \row \li hh:mm:ss.zzz \li 14:13:09.042
1578 \row \li h:m:s ap \li 2:13:9 pm
1579 \row \li H:m:s a \li 14:13:9 pm
1582 If the datetime is invalid, an empty string will be returned.
1583 If \a format is empty, the default format "hh:mm:ss" is used.
1585 \sa QDate::toString(), QDateTime::toString()
1587 QString QTime::toString(const QString& format) const
1589 return fmtDateTime(format, this, 0);
1591 #endif //QT_NO_DATESTRING
1593 Sets the time to hour \a h, minute \a m, seconds \a s and
1596 \a h must be in the range 0 to 23, \a m and \a s must be in the
1597 range 0 to 59, and \a ms must be in the range 0 to 999.
1598 Returns true if the set time is valid; otherwise returns false.
1603 bool QTime::setHMS(int h, int m, int s, int ms)
1605 #if defined(Q_OS_WINCE)
1606 startTick = NullTime;
1608 if (!isValid(h,m,s,ms)) {
1609 mds = NullTime; // make this invalid
1612 mds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;
1617 Returns a QTime object containing a time \a s seconds later
1618 than the time of this object (or earlier if \a s is negative).
1620 Note that the time will wrap if it passes midnight.
1622 Returns a null time if this time is invalid.
1626 \snippet code/src_corelib_tools_qdatetime.cpp 5
1628 \sa addMSecs(), secsTo(), QDateTime::addSecs()
1631 QTime QTime::addSecs(int s) const
1633 return addMSecs(s * 1000);
1637 Returns the number of seconds from this time to \a t.
1638 If \a t is earlier than this time, the number of seconds returned
1641 Because QTime measures time within a day and there are 86400
1642 seconds in a day, the result is always between -86400 and 86400.
1644 secsTo() does not take into account any milliseconds.
1646 Returns 0 if either time is invalid.
1648 \sa addSecs(), QDateTime::secsTo()
1651 int QTime::secsTo(const QTime &t) const
1653 if (!isValid() || !t.isValid())
1656 return (t.ds() - ds()) / 1000;
1660 Returns a QTime object containing a time \a ms milliseconds later
1661 than the time of this object (or earlier if \a ms is negative).
1663 Note that the time will wrap if it passes midnight. See addSecs()
1666 Returns a null time if this time is invalid.
1668 \sa addSecs(), msecsTo(), QDateTime::addMSecs()
1671 QTime QTime::addMSecs(int ms) const
1676 // % not well-defined for -ve, but / is.
1677 int negdays = (MSECS_PER_DAY - ms) / MSECS_PER_DAY;
1678 t.mds = (ds() + ms + negdays * MSECS_PER_DAY) % MSECS_PER_DAY;
1680 t.mds = (ds() + ms) % MSECS_PER_DAY;
1683 #if defined(Q_OS_WINCE)
1684 if (startTick > NullTime)
1685 t.startTick = (startTick + ms) % MSECS_PER_DAY;
1691 Returns the number of milliseconds from this time to \a t.
1692 If \a t is earlier than this time, the number of milliseconds returned
1695 Because QTime measures time within a day and there are 86400
1696 seconds in a day, the result is always between -86400000 and
1699 Returns 0 if either time is invalid.
1701 \sa secsTo(), addMSecs(), QDateTime::msecsTo()
1704 int QTime::msecsTo(const QTime &t) const
1706 if (!isValid() || !t.isValid())
1708 #if defined(Q_OS_WINCE)
1709 // GetLocalTime() for Windows CE has no milliseconds resolution
1710 if (t.startTick > NullTime && startTick > NullTime)
1711 return t.startTick - startTick;
1714 return t.ds() - ds();
1719 \fn bool QTime::operator==(const QTime &t) const
1721 Returns true if this time is equal to \a t; otherwise returns false.
1725 \fn bool QTime::operator!=(const QTime &t) const
1727 Returns true if this time is different from \a t; otherwise returns false.
1731 \fn bool QTime::operator<(const QTime &t) const
1733 Returns true if this time is earlier than \a t; otherwise returns false.
1737 \fn bool QTime::operator<=(const QTime &t) const
1739 Returns true if this time is earlier than or equal to \a t;
1740 otherwise returns false.
1744 \fn bool QTime::operator>(const QTime &t) const
1746 Returns true if this time is later than \a t; otherwise returns false.
1750 \fn bool QTime::operator>=(const QTime &t) const
1752 Returns true if this time is later than or equal to \a t;
1753 otherwise returns false.
1757 \fn QTime::currentTime()
1759 Returns the current time as reported by the system clock.
1761 Note that the accuracy depends on the accuracy of the underlying
1762 operating system; not all systems provide 1-millisecond accuracy.
1765 #ifndef QT_NO_DATESTRING
1767 \fn QTime QTime::fromString(const QString &string, Qt::DateFormat format)
1769 Returns the time represented in the \a string as a QTime using the
1770 \a format given, or an invalid time if this is not possible.
1772 Note that fromString() uses a "C" locale encoded string to convert
1773 milliseconds to a float value. If the default locale is not "C",
1774 this may result in two conversion attempts (if the conversion
1775 fails for the default locale). This should be considered an
1776 implementation detail.
1778 QTime QTime::fromString(const QString& s, Qt::DateFormat f)
1787 case Qt::SystemLocaleDate:
1788 case Qt::SystemLocaleShortDate:
1789 case Qt::SystemLocaleLongDate:
1790 return fromString(s, QLocale::system().timeFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
1791 : QLocale::ShortFormat));
1792 case Qt::LocaleDate:
1793 case Qt::DefaultLocaleShortDate:
1794 case Qt::DefaultLocaleLongDate:
1795 return fromString(s, QLocale().timeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
1796 : QLocale::ShortFormat));
1800 const int hour(s.mid(0, 2).toInt(&ok));
1803 const int minute(s.mid(3, 2).toInt(&ok));
1806 if (f == Qt::ISODate && s.size() == 5) {
1807 // Do not need to specify seconds if using ISO format.
1808 return QTime(hour, minute, 0, 0);
1810 const int second(s.mid(6, 2).toInt(&ok));
1813 const QString msec_s(QLatin1String("0.") + s.mid(9, 4));
1814 const float msec(msec_s.toFloat(&ok));
1816 return QTime(hour, minute, second, 0);
1817 return QTime(hour, minute, second, qMin(qRound(msec * 1000.0), 999));
1823 \fn QTime::fromString(const QString &string, const QString &format)
1825 Returns the QTime represented by the \a string, using the \a
1826 format given, or an invalid time if the string cannot be parsed.
1828 These expressions may be used for the format:
1831 \header \li Expression \li Output
1833 \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
1835 \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
1836 \row \li m \li the minute without a leading zero (0 to 59)
1837 \row \li mm \li the minute with a leading zero (00 to 59)
1838 \row \li s \li the second without a leading zero (0 to 59)
1839 \row \li ss \li the second with a leading zero (00 to 59)
1840 \row \li z \li the milliseconds without leading zeroes (0 to 999)
1841 \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
1843 \li interpret as an AM/PM time. \e AP must be either "AM" or "PM".
1845 \li Interpret as an AM/PM time. \e ap must be either "am" or "pm".
1848 All other input characters will be treated as text. Any sequence
1849 of characters that are enclosed in single quotes will also be
1850 treated as text and not be used as an expression.
1852 \snippet code/src_corelib_tools_qdatetime.cpp 6
1854 If the format is not satisfied an invalid QTime is returned.
1855 Expressions that do not expect leading zeroes to be given (h, m, s
1856 and z) are greedy. This means that they will use two digits even if
1857 this puts them outside the range of accepted values and leaves too
1858 few digits for other sections. For example, the following string
1859 could have meant 00:07:10, but the m will grab two digits, resulting
1862 \snippet code/src_corelib_tools_qdatetime.cpp 7
1864 Any field that is not represented in the format will be set to zero.
1867 \snippet code/src_corelib_tools_qdatetime.cpp 8
1869 \sa QDateTime::fromString(), QDate::fromString(), QDate::toString(),
1870 QDateTime::toString(), QTime::toString()
1873 QTime QTime::fromString(const QString &string, const QString &format)
1876 #ifndef QT_BOOTSTRAPPED
1877 QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
1878 if (dt.parseFormat(format))
1879 dt.fromString(string, 0, &time);
1887 #endif // QT_NO_DATESTRING
1893 Returns true if the specified time is valid; otherwise returns
1896 The time is valid if \a h is in the range 0 to 23, \a m and
1897 \a s are in the range 0 to 59, and \a ms is in the range 0 to 999.
1901 \snippet code/src_corelib_tools_qdatetime.cpp 9
1904 bool QTime::isValid(int h, int m, int s, int ms)
1906 return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
1911 Sets this time to the current time. This is practical for timing:
1913 \snippet code/src_corelib_tools_qdatetime.cpp 10
1915 \sa restart(), elapsed(), currentTime()
1920 *this = currentTime();
1924 Sets this time to the current time and returns the number of
1925 milliseconds that have elapsed since the last time start() or
1926 restart() was called.
1928 This function is guaranteed to be atomic and is thus very handy
1929 for repeated measurements. Call start() to start the first
1930 measurement, and restart() for each later measurement.
1932 Note that the counter wraps to zero 24 hours after the last call
1933 to start() or restart().
1935 \warning If the system's clock setting has been changed since the
1936 last time start() or restart() was called, the result is
1937 undefined. This can happen when daylight savings time is turned on
1940 \sa start(), elapsed(), currentTime()
1943 int QTime::restart()
1945 QTime t = currentTime();
1947 if (n < 0) // passed midnight
1954 Returns the number of milliseconds that have elapsed since the
1955 last time start() or restart() was called.
1957 Note that the counter wraps to zero 24 hours after the last call
1958 to start() or restart.
1960 Note that the accuracy depends on the accuracy of the underlying
1961 operating system; not all systems provide 1-millisecond accuracy.
1963 \warning If the system's clock setting has been changed since the
1964 last time start() or restart() was called, the result is
1965 undefined. This can happen when daylight savings time is turned on
1968 \sa start(), restart()
1971 int QTime::elapsed() const
1973 int n = msecsTo(currentTime());
1974 if (n < 0) // passed midnight
1980 /*****************************************************************************
1981 QDateTime member functions
1982 *****************************************************************************/
1987 \brief The QDateTime class provides date and time functions.
1990 A QDateTime object contains a calendar date and a clock time (a
1991 "datetime"). It is a combination of the QDate and QTime classes.
1992 It can read the current datetime from the system clock. It
1993 provides functions for comparing datetimes and for manipulating a
1994 datetime by adding a number of seconds, days, months, or years.
1996 A QDateTime object is typically created either by giving a date
1997 and time explicitly in the constructor, or by using the static
1998 function currentDateTime() that returns a QDateTime object set
1999 to the system clock's time. The date and time can be changed with
2000 setDate() and setTime(). A datetime can also be set using the
2001 setTime_t() function that takes a POSIX-standard "number of
2002 seconds since 00:00:00 on January 1, 1970" value. The fromString()
2003 function returns a QDateTime, given a string and a date format
2004 used to interpret the date within the string.
2006 The date() and time() functions provide access to the date and
2007 time parts of the datetime. The same information is provided in
2008 textual format by the toString() function.
2010 QDateTime provides a full set of operators to compare two
2011 QDateTime objects where smaller means earlier and larger means
2014 You can increment (or decrement) a datetime by a given number of
2015 milliseconds using addMSecs(), seconds using addSecs(), or days
2016 using addDays(). Similarly you can use addMonths() and addYears().
2017 The daysTo() function returns the number of days between two datetimes,
2018 secsTo() returns the number of seconds between two datetimes, and
2019 msecsTo() returns the number of milliseconds between two datetimes.
2021 QDateTime can store datetimes as \l{Qt::LocalTime}{local time} or
2022 as \l{Qt::UTC}{UTC}. QDateTime::currentDateTime() returns a
2023 QDateTime expressed as local time; use toUTC() to convert it to
2024 UTC. You can also use timeSpec() to find out if a QDateTime
2025 object stores a UTC time or a local time. Operations such as
2026 addSecs() and secsTo() are aware of daylight saving time (DST).
2028 \note QDateTime does not account for leap seconds.
2034 There is no year 0. Dates in that year are considered invalid. The
2035 year -1 is the year "1 before Christ" or "1 before current era."
2036 The day before 1 January 1 CE is 31 December 1 BCE.
2038 \section2 Range of Valid Dates
2040 Dates are stored internally as a Julian Day number, an interger count of
2041 every day in a contiguous range, with 24 November 4714 BCE in the Gregorian
2042 calendar being Julian Day 0 (1 January 4713 BCE in the Julian calendar).
2043 As well as being an efficient and accurate way of storing an absolute date,
2044 it is suitable for converting a Date into other calendar systems such as
2045 Hebrew, Islamic or Chinese. The Julian Day number can be obtained using
2046 QDate::toJulianDay() and can be set using QDate::fromJulianDay().
2048 The range of dates able to be stored by QDate as a Julian Day number is
2049 limited for convenience from std::numeric_limits<qint64>::min() / 2 to
2050 std::numeric_limits<qint64>::max() / 2, which on most platforms means
2051 from around 2.5 quadrillion BCE to around 2.5 quadrillion CE, effectively
2052 covering the full range of astronomical time. The range of Julian Days
2053 able to be accurately converted to and from valid YMD form Dates is
2054 restricted to 1 January 4800 BCE to 31 December 1400000 CE due to
2055 shortcomings in the available conversion formulas. Conversions outside this
2056 range are not guaranteed to be correct. This may change in the future.
2059 Use of System Timezone
2061 QDateTime uses the system's time zone information to determine the
2062 offset of local time from UTC. If the system is not configured
2063 correctly or not up-to-date, QDateTime will give wrong results as
2066 \section2 Daylight Savings Time (DST)
2068 QDateTime takes into account the system's time zone information
2069 when dealing with DST. On modern Unix systems, this means it
2070 applies the correct historical DST data whenever possible. On
2071 Windows and Windows CE, where the system doesn't support
2072 historical DST data, historical accuracy is not maintained with
2075 The range of valid dates taking DST into account is 1970-01-01 to
2076 the present, and rules are in place for handling DST correctly
2077 until 2037-12-31, but these could change. For dates falling
2078 outside that range, QDateTime makes a \e{best guess} using the
2079 rules for year 1970 or 2037, but we can't guarantee accuracy. This
2080 means QDateTime doesn't take into account changes in a locale's
2081 time zone before 1970, even if the system's time zone database
2082 supports that information.
2084 \sa QDate, QTime, QDateTimeEdit
2088 Constructs a null datetime (i.e. null date and null time). A null
2089 datetime is invalid, since the date is invalid.
2093 QDateTime::QDateTime()
2094 : d(new QDateTimePrivate)
2100 Constructs a datetime with the given \a date, a valid
2101 time(00:00:00.000), and sets the timeSpec() to Qt::LocalTime.
2104 QDateTime::QDateTime(const QDate &date)
2105 : d(new QDateTimePrivate)
2108 d->time = QTime(0, 0, 0);
2112 Constructs a datetime with the given \a date and \a time, using
2113 the time specification defined by \a spec.
2115 If \a date is valid and \a time is not, the time will be set to midnight.
2118 QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec)
2119 : d(new QDateTimePrivate)
2122 d->time = date.isValid() && !time.isValid() ? QTime(0, 0, 0) : time;
2123 d->spec = (spec == Qt::UTC) ? QDateTimePrivate::UTC : QDateTimePrivate::LocalUnknown;
2127 Constructs a copy of the \a other datetime.
2130 QDateTime::QDateTime(const QDateTime &other)
2136 Destroys the datetime.
2138 QDateTime::~QDateTime()
2143 Makes a copy of the \a other datetime and returns a reference to the
2147 QDateTime &QDateTime::operator=(const QDateTime &other)
2154 Returns true if both the date and the time are null; otherwise
2155 returns false. A null datetime is invalid.
2157 \sa QDate::isNull(), QTime::isNull(), isValid()
2160 bool QDateTime::isNull() const
2162 return d->date.isNull() && d->time.isNull();
2166 Returns true if both the date and the time are valid; otherwise
2169 \sa QDate::isValid(), QTime::isValid()
2172 bool QDateTime::isValid() const
2174 return d->date.isValid() && d->time.isValid();
2178 Returns the date part of the datetime.
2180 \sa setDate(), time(), timeSpec()
2183 QDate QDateTime::date() const
2189 Returns the time part of the datetime.
2191 \sa setTime(), date(), timeSpec()
2194 QTime QDateTime::time() const
2200 Returns the time specification of the datetime.
2202 \sa setTimeSpec(), date(), time(), Qt::TimeSpec
2205 Qt::TimeSpec QDateTime::timeSpec() const
2209 case QDateTimePrivate::UTC:
2211 case QDateTimePrivate::OffsetFromUTC:
2212 return Qt::OffsetFromUTC;
2214 return Qt::LocalTime;
2219 Sets the date part of this datetime to \a date.
2220 If no time is set, it is set to midnight.
2222 \sa date(), setTime(), setTimeSpec()
2225 void QDateTime::setDate(const QDate &date)
2229 if (d->spec == QDateTimePrivate::LocalStandard
2230 || d->spec == QDateTimePrivate::LocalDST)
2231 d->spec = QDateTimePrivate::LocalUnknown;
2232 if (date.isValid() && !d->time.isValid())
2233 d->time = QTime(0, 0, 0);
2237 Sets the time part of this datetime to \a time.
2239 \sa time(), setDate(), setTimeSpec()
2242 void QDateTime::setTime(const QTime &time)
2245 if (d->spec == QDateTimePrivate::LocalStandard
2246 || d->spec == QDateTimePrivate::LocalDST)
2247 d->spec = QDateTimePrivate::LocalUnknown;
2252 Sets the time specification used in this datetime to \a spec.
2254 \sa timeSpec(), setDate(), setTime(), Qt::TimeSpec
2257 void QDateTime::setTimeSpec(Qt::TimeSpec spec)
2264 d->spec = QDateTimePrivate::UTC;
2266 case Qt::OffsetFromUTC:
2267 d->spec = QDateTimePrivate::OffsetFromUTC;
2270 d->spec = QDateTimePrivate::LocalUnknown;
2275 qint64 toMSecsSinceEpoch_helper(qint64 jd, int msecs)
2277 qint64 days = jd - JULIAN_DAY_FOR_EPOCH;
2278 qint64 retval = (days * MSECS_PER_DAY) + msecs;
2285 Returns the datetime as the number of milliseconds that have passed
2286 since 1970-01-01T00:00:00.000, Coordinated Universal Time (Qt::UTC).
2288 On systems that do not support time zones, this function will
2289 behave as if local time were Qt::UTC.
2291 The behavior for this function is undefined if the datetime stored in
2292 this object is not valid. However, for all valid dates, this function
2293 returns a unique value.
2295 \sa toTime_t(), setMSecsSinceEpoch()
2297 qint64 QDateTime::toMSecsSinceEpoch() const
2301 d->getUTC(utcDate, utcTime);
2303 return toMSecsSinceEpoch_helper(utcDate.toJulianDay(), QTime(0, 0, 0).msecsTo(utcTime));
2307 Returns the datetime as the number of seconds that have passed
2308 since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC).
2310 On systems that do not support time zones, this function will
2311 behave as if local time were Qt::UTC.
2313 \note This function returns a 32-bit unsigned integer, so it does not
2314 support dates before 1970, but it does support dates after
2315 2038-01-19T03:14:06, which may not be valid time_t values. Be careful
2316 when passing those time_t values to system functions, which could
2317 interpret them as negative dates.
2319 If the date is outside the range 1970-01-01T00:00:00 to
2320 2106-02-07T06:28:14, this function returns -1 cast to an unsigned integer
2323 To get an extended range, use toMSecsSinceEpoch().
2325 \sa toMSecsSinceEpoch(), setTime_t()
2328 uint QDateTime::toTime_t() const
2330 qint64 retval = toMSecsSinceEpoch() / 1000;
2331 if (quint64(retval) >= Q_UINT64_C(0xFFFFFFFF))
2333 return uint(retval);
2339 Sets the date and time given the number of milliseconds,\a msecs, that have
2340 passed since 1970-01-01T00:00:00.000, Coordinated Universal Time
2341 (Qt::UTC). On systems that do not support time zones this function
2342 will behave as if local time were Qt::UTC.
2344 Note that there are possible values for \a msecs that lie outside the
2345 valid range of QDateTime, both negative and positive. The behavior of
2346 this function is undefined for those values.
2348 \sa toMSecsSinceEpoch(), setTime_t()
2350 void QDateTime::setMSecsSinceEpoch(qint64 msecs)
2354 QDateTimePrivate::Spec oldSpec = d->spec;
2356 int ddays = msecs / MSECS_PER_DAY;
2357 msecs %= MSECS_PER_DAY;
2361 msecs += MSECS_PER_DAY;
2364 d->date = QDate(1970, 1, 1).addDays(ddays);
2365 d->time = QTime(0, 0, 0).addMSecs(msecs);
2366 d->spec = QDateTimePrivate::UTC;
2368 if (oldSpec != QDateTimePrivate::UTC)
2369 d->spec = d->getLocal(d->date, d->time);
2373 \fn void QDateTime::setTime_t(uint seconds)
2375 Sets the date and time given the number of \a seconds that have
2376 passed since 1970-01-01T00:00:00, Coordinated Universal Time
2377 (Qt::UTC). On systems that do not support time zones this function
2378 will behave as if local time were Qt::UTC.
2383 void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
2387 QDateTimePrivate::Spec oldSpec = d->spec;
2389 d->date = QDate(1970, 1, 1).addDays(secsSince1Jan1970UTC / SECS_PER_DAY);
2390 d->time = QTime(0, 0, 0).addSecs(secsSince1Jan1970UTC % SECS_PER_DAY);
2391 d->spec = QDateTimePrivate::UTC;
2393 if (oldSpec != QDateTimePrivate::UTC)
2394 d->spec = d->getLocal(d->date, d->time);
2397 #ifndef QT_NO_DATESTRING
2399 \fn QString QDateTime::toString(Qt::DateFormat format) const
2403 Returns the datetime as a string in the \a format given.
2405 If the \a format is Qt::TextDate, the string is formatted in
2406 the default way. QDate::shortDayName(), QDate::shortMonthName(),
2407 and QTime::toString() are used to generate the string, so the
2408 day and month names will be localized names. An example of this
2409 formatting is "Wed May 20 03:40:13 1998".
2411 If the \a format is Qt::ISODate, the string format corresponds
2412 to the ISO 8601 extended specification for representations of
2413 dates and times, taking the form YYYY-MM-DDTHH:MM:SS[Z|[+|-]HH:MM],
2414 depending on the timeSpec() of the QDateTime. If the timeSpec()
2415 is Qt::UTC, Z will be appended to the string; if the timeSpec() is
2416 Qt::OffsetFromUTC the offset in hours and minutes from UTC will
2417 be appended to the string.
2419 If the \a format is Qt::SystemLocaleShortDate or
2420 Qt::SystemLocaleLongDate, the string format depends on the locale
2421 settings of the system. Identical to calling
2422 QLocale::system().toString(datetime, QLocale::ShortFormat) or
2423 QLocale::system().toString(datetime, QLocale::LongFormat).
2425 If the \a format is Qt::DefaultLocaleShortDate or
2426 Qt::DefaultLocaleLongDate, the string format depends on the
2427 default application locale. This is the locale set with
2428 QLocale::setDefault(), or the system locale if no default locale
2429 has been set. Identical to calling QLocale().toString(datetime,
2430 QLocale::ShortFormat) or QLocale().toString(datetime,
2431 QLocale::LongFormat).
2433 If the datetime is invalid, an empty string will be returned.
2435 \warning The Qt::ISODate format is only valid for years in the
2436 range 0 to 9999. This restriction may apply to locale-aware
2437 formats as well, depending on the locale settings.
2439 \sa QDate::toString(), QTime::toString(), Qt::DateFormat
2442 QString QDateTime::toString(Qt::DateFormat f) const
2448 if (f == Qt::ISODate) {
2449 buf = d->date.toString(Qt::ISODate);
2451 return QString(); // failed to convert
2452 buf += QLatin1Char('T');
2453 buf += d->time.toString(Qt::ISODate);
2455 case QDateTimePrivate::UTC:
2456 buf += QLatin1Char('Z');
2458 case QDateTimePrivate::OffsetFromUTC: {
2459 int sign = d->utcOffset >= 0 ? 1: -1;
2460 buf += QString::fromLatin1("%1%2:%3").
2461 arg(sign == 1 ? QLatin1Char('+') : QLatin1Char('-')).
2462 arg(d->utcOffset * sign / SECS_PER_HOUR, 2, 10, QLatin1Char('0')).
2463 arg((d->utcOffset / 60) % 60, 2, 10, QLatin1Char('0'));
2470 #ifndef QT_NO_TEXTDATE
2471 else if (f == Qt::TextDate) {
2473 buf = d->date.shortDayName(d->date.dayOfWeek());
2474 buf += QLatin1Char(' ');
2475 buf += d->date.shortMonthName(d->date.month());
2476 buf += QLatin1Char(' ');
2477 buf += QString::number(d->date.day());
2480 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255);
2481 QString winstr = QString::fromWCharArray(out);
2482 switch (winstr.toInt()) {
2484 buf = d->date.shortDayName(d->date.dayOfWeek());
2485 buf += QLatin1Char(' ');
2486 buf += QString::number(d->date.day());
2487 buf += QLatin1String(". ");
2488 buf += d->date.shortMonthName(d->date.month());
2491 buf = d->date.shortDayName(d->date.dayOfWeek());
2492 buf += QLatin1Char(' ');
2493 buf += d->date.shortMonthName(d->date.month());
2494 buf += QLatin1Char(' ');
2495 buf += QString::number(d->date.day());
2498 buf += QLatin1Char(' ');
2499 buf += d->time.toString();
2500 buf += QLatin1Char(' ');
2501 buf += QString::number(d->date.year());
2505 buf = d->date.toString(f);
2507 return QString(); // failed to convert
2508 buf += QLatin1Char(' ');
2509 buf += d->time.toString(f);
2516 Returns the datetime as a string. The \a format parameter
2517 determines the format of the result string.
2519 These expressions may be used for the date:
2522 \header \li Expression \li Output
2523 \row \li d \li the day as number without a leading zero (1 to 31)
2524 \row \li dd \li the day as number with a leading zero (01 to 31)
2526 \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
2527 Uses QDate::shortDayName().
2529 \li the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
2530 Uses QDate::longDayName().
2531 \row \li M \li the month as number without a leading zero (1-12)
2532 \row \li MM \li the month as number with a leading zero (01-12)
2534 \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
2535 Uses QDate::shortMonthName().
2537 \li the long localized month name (e.g. 'January' to 'December').
2538 Uses QDate::longMonthName().
2539 \row \li yy \li the year as two digit number (00-99)
2540 \row \li yyyy \li the year as four digit number
2543 These expressions may be used for the time:
2546 \header \li Expression \li Output
2548 \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
2550 \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
2551 \row \li m \li the minute without a leading zero (0 to 59)
2552 \row \li mm \li the minute with a leading zero (00 to 59)
2553 \row \li s \li the second without a leading zero (0 to 59)
2554 \row \li ss \li the second with a leading zero (00 to 59)
2555 \row \li z \li the milliseconds without leading zeroes (0 to 999)
2556 \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
2558 \li use AM/PM display. \e AP will be replaced by either "AM" or "PM".
2560 \li use am/pm display. \e ap will be replaced by either "am" or "pm".
2563 All other input characters will be ignored. Any sequence of characters that
2564 are enclosed in singlequotes will be treated as text and not be used as an
2565 expression. Two consecutive singlequotes ("''") are replaced by a singlequote
2568 Example format strings (assumed that the QDateTime is 21 May 2001
2572 \header \li Format \li Result
2573 \row \li dd.MM.yyyy \li 21.05.2001
2574 \row \li ddd MMMM d yy \li Tue May 21 01
2575 \row \li hh:mm:ss.zzz \li 14:13:09.042
2576 \row \li h:m:s ap \li 2:13:9 pm
2579 If the datetime is invalid, an empty string will be returned.
2581 \sa QDate::toString(), QTime::toString()
2583 QString QDateTime::toString(const QString& format) const
2585 return fmtDateTime(format, &d->time, &d->date);
2587 #endif //QT_NO_DATESTRING
2590 Returns a QDateTime object containing a datetime \a ndays days
2591 later than the datetime of this object (or earlier if \a ndays is
2594 \sa daysTo(), addMonths(), addYears(), addSecs()
2597 QDateTime QDateTime::addDays(qint64 ndays) const
2599 return QDateTime(d->date.addDays(ndays), d->time, timeSpec());
2603 Returns a QDateTime object containing a datetime \a nmonths months
2604 later than the datetime of this object (or earlier if \a nmonths
2607 \sa daysTo(), addDays(), addYears(), addSecs()
2610 QDateTime QDateTime::addMonths(int nmonths) const
2612 return QDateTime(d->date.addMonths(nmonths), d->time, timeSpec());
2616 Returns a QDateTime object containing a datetime \a nyears years
2617 later than the datetime of this object (or earlier if \a nyears is
2620 \sa daysTo(), addDays(), addMonths(), addSecs()
2623 QDateTime QDateTime::addYears(int nyears) const
2625 return QDateTime(d->date.addYears(nyears), d->time, timeSpec());
2628 QDateTime QDateTimePrivate::addMSecs(const QDateTime &dt, qint64 msecs)
2632 dt.d->getUTC(utcDate, utcTime);
2634 addMSecs(utcDate, utcTime, msecs);
2636 return QDateTime(utcDate, utcTime, Qt::UTC).toTimeSpec(dt.timeSpec());
2640 Adds \a msecs to utcDate and \a utcTime as appropriate. It is assumed that
2641 utcDate and utcTime are adjusted to UTC.
2646 void QDateTimePrivate::addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs)
2648 qint64 dd = utcDate.toJulianDay();
2649 int tt = QTime(0, 0, 0).msecsTo(utcTime);
2655 if (msecs >= int(MSECS_PER_DAY)) {
2656 dd += sign * (msecs / MSECS_PER_DAY);
2657 msecs %= MSECS_PER_DAY;
2662 tt = MSECS_PER_DAY - tt - 1;
2663 dd -= tt / MSECS_PER_DAY;
2664 tt = tt % MSECS_PER_DAY;
2665 tt = MSECS_PER_DAY - tt - 1;
2666 } else if (tt >= int(MSECS_PER_DAY)) {
2667 dd += tt / MSECS_PER_DAY;
2668 tt = tt % MSECS_PER_DAY;
2671 utcDate = QDate::fromJulianDay(dd);
2672 utcTime = QTime(0, 0, 0).addMSecs(tt);
2676 Returns a QDateTime object containing a datetime \a s seconds
2677 later than the datetime of this object (or earlier if \a s is
2680 \sa addMSecs(), secsTo(), addDays(), addMonths(), addYears()
2683 QDateTime QDateTime::addSecs(int s) const
2685 return d->addMSecs(*this, qint64(s) * 1000);
2689 Returns a QDateTime object containing a datetime \a msecs miliseconds
2690 later than the datetime of this object (or earlier if \a msecs is
2693 \sa addSecs(), msecsTo(), addDays(), addMonths(), addYears()
2695 QDateTime QDateTime::addMSecs(qint64 msecs) const
2697 return d->addMSecs(*this, msecs);
2701 Returns the number of days from this datetime to the \a other
2702 datetime. If the \a other datetime is earlier than this datetime,
2703 the value returned is negative.
2705 \sa addDays(), secsTo(), msecsTo()
2708 qint64 QDateTime::daysTo(const QDateTime &other) const
2710 return d->date.daysTo(other.d->date);
2714 Returns the number of seconds from this datetime to the \a other
2715 datetime. If the \a other datetime is earlier than this datetime,
2716 the value returned is negative.
2718 Before performing the comparison, the two datetimes are converted
2719 to Qt::UTC to ensure that the result is correct if one of the two
2720 datetimes has daylight saving time (DST) and the other doesn't.
2722 Returns 0 if either time is invalid.
2725 \snippet code/src_corelib_tools_qdatetime.cpp 11
2727 \sa addSecs(), daysTo(), QTime::secsTo()
2730 int QDateTime::secsTo(const QDateTime &other) const
2732 if (!isValid() || !other.isValid())
2738 d->getUTC(date1, time1);
2739 other.d->getUTC(date2, time2);
2741 return (date1.daysTo(date2) * SECS_PER_DAY) + time1.secsTo(time2);
2745 Returns the number of milliseconds from this datetime to the \a other
2746 datetime. If the \a other datetime is earlier than this datetime,
2747 the value returned is negative.
2749 Before performing the comparison, the two datetimes are converted
2750 to Qt::UTC to ensure that the result is correct if one of the two
2751 datetimes has daylight saving time (DST) and the other doesn't.
2753 Returns 0 if either time is null.
2755 \sa addMSecs(), daysTo(), QTime::msecsTo()
2758 qint64 QDateTime::msecsTo(const QDateTime &other) const
2760 if (!isValid() || !other.isValid())
2768 d->getUTC(selfDate, selfTime);
2769 other.d->getUTC(otherDate, otherTime);
2771 return (static_cast<qint64>(selfDate.daysTo(otherDate)) * static_cast<qint64>(MSECS_PER_DAY))
2772 + static_cast<qint64>(selfTime.msecsTo(otherTime));
2777 \fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec specification) const
2779 Returns a copy of this datetime configured to use the given time
2782 \sa timeSpec(), toUTC(), toLocalTime()
2785 QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
2787 if ((d->spec == QDateTimePrivate::UTC) == (spec == Qt::UTC))
2791 if (spec == Qt::UTC) {
2792 d->getUTC(ret.d->date, ret.d->time);
2793 ret.d->spec = QDateTimePrivate::UTC;
2795 ret.d->spec = d->getLocal(ret.d->date, ret.d->time);
2801 Returns true if this datetime is equal to the \a other datetime;
2802 otherwise returns false.
2807 bool QDateTime::operator==(const QDateTime &other) const
2809 if (d->spec == other.d->spec && d->utcOffset == other.d->utcOffset)
2810 return d->time == other.d->time && d->date == other.d->date;
2815 d->getUTC(date1, time1);
2816 other.d->getUTC(date2, time2);
2817 return time1 == time2 && date1 == date2;
2822 \fn bool QDateTime::operator!=(const QDateTime &other) const
2824 Returns true if this datetime is different from the \a other
2825 datetime; otherwise returns false.
2827 Two datetimes are different if either the date, the time, or the
2828 time zone components are different.
2834 Returns true if this datetime is earlier than the \a other
2835 datetime; otherwise returns false.
2838 bool QDateTime::operator<(const QDateTime &other) const
2840 if (d->spec == other.d->spec && d->spec != QDateTimePrivate::OffsetFromUTC) {
2841 if (d->date != other.d->date)
2842 return d->date < other.d->date;
2843 return d->time < other.d->time;
2847 d->getUTC(date1, time1);
2848 other.d->getUTC(date2, time2);
2850 return date1 < date2;
2851 return time1 < time2;
2856 \fn bool QDateTime::operator<=(const QDateTime &other) const
2858 Returns true if this datetime is earlier than or equal to the
2859 \a other datetime; otherwise returns false.
2863 \fn bool QDateTime::operator>(const QDateTime &other) const
2865 Returns true if this datetime is later than the \a other datetime;
2866 otherwise returns false.
2870 \fn bool QDateTime::operator>=(const QDateTime &other) const
2872 Returns true if this datetime is later than or equal to the
2873 \a other datetime; otherwise returns false.
2877 \fn QDateTime QDateTime::currentDateTime()
2878 Returns the current datetime, as reported by the system clock, in
2879 the local time zone.
2881 \sa currentDateTimeUtc(), QDate::currentDate(), QTime::currentTime(), toTimeSpec()
2885 \fn QDateTime QDateTime::currentDateTimeUtc()
2887 Returns the current datetime, as reported by the system clock, in
2890 \sa currentDateTime(), QDate::currentDate(), QTime::currentTime(), toTimeSpec()
2894 \fn qint64 QDateTime::currentMSecsSinceEpoch()
2897 Returns the number of milliseconds since 1970-01-01T00:00:00 Universal
2898 Coordinated Time. This number is like the POSIX time_t variable, but
2899 expressed in milliseconds instead.
2901 \sa currentDateTime(), currentDateTimeUtc(), toTime_t(), toTimeSpec()
2904 static inline uint msecsFromDecomposed(int hour, int minute, int sec, int msec = 0)
2906 return MSECS_PER_HOUR * hour + MSECS_PER_MIN * minute + 1000 * sec + msec;
2909 #if defined(Q_OS_WIN)
2910 QDate QDate::currentDate()
2914 memset(&st, 0, sizeof(SYSTEMTIME));
2916 d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
2920 QTime QTime::currentTime()
2924 memset(&st, 0, sizeof(SYSTEMTIME));
2926 ct.setHMS(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
2927 #if defined(Q_OS_WINCE)
2928 ct.startTick = GetTickCount() % MSECS_PER_DAY;
2933 QDateTime QDateTime::currentDateTime()
2938 memset(&st, 0, sizeof(SYSTEMTIME));
2940 d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
2941 t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
2942 return QDateTime(d, t);
2945 QDateTime QDateTime::currentDateTimeUtc()
2950 memset(&st, 0, sizeof(SYSTEMTIME));
2952 d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
2953 t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
2954 return QDateTime(d, t, Qt::UTC);
2957 qint64 QDateTime::currentMSecsSinceEpoch()
2962 memset(&st, 0, sizeof(SYSTEMTIME));
2965 return msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds) +
2966 qint64(julianDayFromDate(st.wYear, st.wMonth, st.wDay)
2967 - julianDayFromDate(1970, 1, 1)) * Q_INT64_C(86400000);
2970 #elif defined(Q_OS_UNIX)
2971 QDate QDate::currentDate()
2974 // posix compliant system
2979 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
2980 // use the reentrant version of localtime() where available
2983 t = localtime_r(<ime, &res);
2985 t = localtime(<ime);
2986 #endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
2988 d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
2992 QTime QTime::currentTime()
2995 // posix compliant system
2997 gettimeofday(&tv, 0);
2998 time_t ltime = tv.tv_sec;
3001 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3002 // use the reentrant version of localtime() where available
3005 t = localtime_r(<ime, &res);
3007 t = localtime(<ime);
3011 ct.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
3015 QDateTime QDateTime::currentDateTime()
3017 // posix compliant system
3018 // we have milliseconds
3020 gettimeofday(&tv, 0);
3021 time_t ltime = tv.tv_sec;
3024 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3025 // use the reentrant version of localtime() where available
3028 t = localtime_r(<ime, &res);
3030 t = localtime(<ime);
3034 dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
3036 dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
3037 dt.d->spec = t->tm_isdst > 0 ? QDateTimePrivate::LocalDST :
3038 t->tm_isdst == 0 ? QDateTimePrivate::LocalStandard :
3039 QDateTimePrivate::LocalUnknown;
3043 QDateTime QDateTime::currentDateTimeUtc()
3045 // posix compliant system
3046 // we have milliseconds
3048 gettimeofday(&tv, 0);
3049 time_t ltime = tv.tv_sec;
3052 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3053 // use the reentrant version of localtime() where available
3055 t = gmtime_r(<ime, &res);
3061 dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
3063 dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
3064 dt.d->spec = QDateTimePrivate::UTC;
3068 qint64 QDateTime::currentMSecsSinceEpoch()
3070 // posix compliant system
3071 // we have milliseconds
3073 gettimeofday(&tv, 0);
3074 return qint64(tv.tv_sec) * Q_INT64_C(1000) + tv.tv_usec / 1000;
3078 #error "What system is this?"
3084 Returns a datetime whose date and time are the number of \a seconds
3085 that have passed since 1970-01-01T00:00:00, Coordinated Universal
3086 Time (Qt::UTC). On systems that do not support time zones, the time
3087 will be set as if local time were Qt::UTC.
3089 \sa toTime_t(), setTime_t()
3091 QDateTime QDateTime::fromTime_t(uint seconds)
3094 d.setTime_t(seconds);
3101 Returns a datetime whose date and time are the number of milliseconds, \a msecs,
3102 that have passed since 1970-01-01T00:00:00.000, Coordinated Universal
3103 Time (Qt::UTC). On systems that do not support time zones, the time
3104 will be set as if local time were Qt::UTC.
3106 Note that there are possible values for \a msecs that lie outside the valid
3107 range of QDateTime, both negative and positive. The behavior of this
3108 function is undefined for those values.
3110 \sa toTime_t(), setTime_t()
3112 QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs)
3115 d.setMSecsSinceEpoch(msecs);
3123 Sets the offset from UTC to \a seconds, and also sets timeSpec() to
3126 The maximum and minimum offset is 14 positive or negative hours. If
3127 \a seconds is larger or smaller than that, the result is undefined.
3129 0 as offset is identical to UTC. Therefore, if \a seconds is 0, the
3130 timeSpec() will be set to Qt::UTC. Hence the UTC offset always
3131 relates to UTC, and can never relate to local time.
3133 \sa isValid(), utcOffset()
3135 void QDateTime::setUtcOffset(int seconds)
3139 /* The motivation to also setting d->spec is to ensure that the QDateTime
3140 * instance stay in well-defined states all the time, instead of that
3141 * we instruct the user to ensure it. */
3143 d->spec = QDateTimePrivate::UTC;
3145 d->spec = QDateTimePrivate::OffsetFromUTC;
3147 /* Even if seconds is 0 we assign it to utcOffset. */
3148 d->utcOffset = seconds;
3155 Returns the UTC offset in seconds. If the timeSpec() isn't
3156 Qt::OffsetFromUTC, 0 is returned. However, since 0 is a valid UTC
3157 offset the return value of this function cannot be used to determine
3158 whether a utcOffset() is used or is valid, timeSpec() must be
3161 Likewise, if this QDateTime() is invalid or if timeSpec() isn't
3162 Qt::OffsetFromUTC, 0 is returned.
3164 The UTC offset only applies if the timeSpec() is Qt::OffsetFromUTC.
3166 \sa isValid(), setUtcOffset()
3168 int QDateTime::utcOffset() const
3170 if(isValid() && d->spec == QDateTimePrivate::OffsetFromUTC)
3171 return d->utcOffset;
3176 #ifndef QT_NO_DATESTRING
3178 static int fromShortMonthName(const QString &monthName)
3180 // Assume that English monthnames are the default
3181 for (int i = 0; i < 12; ++i) {
3182 if (monthName == QLatin1String(qt_shortMonthNames[i]))
3185 // If English names can't be found, search the localized ones
3186 for (int i = 1; i <= 12; ++i) {
3187 if (monthName == QDate::shortMonthName(i))
3194 \fn QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
3196 Returns the QDateTime represented by the \a string, using the
3197 \a format given, or an invalid datetime if this is not possible.
3199 Note for Qt::TextDate: It is recommended that you use the
3200 English short month names (e.g. "Jan"). Although localized month
3201 names can also be used, they depend on the user's locale settings.
3203 QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
3212 Qt::TimeSpec ts = Qt::LocalTime;
3213 QDate date = QDate::fromString(tmp.left(10), Qt::ISODate);
3214 if (tmp.size() == 10)
3215 return QDateTime(date);
3219 // Recognize UTC specifications
3220 if (tmp.endsWith(QLatin1Char('Z'))) {
3225 // Recognize timezone specifications
3226 QRegExp rx(QLatin1String("[+-]"));
3227 if (tmp.contains(rx)) {
3228 int idx = tmp.indexOf(rx);
3229 QString tmp2 = tmp.mid(idx);
3230 tmp = tmp.left(idx);
3234 if ( tmp2.indexOf(QLatin1Char(':')) == 3 )
3236 const int tzhour(tmp2.mid(ntzhour, 2).toInt(&ok));
3237 const int tzminute(tmp2.mid(ntzminute, 2).toInt(&ok));
3238 QTime tzt(tzhour, tzminute);
3239 int utcOffset = (tzt.hour() * 60 + tzt.minute()) * 60;
3240 if ( utcOffset != 0 ) {
3241 ts = Qt::OffsetFromUTC;
3242 QDateTime dt(date, QTime::fromString(tmp, Qt::ISODate), ts);
3243 dt.setUtcOffset( utcOffset * (tmp2.startsWith(QLatin1Char('-')) ? -1 : 1) );
3248 QTime time(QTime::fromString(tmp, Qt::ISODate));
3249 if (!time.isValid() && tmp == QString::fromLatin1("24:00:00")) {
3250 // ISO 8601 (section 4.2.3) says that 24:00 is equivalent to 00:00 the next day.
3251 date = date.addDays(1);
3252 // Don't need to correct time since QDateTime constructor will do it for us.
3255 return QDateTime(date, time, ts);
3257 case Qt::SystemLocaleDate:
3258 case Qt::SystemLocaleShortDate:
3259 case Qt::SystemLocaleLongDate:
3260 return fromString(s, QLocale::system().dateTimeFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
3261 : QLocale::ShortFormat));
3262 case Qt::LocaleDate:
3263 case Qt::DefaultLocaleShortDate:
3264 case Qt::DefaultLocaleLongDate:
3265 return fromString(s, QLocale().dateTimeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
3266 : QLocale::ShortFormat));
3267 #if !defined(QT_NO_TEXTDATE)
3268 case Qt::TextDate: {
3269 QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts);
3271 if ((parts.count() < 5) || (parts.count() > 6)) {
3275 // Accept "Sun Dec 1 13:02:00 1974" and "Sun 1. Dec 13:02:00 1974"
3276 int month = -1, day = -1;
3279 month = fromShortMonthName(parts.at(1));
3281 day = parts.at(2).toInt(&ok);
3286 if (month == -1 || day == -1) {
3287 // first variant failed, lets try the other
3288 month = fromShortMonthName(parts.at(2));
3290 QString dayStr = parts.at(1);
3291 if (dayStr.endsWith(QLatin1Char('.'))) {
3293 day = dayStr.toInt(&ok);
3302 if (month == -1 || day == -1) {
3303 // both variants failed, give up
3308 QStringList timeParts = parts.at(3).split(QLatin1Char(':'));
3309 if ((timeParts.count() == 3) || (timeParts.count() == 2)) {
3310 year = parts.at(4).toInt(&ok);
3314 timeParts = parts.at(4).split(QLatin1Char(':'));
3315 if ((timeParts.count() != 3) && (timeParts.count() != 2))
3317 year = parts.at(3).toInt(&ok);
3322 int hour = timeParts.at(0).toInt(&ok);
3327 int minute = timeParts.at(1).toInt(&ok);
3332 int second = (timeParts.count() > 2) ? timeParts.at(2).toInt(&ok) : 0;
3337 QDate date(year, month, day);
3338 QTime time(hour, minute, second);
3340 if (parts.count() == 5)
3341 return QDateTime(date, time, Qt::LocalTime);
3343 QString tz = parts.at(5);
3344 if (!tz.startsWith(QLatin1String("GMT"), Qt::CaseInsensitive))
3346 QDateTime dt(date, time, Qt::UTC);
3347 if (tz.length() > 3) {
3349 QChar sign = tz.at(3);
3350 if ((sign != QLatin1Char('+'))
3351 && (sign != QLatin1Char('-'))) {
3354 int tzhour = tz.mid(4, 2).toInt(&ok);
3357 int tzminute = tz.mid(6).toInt(&ok);
3360 tzoffset = (tzhour*60 + tzminute) * 60;
3361 if (sign == QLatin1Char('-'))
3362 tzoffset = -tzoffset;
3363 dt.setUtcOffset(tzoffset);
3365 return dt.toLocalTime();
3367 #endif //QT_NO_TEXTDATE
3374 \fn QDateTime::fromString(const QString &string, const QString &format)
3376 Returns the QDateTime represented by the \a string, using the \a
3377 format given, or an invalid datetime if the string cannot be parsed.
3379 These expressions may be used for the date part of the format string:
3382 \header \li Expression \li Output
3383 \row \li d \li the day as number without a leading zero (1 to 31)
3384 \row \li dd \li the day as number with a leading zero (01 to 31)
3386 \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
3387 Uses QDate::shortDayName().
3389 \li the long localized day name (e.g. 'Monday' to 'Sunday').
3390 Uses QDate::longDayName().
3391 \row \li M \li the month as number without a leading zero (1-12)
3392 \row \li MM \li the month as number with a leading zero (01-12)
3394 \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
3395 Uses QDate::shortMonthName().
3397 \li the long localized month name (e.g. 'January' to 'December').
3398 Uses QDate::longMonthName().
3399 \row \li yy \li the year as two digit number (00-99)
3400 \row \li yyyy \li the year as four digit number
3403 \note Unlike the other version of this function, day and month names must
3404 be given in the user's local language. It is only possible to use the English
3405 names if the user's language is English.
3407 These expressions may be used for the time part of the format string:
3410 \header \li Expression \li Output
3412 \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
3414 \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
3416 \li the hour without a leading zero (0 to 23, even with AM/PM display)
3418 \li the hour with a leading zero (00 to 23, even with AM/PM display)
3419 \row \li m \li the minute without a leading zero (0 to 59)
3420 \row \li mm \li the minute with a leading zero (00 to 59)
3421 \row \li s \li the second without a leading zero (0 to 59)
3422 \row \li ss \li the second with a leading zero (00 to 59)
3423 \row \li z \li the milliseconds without leading zeroes (0 to 999)
3424 \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
3426 \li interpret as an AM/PM time. \e AP must be either "AM" or "PM".
3428 \li Interpret as an AM/PM time. \e ap must be either "am" or "pm".
3431 All other input characters will be treated as text. Any sequence
3432 of characters that are enclosed in singlequotes will also be
3433 treated as text and not be used as an expression.
3435 \snippet code/src_corelib_tools_qdatetime.cpp 12
3437 If the format is not satisfied an invalid QDateTime is returned.
3438 The expressions that don't have leading zeroes (d, M, h, m, s, z) will be
3439 greedy. This means that they will use two digits even if this will
3440 put them outside the range and/or leave too few digits for other
3443 \snippet code/src_corelib_tools_qdatetime.cpp 13
3445 This could have meant 1 January 00:30.00 but the M will grab
3448 For any field that is not represented in the format the following
3452 \header \li Field \li Default value
3453 \row \li Year \li 1900
3454 \row \li Month \li 1 (January)
3457 \row \li Minute \li 0
3458 \row \li Second \li 0
3463 \snippet code/src_corelib_tools_qdatetime.cpp 14
3465 \sa QDate::fromString(), QTime::fromString(), QDate::toString(),
3466 QDateTime::toString(), QTime::toString()
3469 QDateTime QDateTime::fromString(const QString &string, const QString &format)
3471 #ifndef QT_BOOTSTRAPPED
3475 QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString);
3476 if (dt.parseFormat(format) && dt.fromString(string, &date, &time))
3477 return QDateTime(date, time);
3482 return QDateTime(QDate(), QTime(-1, -1, -1));
3485 #endif // QT_NO_DATESTRING
3487 \fn QDateTime QDateTime::toLocalTime() const
3489 Returns a datetime containing the date and time information in
3490 this datetime, but specified using the Qt::LocalTime definition.
3496 \fn QDateTime QDateTime::toUTC() const
3498 Returns a datetime containing the date and time information in
3499 this datetime, but specified using the Qt::UTC definition.
3506 void QDateTime::detach()
3511 /*****************************************************************************
3512 Date/time stream functions
3513 *****************************************************************************/
3515 #ifndef QT_NO_DATASTREAM
3519 Writes the \a date to stream \a out.
3521 \sa {Serializing Qt Data Types}
3524 QDataStream &operator<<(QDataStream &out, const QDate &date)
3526 if (out.version() < QDataStream::Qt_5_0)
3527 return out << quint32(date.jd);
3529 return out << qint64(date.jd);
3535 Reads a date from stream \a in into the \a date.
3537 \sa {Serializing Qt Data Types}
3540 QDataStream &operator>>(QDataStream &in, QDate &date)
3542 if (in.version() < QDataStream::Qt_5_0) {
3558 Writes \a time to stream \a out.
3560 \sa {Serializing Qt Data Types}
3563 QDataStream &operator<<(QDataStream &out, const QTime &time)
3565 return out << quint32(time.mds);
3571 Reads a time from stream \a in into the given \a time.
3573 \sa {Serializing Qt Data Types}
3576 QDataStream &operator>>(QDataStream &in, QTime &time)
3587 Writes \a dateTime to the \a out stream.
3589 \sa {Serializing Qt Data Types}
3591 QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime)
3593 out << dateTime.d->date << dateTime.d->time;
3594 if (out.version() >= 7)
3595 out << (qint8)dateTime.d->spec;
3602 Reads a datetime from the stream \a in into \a dateTime.
3604 \sa {Serializing Qt Data Types}
3607 QDataStream &operator>>(QDataStream &in, QDateTime &dateTime)
3611 qint8 ts = (qint8)QDateTimePrivate::LocalUnknown;
3612 in >> dateTime.d->date >> dateTime.d->time;
3613 if (in.version() >= 7)
3615 dateTime.d->spec = (QDateTimePrivate::Spec)ts;
3618 #endif // QT_NO_DATASTREAM
3622 // checks if there is an unqoted 'AP' or 'ap' in the string
3623 static bool hasUnquotedAP(const QString &f)
3625 const QLatin1Char quote('\'');
3626 bool inquote = false;
3627 const int max = f.size();
3628 for (int i=0; i<max; ++i) {
3629 if (f.at(i) == quote) {
3631 } else if (!inquote && f.at(i).toUpper() == QLatin1Char('A')) {
3638 #ifndef QT_NO_DATESTRING
3639 /*****************************************************************************
3640 Some static function used by QDate, QTime and QDateTime
3641 *****************************************************************************/
3643 // Replaces tokens by their value. See QDateTime::toString() for a list of valid tokens
3644 static QString getFmtString(const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = false)
3653 if (f.startsWith(QLatin1String("hh")) || f.startsWith(QLatin1String("HH"))) {
3654 const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
3655 if (hour12 && dt->hour() > 12)
3656 buf = QString::number(dt->hour() - 12).rightJustified(2, QLatin1Char('0'), true);
3657 else if (hour12 && dt->hour() == 0)
3658 buf = QLatin1String("12");
3660 buf = QString::number(dt->hour()).rightJustified(2, QLatin1Char('0'), true);
3662 } else if (f.at(0) == QLatin1Char('h') || f.at(0) == QLatin1Char('H')) {
3663 const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
3664 if (hour12 && dt->hour() > 12)
3665 buf = QString::number(dt->hour() - 12);
3666 else if (hour12 && dt->hour() == 0)
3667 buf = QLatin1String("12");
3669 buf = QString::number(dt->hour());
3671 } else if (f.startsWith(QLatin1String("mm"))) {
3672 buf = QString::number(dt->minute()).rightJustified(2, QLatin1Char('0'), true);
3674 } else if (f.at(0) == (QLatin1Char('m'))) {
3675 buf = QString::number(dt->minute());
3677 } else if (f.startsWith(QLatin1String("ss"))) {
3678 buf = QString::number(dt->second()).rightJustified(2, QLatin1Char('0'), true);
3680 } else if (f.at(0) == QLatin1Char('s')) {
3681 buf = QString::number(dt->second());
3682 } else if (f.startsWith(QLatin1String("zzz"))) {
3683 buf = QString::number(dt->msec()).rightJustified(3, QLatin1Char('0'), true);
3685 } else if (f.at(0) == QLatin1Char('z')) {
3686 buf = QString::number(dt->msec());
3688 } else if (f.at(0).toUpper() == QLatin1Char('A')) {
3689 const bool upper = f.at(0) == QLatin1Char('A');
3690 buf = dt->hour() < 12 ? QLatin1String("am") : QLatin1String("pm");
3692 buf = buf.toUpper();
3693 if (f.size() > 1 && f.at(1).toUpper() == QLatin1Char('P') &&
3694 f.at(0).isUpper() == f.at(1).isUpper()) {
3703 if (f.startsWith(QLatin1String("dddd"))) {
3704 buf = dd->longDayName(dd->dayOfWeek());
3706 } else if (f.startsWith(QLatin1String("ddd"))) {
3707 buf = dd->shortDayName(dd->dayOfWeek());
3709 } else if (f.startsWith(QLatin1String("dd"))) {
3710 buf = QString::number(dd->day()).rightJustified(2, QLatin1Char('0'), true);
3712 } else if (f.at(0) == QLatin1Char('d')) {
3713 buf = QString::number(dd->day());
3715 } else if (f.startsWith(QLatin1String("MMMM"))) {
3716 buf = dd->longMonthName(dd->month());
3718 } else if (f.startsWith(QLatin1String("MMM"))) {
3719 buf = dd->shortMonthName(dd->month());
3721 } else if (f.startsWith(QLatin1String("MM"))) {
3722 buf = QString::number(dd->month()).rightJustified(2, QLatin1Char('0'), true);
3724 } else if (f.at(0) == QLatin1Char('M')) {
3725 buf = QString::number(dd->month());
3727 } else if (f.startsWith(QLatin1String("yyyy"))) {
3728 const int year = dd->year();
3729 buf = QString::number(qAbs(year)).rightJustified(4, QLatin1Char('0'));
3734 buf.prepend(QLatin1Char('-'));
3738 } else if (f.startsWith(QLatin1String("yy"))) {
3739 buf = QString::number(dd->year()).right(2).rightJustified(2, QLatin1Char('0'));
3743 if (removed == 0 || removed >= f.size()) {
3747 return buf + getFmtString(f.mid(removed), dt, dd, am_pm);
3750 // Parses the format string and uses getFmtString to get the values for the tokens. Ret
3751 static QString fmtDateTime(const QString& f, const QTime* dt, const QDate* dd)
3753 const QLatin1Char quote('\'');
3756 if (dt && !dt->isValid())
3758 if (dd && !dd->isValid())
3761 const bool ap = hasUnquotedAP(f);
3765 QChar status(QLatin1Char('0'));
3767 for (int i = 0; i < (int)f.length(); ++i) {
3768 if (f.at(i) == quote) {
3769 if (status == quote) {
3770 if (i > 0 && f.at(i - 1) == quote)
3771 buf += QLatin1Char('\'');
3772 status = QLatin1Char('0');
3774 if (!frm.isEmpty()) {
3775 buf += getFmtString(frm, dt, dd, ap);
3780 } else if (status == quote) {
3782 } else if (f.at(i) == status) {
3783 if ((ap) && ((f.at(i) == QLatin1Char('P')) || (f.at(i) == QLatin1Char('p'))))
3784 status = QLatin1Char('0');
3787 buf += getFmtString(frm, dt, dd, ap);
3789 if ((f.at(i) == QLatin1Char('h')) || (f.at(i) == QLatin1Char('m'))
3790 || (f.at(i) == QLatin1Char('H'))
3791 || (f.at(i) == QLatin1Char('s')) || (f.at(i) == QLatin1Char('z'))) {
3794 } else if ((f.at(i) == QLatin1Char('d')) || (f.at(i) == QLatin1Char('M')) || (f.at(i) == QLatin1Char('y'))) {
3797 } else if ((ap) && (f.at(i) == QLatin1Char('A'))) {
3798 status = QLatin1Char('P');
3800 } else if((ap) && (f.at(i) == QLatin1Char('a'))) {
3801 status = QLatin1Char('p');
3805 status = QLatin1Char('0');
3810 buf += getFmtString(frm, dt, dd, ap);
3814 #endif // QT_NO_DATESTRING
3817 static const int LowerYear = 1980;
3819 static const int LowerYear = 1970;
3821 static const int UpperYear = 2037;
3823 static QDate adjustDate(QDate date)
3825 QDate lowerLimit(LowerYear, 1, 2);
3826 QDate upperLimit(UpperYear, 12, 30);
3828 if (date > lowerLimit && date < upperLimit)
3831 int month = date.month();
3832 int day = date.day();
3834 // neither 1970 nor 2037 are leap years, so make sure date isn't Feb 29
3835 if (month == 2 && day == 29)
3838 if (date < lowerLimit)
3839 date.setDate(LowerYear, month, day);
3841 date.setDate(UpperYear, month, day);
3846 static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time)
3848 QDate fakeDate = adjustDate(date);
3850 // won't overflow because of fakeDate
3851 time_t secsSince1Jan1970UTC = toMSecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime(0, 0, 0).msecsTo(time)) / 1000;
3854 #if defined(Q_OS_WINCE)
3856 FILETIME utcTime = time_tToFt(secsSince1Jan1970UTC);
3857 FILETIME resultTime;
3858 FileTimeToLocalFileTime(&utcTime , &resultTime);
3860 FileTimeToSystemTime(&resultTime , &sysTime);
3862 res.tm_sec = sysTime.wSecond;
3863 res.tm_min = sysTime.wMinute;
3864 res.tm_hour = sysTime.wHour;
3865 res.tm_mday = sysTime.wDay;
3866 res.tm_mon = sysTime.wMonth - 1;
3867 res.tm_year = sysTime.wYear - 1900;
3869 #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3870 // use the reentrant version of localtime() where available
3873 brokenDown = localtime_r(&secsSince1Jan1970UTC, &res);
3874 #elif defined(_MSC_VER) && _MSC_VER >= 1400
3876 if (!_localtime64_s(&res, &secsSince1Jan1970UTC))
3879 brokenDown = localtime(&secsSince1Jan1970UTC);
3882 date = QDate(1970, 1, 1);
3884 return QDateTimePrivate::LocalUnknown;
3886 int deltaDays = fakeDate.daysTo(date);
3887 date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
3888 time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());
3889 date = date.addDays(deltaDays);
3890 if (brokenDown->tm_isdst > 0)
3891 return QDateTimePrivate::LocalDST;
3892 else if (brokenDown->tm_isdst < 0)
3893 return QDateTimePrivate::LocalUnknown;
3895 return QDateTimePrivate::LocalStandard;
3899 static void localToUtc(QDate &date, QTime &time, int isdst)
3901 if (!date.isValid())
3904 QDate fakeDate = adjustDate(date);
3907 localTM.tm_sec = time.second();
3908 localTM.tm_min = time.minute();
3909 localTM.tm_hour = time.hour();
3910 localTM.tm_mday = fakeDate.day();
3911 localTM.tm_mon = fakeDate.month() - 1;
3912 localTM.tm_year = fakeDate.year() - 1900;
3913 localTM.tm_isdst = (int)isdst;
3914 #if defined(Q_OS_WINCE)
3915 time_t secsSince1Jan1970UTC = (toMSecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime().msecsTo(time)) / 1000);
3917 #if defined(Q_OS_WIN)
3920 time_t secsSince1Jan1970UTC = mktime(&localTM);
3923 #if defined(Q_OS_WINCE)
3925 FILETIME localTime = time_tToFt(secsSince1Jan1970UTC);
3927 FileTimeToSystemTime(&localTime, &sysTime);
3928 FILETIME resultTime;
3929 LocalFileTimeToFileTime(&localTime , &resultTime);
3930 FileTimeToSystemTime(&resultTime , &sysTime);
3931 res.tm_sec = sysTime.wSecond;
3932 res.tm_min = sysTime.wMinute;
3933 res.tm_hour = sysTime.wHour;
3934 res.tm_mday = sysTime.wDay;
3935 res.tm_mon = sysTime.wMonth - 1;
3936 res.tm_year = sysTime.wYear - 1900;
3937 res.tm_isdst = (int)isdst;
3939 #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3940 // use the reentrant version of gmtime() where available
3942 brokenDown = gmtime_r(&secsSince1Jan1970UTC, &res);
3943 #elif defined(_MSC_VER) && _MSC_VER >= 1400
3945 if (!_gmtime64_s(&res, &secsSince1Jan1970UTC))
3948 brokenDown = gmtime(&secsSince1Jan1970UTC);
3949 #endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
3951 date = QDate(1970, 1, 1);
3954 int deltaDays = fakeDate.daysTo(date);
3955 date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
3956 time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());
3957 date = date.addDays(deltaDays);
3961 QDateTimePrivate::Spec QDateTimePrivate::getLocal(QDate &outDate, QTime &outTime) const
3965 if (spec == QDateTimePrivate::UTC)
3966 return utcToLocal(outDate, outTime);
3970 void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const
3974 const bool isOffset = spec == QDateTimePrivate::OffsetFromUTC;
3976 if (spec != QDateTimePrivate::UTC && !isOffset)
3977 localToUtc(outDate, outTime, (int)spec);
3980 addMSecs(outDate, outTime, -(qint64(utcOffset) * 1000));
3983 #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
3984 QDebug operator<<(QDebug dbg, const QDate &date)
3986 dbg.nospace() << "QDate(" << date.toString() << ')';
3990 QDebug operator<<(QDebug dbg, const QTime &time)
3992 dbg.nospace() << "QTime(" << time.toString() << ')';
3996 QDebug operator<<(QDebug dbg, const QDateTime &date)
3998 dbg.nospace() << "QDateTime(" << date.toString() << ')';
4003 #ifndef QT_BOOTSTRAPPED
4007 Gets the digit from a datetime. E.g.
4009 QDateTime var(QDate(2004, 02, 02));
4010 int digit = getDigit(var, Year);
4014 int QDateTimeParser::getDigit(const QDateTime &t, int index) const
4016 if (index < 0 || index >= sectionNodes.size()) {
4017 #ifndef QT_NO_DATESTRING
4018 qWarning("QDateTimeParser::getDigit() Internal error (%s %d)",
4019 qPrintable(t.toString()), index);
4021 qWarning("QDateTimeParser::getDigit() Internal error (%d)", index);
4025 const SectionNode &node = sectionNodes.at(index);
4026 switch (node.type) {
4027 case Hour24Section: case Hour12Section: return t.time().hour();
4028 case MinuteSection: return t.time().minute();
4029 case SecondSection: return t.time().second();
4030 case MSecSection: return t.time().msec();
4031 case YearSection2Digits:
4032 case YearSection: return t.date().year();
4033 case MonthSection: return t.date().month();
4034 case DaySection: return t.date().day();
4035 case DayOfWeekSection: return t.date().day();
4036 case AmPmSection: return t.time().hour() > 11 ? 1 : 0;
4041 #ifndef QT_NO_DATESTRING
4042 qWarning("QDateTimeParser::getDigit() Internal error 2 (%s %d)",
4043 qPrintable(t.toString()), index);
4045 qWarning("QDateTimeParser::getDigit() Internal error 2 (%d)", index);
4052 Sets a digit in a datetime. E.g.
4054 QDateTime var(QDate(2004, 02, 02));
4055 int digit = getDigit(var, Year);
4057 setDigit(&var, Year, 2005);
4058 digit = getDigit(var, Year);
4062 bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
4064 if (index < 0 || index >= sectionNodes.size()) {
4065 #ifndef QT_NO_DATESTRING
4066 qWarning("QDateTimeParser::setDigit() Internal error (%s %d %d)",
4067 qPrintable(v.toString()), index, newVal);
4069 qWarning("QDateTimeParser::setDigit() Internal error (%d %d)", index, newVal);
4073 const SectionNode &node = sectionNodes.at(index);
4075 int year, month, day, hour, minute, second, msec;
4076 year = v.date().year();
4077 month = v.date().month();
4078 day = v.date().day();
4079 hour = v.time().hour();
4080 minute = v.time().minute();
4081 second = v.time().second();
4082 msec = v.time().msec();
4084 switch (node.type) {
4085 case Hour24Section: case Hour12Section: hour = newVal; break;
4086 case MinuteSection: minute = newVal; break;
4087 case SecondSection: second = newVal; break;
4088 case MSecSection: msec = newVal; break;
4089 case YearSection2Digits:
4090 case YearSection: year = newVal; break;
4091 case MonthSection: month = newVal; break;
4093 case DayOfWeekSection:
4095 // have to keep legacy behavior. setting the
4096 // date to 32 should return false. Setting it
4097 // to 31 for february should return true
4102 case AmPmSection: hour = (newVal == 0 ? hour % 12 : (hour % 12) + 12); break;
4104 qWarning("QDateTimeParser::setDigit() Internal error (%s)",
4105 qPrintable(sectionName(node.type)));
4109 if (!(node.type & (DaySection|DayOfWeekSection))) {
4110 if (day < cachedDay)
4112 const int max = QDate(year, month, 1).daysInMonth();
4117 if (QDate::isValid(year, month, day) && QTime::isValid(hour, minute, second, msec)) {
4118 v = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);
4129 Returns the absolute maximum for a section
4132 int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
4134 const SectionNode &sn = sectionNode(s);
4137 case Hour12Section: return 23; // this is special-cased in
4138 // parseSection. We want it to be
4139 // 23 for the stepBy case.
4141 case SecondSection: return 59;
4142 case MSecSection: return 999;
4143 case YearSection2Digits:
4144 case YearSection: return 9999; // sectionMaxSize will prevent
4145 // people from typing in a larger
4146 // number in count == 2 sections.
4147 // stepBy() will work on real years anyway
4148 case MonthSection: return 12;
4150 case DayOfWeekSection: return cur.isValid() ? cur.date().daysInMonth() : 31;
4151 case AmPmSection: return 1;
4154 qWarning("QDateTimeParser::absoluteMax() Internal error (%s)",
4155 qPrintable(sectionName(sn.type)));
4162 Returns the absolute minimum for a section
4165 int QDateTimeParser::absoluteMin(int s) const
4167 const SectionNode &sn = sectionNode(s);
4174 case YearSection2Digits:
4175 case YearSection: return 0;
4178 case DayOfWeekSection: return 1;
4179 case AmPmSection: return 0;
4182 qWarning("QDateTimeParser::absoluteMin() Internal error (%s, %0x)",
4183 qPrintable(sectionName(sn.type)), sn.type);
4190 Returns the sectionNode for the Section \a s.
4193 const QDateTimeParser::SectionNode &QDateTimeParser::sectionNode(int sectionIndex) const
4195 if (sectionIndex < 0) {
4196 switch (sectionIndex) {
4197 case FirstSectionIndex:
4199 case LastSectionIndex:
4201 case NoSectionIndex:
4204 } else if (sectionIndex < sectionNodes.size()) {
4205 return sectionNodes.at(sectionIndex);
4208 qWarning("QDateTimeParser::sectionNode() Internal error (%d)",
4213 QDateTimeParser::Section QDateTimeParser::sectionType(int sectionIndex) const
4215 return sectionNode(sectionIndex).type;
4222 Returns the starting position for section \a s.
4225 int QDateTimeParser::sectionPos(int sectionIndex) const
4227 return sectionPos(sectionNode(sectionIndex));
4230 int QDateTimeParser::sectionPos(const SectionNode &sn) const
4233 case FirstSection: return 0;
4234 case LastSection: return displayText().size() - 1;
4238 qWarning("QDateTimeParser::sectionPos Internal error (%s)", qPrintable(sectionName(sn.type)));
4246 \internal helper function for parseFormat. removes quotes that are
4247 not escaped and removes the escaping on those that are escaped
4251 static QString unquote(const QString &str)
4253 const QChar quote(QLatin1Char('\''));
4254 const QChar slash(QLatin1Char('\\'));
4255 const QChar zero(QLatin1Char('0'));
4258 const int max = str.size();
4259 for (int i=0; i<max; ++i) {
4260 if (str.at(i) == quote) {
4261 if (status != quote) {
4263 } else if (!ret.isEmpty() && str.at(i - 1) == slash) {
4264 ret[ret.size() - 1] = quote;
4277 Parses the format \a newFormat. If successful, returns true and
4278 sets up the format. Else keeps the old format and returns false.
4282 static inline int countRepeat(const QString &str, int index, int maxCount)
4285 const QChar ch(str.at(index));
4286 const int max = qMin(index + maxCount, str.size());
4287 while (index + count < max && str.at(index + count) == ch) {
4293 static inline void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote)
4295 QString str(string.mid(from, size));
4296 if (lastQuote >= from)
4302 bool QDateTimeParser::parseFormat(const QString &newFormat)
4304 const QLatin1Char quote('\'');
4305 const QLatin1Char slash('\\');
4306 const QLatin1Char zero('0');
4307 if (newFormat == displayFormat && !newFormat.isEmpty()) {
4311 QDTPDEBUGN("parseFormat: %s", newFormat.toLatin1().constData());
4313 QVector<SectionNode> newSectionNodes;
4314 Sections newDisplay = 0;
4315 QStringList newSeparators;
4319 const int max = newFormat.size();
4321 for (i = 0; i<max; ++i) {
4322 if (newFormat.at(i) == quote) {
4325 if (status != quote) {
4327 } else if (newFormat.at(i - 1) != slash) {
4330 } else if (status != quote) {
4331 const char sect = newFormat.at(i).toLatin1();
4335 if (parserType != QVariant::Date) {
4336 const Section hour = (sect == 'h') ? Hour12Section : Hour24Section;
4337 const SectionNode sn = { hour, i - add, countRepeat(newFormat, i, 2) };
4338 newSectionNodes.append(sn);
4339 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4346 if (parserType != QVariant::Date) {
4347 const SectionNode sn = { MinuteSection, i - add, countRepeat(newFormat, i, 2) };
4348 newSectionNodes.append(sn);
4349 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4352 newDisplay |= MinuteSection;
4356 if (parserType != QVariant::Date) {
4357 const SectionNode sn = { SecondSection, i - add, countRepeat(newFormat, i, 2) };
4358 newSectionNodes.append(sn);
4359 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4362 newDisplay |= SecondSection;
4367 if (parserType != QVariant::Date) {
4368 const SectionNode sn = { MSecSection, i - add, countRepeat(newFormat, i, 3) < 3 ? 1 : 3 };
4369 newSectionNodes.append(sn);
4370 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4373 newDisplay |= MSecSection;
4378 if (parserType != QVariant::Date) {
4379 const bool cap = (sect == 'A');
4380 const SectionNode sn = { AmPmSection, i - add, (cap ? 1 : 0) };
4381 newSectionNodes.append(sn);
4382 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4383 newDisplay |= AmPmSection;
4384 if (i + 1 < newFormat.size()
4385 && newFormat.at(i+1) == (cap ? QLatin1Char('P') : QLatin1Char('p'))) {
4392 if (parserType != QVariant::Time) {
4393 const int repeat = countRepeat(newFormat, i, 4);
4395 const SectionNode sn = { repeat == 4 ? YearSection : YearSection2Digits,
4396 i - add, repeat == 4 ? 4 : 2 };
4397 newSectionNodes.append(sn);
4398 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4401 newDisplay |= sn.type;
4406 if (parserType != QVariant::Time) {
4407 const SectionNode sn = { MonthSection, i - add, countRepeat(newFormat, i, 4) };
4408 newSectionNodes.append(sn);
4409 newSeparators.append(unquote(newFormat.mid(index, i - index)));
4412 newDisplay |= MonthSection;
4416 if (parserType != QVariant::Time) {
4417 const int repeat = countRepeat(newFormat, i, 4);
4418 const SectionNode sn = { repeat >= 3 ? DayOfWeekSection : DaySection, i - add, repeat };
4419 newSectionNodes.append(sn);
4420 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4423 newDisplay |= sn.type;
4432 if (newSectionNodes.isEmpty() && context == DateTimeEdit) {
4436 if ((newDisplay & (AmPmSection|Hour12Section)) == Hour12Section) {
4437 const int max = newSectionNodes.size();
4438 for (int i=0; i<max; ++i) {
4439 SectionNode &node = newSectionNodes[i];
4440 if (node.type == Hour12Section)
4441 node.type = Hour24Section;
4445 if (index < newFormat.size()) {
4446 appendSeparator(&newSeparators, newFormat, index, index - max, lastQuote);
4448 newSeparators.append(QString());
4451 displayFormat = newFormat;
4452 separators = newSeparators;
4453 sectionNodes = newSectionNodes;
4454 display = newDisplay;
4457 // for (int i=0; i<sectionNodes.size(); ++i) {
4458 // QDTPDEBUG << sectionName(sectionNodes.at(i).type) << sectionNodes.at(i).count;
4461 QDTPDEBUG << newFormat << displayFormat;
4462 QDTPDEBUGN("separators:\n'%s'", separators.join(QLatin1String("\n")).toLatin1().constData());
4470 Returns the size of section \a s.
4473 int QDateTimeParser::sectionSize(int sectionIndex) const
4475 if (sectionIndex < 0)
4478 if (sectionIndex >= sectionNodes.size()) {
4479 qWarning("QDateTimeParser::sectionSize Internal error (%d)", sectionIndex);
4482 if (sectionIndex == sectionNodes.size() - 1) {
4483 return displayText().size() - sectionPos(sectionIndex) - separators.last().size();
4485 return sectionPos(sectionIndex + 1) - sectionPos(sectionIndex)
4486 - separators.at(sectionIndex + 1).size();
4491 int QDateTimeParser::sectionMaxSize(Section s, int count) const
4493 #ifndef QT_NO_TEXTDATE
4500 case LastSection: return 0;
4503 const int lowerMax = qMin(getAmPmText(AmText, LowerCase).size(),
4504 getAmPmText(PmText, LowerCase).size());
4505 const int upperMax = qMin(getAmPmText(AmText, UpperCase).size(),
4506 getAmPmText(PmText, UpperCase).size());
4507 return qMin(4, qMin(lowerMax, upperMax));
4514 case DaySection: return 2;
4515 case DayOfWeekSection:
4516 #ifdef QT_NO_TEXTDATE
4526 #ifdef QT_NO_TEXTDATE
4531 const QLocale l = locale();
4532 for (int i=1; i<=mcount; ++i) {
4533 const QString str = (s == MonthSection
4534 ? l.monthName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat)
4535 : l.dayName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat));
4536 ret = qMax(str.size(), ret);
4541 case MSecSection: return 3;
4542 case YearSection: return 4;
4543 case YearSection2Digits: return 2;
4545 case CalendarPopupSection:
4547 case TimeSectionMask:
4548 case DateSectionMask:
4549 qWarning("QDateTimeParser::sectionMaxSize: Invalid section %s",
4550 sectionName(s).toLatin1().constData());
4552 case NoSectionIndex:
4553 case FirstSectionIndex:
4554 case LastSectionIndex:
4555 case CalendarPopupIndex:
4556 // these cases can't happen
4563 int QDateTimeParser::sectionMaxSize(int index) const
4565 const SectionNode &sn = sectionNode(index);
4566 return sectionMaxSize(sn.type, sn.count);
4572 Returns the text of section \a s. This function operates on the
4573 arg text rather than edit->text().
4577 QString QDateTimeParser::sectionText(const QString &text, int sectionIndex, int index) const
4579 const SectionNode &sn = sectionNode(sectionIndex);
4581 case NoSectionIndex:
4582 case FirstSectionIndex:
4583 case LastSectionIndex:
4588 return text.mid(index, sectionSize(sectionIndex));
4591 QString QDateTimeParser::sectionText(int sectionIndex) const
4593 const SectionNode &sn = sectionNode(sectionIndex);
4595 case NoSectionIndex:
4596 case FirstSectionIndex:
4597 case LastSectionIndex:
4602 return displayText().mid(sn.pos, sectionSize(sectionIndex));
4606 #ifndef QT_NO_TEXTDATE
4608 \internal:skipToNextSection
4610 Parses the part of \a text that corresponds to \a s and returns
4611 the value of that field. Sets *stateptr to the right state if
4615 int QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex,
4616 QString &text, int &cursorPosition, int index,
4617 State &state, int *usedptr) const
4621 const SectionNode &sn = sectionNode(sectionIndex);
4622 if ((sn.type & Internal) == Internal) {
4623 qWarning("QDateTimeParser::parseSection Internal error (%s %d)",
4624 qPrintable(sectionName(sn.type)), sectionIndex);
4628 const int sectionmaxsize = sectionMaxSize(sectionIndex);
4629 QString sectiontext = text.mid(index, sectionmaxsize);
4630 int sectiontextSize = sectiontext.size();
4632 QDTPDEBUG << "sectionValue for" << sectionName(sn.type)
4633 << "with text" << text << "and st" << sectiontext
4634 << text.mid(index, sectionmaxsize)
4640 const int ampm = findAmPm(sectiontext, sectionIndex, &used);
4642 case AM: // sectiontext == AM
4643 case PM: // sectiontext == PM
4647 case PossibleAM: // sectiontext => AM
4648 case PossiblePM: // sectiontext => PM
4650 state = Intermediate;
4652 case PossibleBoth: // sectiontext => AM|PM
4654 state = Intermediate;
4658 QDTPDEBUG << "invalid because findAmPm(" << sectiontext << ") returned -1";
4661 QDTPDEBUGN("This should never happen (findAmPm returned %d)", ampm);
4664 if (state != Invalid) {
4666 text.replace(index, used, sectiontext.left(used));
4670 case DayOfWeekSection:
4671 if (sn.count >= 3) {
4672 if (sn.type == MonthSection) {
4674 const QDate minDate = getMinimum().date();
4675 if (currentValue.date().year() == minDate.year()) {
4676 min = minDate.month();
4678 num = findMonth(sectiontext.toLower(), min, sectionIndex, §iontext, &used);
4680 num = findDay(sectiontext.toLower(), 1, sectionIndex, §iontext, &used);
4684 state = (used == sectiontext.size() ? Acceptable : Intermediate);
4686 text.replace(index, used, sectiontext.left(used));
4688 state = Intermediate;
4694 case YearSection2Digits:
4700 if (sectiontextSize == 0) {
4703 state = Intermediate;
4705 const int absMax = absoluteMax(sectionIndex);
4711 QString digitsStr(sectiontext);
4712 for (int i = 0; i < sectiontextSize; ++i) {
4713 if (digitsStr.at(i).isSpace()) {
4714 sectiontextSize = i;
4719 const int max = qMin(sectionmaxsize, sectiontextSize);
4720 for (int digits = max; digits >= 1; --digits) {
4721 digitsStr.truncate(digits);
4722 int tmp = (int)loc.toUInt(digitsStr, &ok);
4723 if (ok && sn.type == Hour12Section) {
4727 } else if (tmp == 12) {
4731 if (ok && tmp <= absMax) {
4732 QDTPDEBUG << sectiontext.left(digits) << tmp << digits;
4740 QChar first(sectiontext.at(0));
4741 if (separators.at(sectionIndex + 1).startsWith(first)) {
4743 state = Intermediate;
4746 QDTPDEBUG << "invalid because" << sectiontext << "can't become a uint" << last << ok;
4750 const FieldInfo fi = fieldInfo(sectionIndex);
4751 const bool done = (used == sectionmaxsize);
4752 if (!done && fi & Fraction) { // typing 2 in a zzz field should be .200, not .002
4753 for (int i=used; i<sectionmaxsize; ++i) {
4757 const int absMin = absoluteMin(sectionIndex);
4759 state = done ? Invalid : Intermediate;
4761 QDTPDEBUG << "invalid because" << num << "is less than absoluteMin" << absMin;
4762 } else if (num > absMax) {
4763 state = Intermediate;
4764 } else if (!done && (fi & (FixedWidth|Numeric)) == (FixedWidth|Numeric)) {
4765 if (skipToNextSection(sectionIndex, currentValue, digitsStr)) {
4767 const int missingZeroes = sectionmaxsize - digitsStr.size();
4768 text.insert(index, QString().fill(QLatin1Char('0'), missingZeroes));
4769 used = sectionmaxsize;
4770 cursorPosition += missingZeroes;
4772 state = Intermediate;;
4781 qWarning("QDateTimeParser::parseSection Internal error (%s %d)",
4782 qPrintable(sectionName(sn.type)), sectionIndex);
4789 return (state != Invalid ? num : -1);
4791 #endif // QT_NO_TEXTDATE
4793 #ifndef QT_NO_DATESTRING
4798 QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPosition,
4799 const QDateTime ¤tValue, bool fixup) const
4801 const QDateTime minimum = getMinimum();
4802 const QDateTime maximum = getMaximum();
4804 State state = Acceptable;
4806 QDateTime newCurrentValue;
4808 bool conflicts = false;
4809 const int sectionNodesCount = sectionNodes.size();
4811 QDTPDEBUG << "parse" << input;
4813 int year, month, day, hour12, hour, minute, second, msec, ampm, dayofweek, year2digits;
4814 getDateFromJulianDay(currentValue.date().toJulianDay(), &year, &month, &day);
4815 year2digits = year % 100;
4816 hour = currentValue.time().hour();
4818 minute = currentValue.time().minute();
4819 second = currentValue.time().second();
4820 msec = currentValue.time().msec();
4821 dayofweek = currentValue.date().dayOfWeek();
4824 Sections isSet = NoSection;
4828 for (int index=0; state != Invalid && index<sectionNodesCount; ++index) {
4829 if (QStringRef(&input, pos, separators.at(index).size()) != separators.at(index)) {
4830 QDTPDEBUG << "invalid because" << input.mid(pos, separators.at(index).size())
4831 << "!=" << separators.at(index)
4832 << index << pos << currentSectionIndex;
4836 pos += separators.at(index).size();
4837 sectionNodes[index].pos = pos;
4839 const SectionNode sn = sectionNodes.at(index);
4842 num = parseSection(currentValue, index, input, cursorPosition, pos, tmpstate, &used);
4843 QDTPDEBUG << "sectionValue" << sectionName(sectionType(index)) << input
4844 << "pos" << pos << "used" << used << stateName(tmpstate);
4845 if (fixup && tmpstate == Intermediate && used < sn.count) {
4846 const FieldInfo fi = fieldInfo(index);
4847 if ((fi & (Numeric|FixedWidth)) == (Numeric|FixedWidth)) {
4848 const QString newText = QString::fromLatin1("%1").arg(num, sn.count, 10, QLatin1Char('0'));
4849 input.replace(pos, used, newText);
4853 pos += qMax(0, used);
4855 state = qMin<State>(state, tmpstate);
4856 if (state == Intermediate && context == FromString) {
4861 QDTPDEBUG << index << sectionName(sectionType(index)) << "is set to"
4862 << pos << "state is" << stateName(state);
4865 if (state != Invalid) {
4867 case Hour24Section: current = &hour; break;
4868 case Hour12Section: current = &hour12; break;
4869 case MinuteSection: current = &minute; break;
4870 case SecondSection: current = &second; break;
4871 case MSecSection: current = &msec; break;
4872 case YearSection: current = &year; break;
4873 case YearSection2Digits: current = &year2digits; break;
4874 case MonthSection: current = &month; break;
4875 case DayOfWeekSection: current = &dayofweek; break;
4876 case DaySection: current = &day; num = qMax<int>(1, num); break;
4877 case AmPmSection: current = &m; break;
4879 qWarning("QDateTimeParser::parse Internal error (%s)",
4880 qPrintable(sectionName(sn.type)));
4884 qWarning("QDateTimeParser::parse Internal error 2");
4887 if (isSet & sn.type && *current != num) {
4888 QDTPDEBUG << "CONFLICT " << sectionName(sn.type) << *current << num;
4890 if (index != currentSectionIndex || num == -1) {
4900 if (state != Invalid && QStringRef(&input, pos, input.size() - pos) != separators.last()) {
4901 QDTPDEBUG << "invalid because" << input.mid(pos)
4902 << "!=" << separators.last() << pos;
4906 if (state != Invalid) {
4907 if (parserType != QVariant::Time) {
4908 if (year % 100 != year2digits) {
4909 switch (isSet & (YearSection2Digits|YearSection)) {
4910 case YearSection2Digits:
4911 year = (year / 100) * 100;
4912 year += year2digits;
4914 case ((uint)YearSection2Digits|(uint)YearSection): {
4916 const SectionNode &sn = sectionNode(currentSectionIndex);
4917 if (sn.type == YearSection2Digits) {
4918 year = (year / 100) * 100;
4919 year += year2digits;
4927 const QDate date(year, month, day);
4928 const int diff = dayofweek - date.dayOfWeek();
4929 if (diff != 0 && state == Acceptable && isSet & DayOfWeekSection) {
4930 conflicts = isSet & DaySection;
4931 const SectionNode &sn = sectionNode(currentSectionIndex);
4932 if (sn.type == DayOfWeekSection || currentSectionIndex == -1) {
4933 // dayofweek should be preferred
4937 } else if (day > date.daysInMonth()) {
4940 QDTPDEBUG << year << month << day << dayofweek
4941 << diff << QDate(year, month, day).dayOfWeek();
4944 bool needfixday = false;
4945 if (sectionType(currentSectionIndex) & (DaySection|DayOfWeekSection)) {
4947 } else if (cachedDay > day) {
4952 if (!QDate::isValid(year, month, day)) {
4956 if (day > 28 && QDate::isValid(year, month, 1)) {
4961 if (context == FromString) {
4965 if (state == Acceptable && fixday) {
4966 day = qMin<int>(day, QDate(year, month, 1).daysInMonth());
4968 const QLocale loc = locale();
4969 for (int i=0; i<sectionNodesCount; ++i) {
4970 if (sectionType(i) & (DaySection|DayOfWeekSection)) {
4971 input.replace(sectionPos(i), sectionSize(i), loc.toString(day));
4975 state = qMin(Intermediate, state);
4980 if (parserType != QVariant::Date) {
4981 if (isSet & Hour12Section) {
4982 const bool hasHour = isSet & Hour24Section;
4985 ampm = (hour < 12 ? 0 : 1);
4987 ampm = 0; // no way to tell if this is am or pm so I assume am
4990 hour12 = (ampm == 0 ? hour12 % 12 : (hour12 % 12) + 12);
4993 } else if (hour != hour12) {
4996 } else if (ampm != -1) {
4997 if (!(isSet & (Hour24Section))) {
4998 hour = (12 * ampm); // special case. Only ap section
4999 } else if ((ampm == 0) != (hour < 12)) {
5006 newCurrentValue = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);
5007 QDTPDEBUG << year << month << day << hour << minute << second << msec;
5009 QDTPDEBUGN("'%s' => '%s'(%s)", input.toLatin1().constData(),
5010 newCurrentValue.toString(QLatin1String("yyyy/MM/dd hh:mm:ss.zzz")).toLatin1().constData(),
5011 stateName(state).toLatin1().constData());
5014 if (newCurrentValue.isValid()) {
5015 if (context != FromString && state != Invalid && newCurrentValue < minimum) {
5016 const QLatin1Char space(' ');
5017 if (newCurrentValue >= minimum)
5018 qWarning("QDateTimeParser::parse Internal error 3 (%s %s)",
5019 qPrintable(newCurrentValue.toString()), qPrintable(minimum.toString()));
5023 for (int i=0; i<sectionNodesCount && !done; ++i) {
5024 const SectionNode &sn = sectionNodes.at(i);
5025 QString t = sectionText(input, i, sn.pos).toLower();
5026 if ((t.size() < sectionMaxSize(i) && (((int)fieldInfo(i) & (FixedWidth|Numeric)) != Numeric))
5027 || t.contains(space)) {
5030 switch (findAmPm(t, i)) {
5042 case PossibleBoth: {
5043 const QDateTime copy(newCurrentValue.addSecs(12 * 60 * 60));
5044 if (copy >= minimum && copy <= maximum) {
5045 state = Intermediate;
5051 if (sn.count >= 3) {
5052 int tmp = newCurrentValue.date().month();
5053 // I know the first possible month makes the date too early
5054 while ((tmp = findMonth(t, tmp + 1, i)) != -1) {
5055 const QDateTime copy(newCurrentValue.addMonths(tmp - newCurrentValue.date().month()));
5056 if (copy >= minimum && copy <= maximum)
5057 break; // break out of while
5062 state = Intermediate;
5071 if (sn.type & TimeSectionMask) {
5072 if (newCurrentValue.daysTo(minimum) != 0) {
5075 toMin = newCurrentValue.time().msecsTo(minimum.time());
5076 if (newCurrentValue.daysTo(maximum) > 0) {
5077 toMax = -1; // can't get to max
5079 toMax = newCurrentValue.time().msecsTo(maximum.time());
5082 toMin = newCurrentValue.daysTo(minimum);
5083 toMax = newCurrentValue.daysTo(maximum);
5085 const int maxChange = QDateTimeParser::maxChange(i);
5086 if (toMin > maxChange) {
5087 QDTPDEBUG << "invalid because toMin > maxChange" << toMin
5088 << maxChange << t << newCurrentValue << minimum;
5092 } else if (toMax > maxChange) {
5093 toMax = -1; // can't get to max
5096 const int min = getDigit(minimum, i);
5098 qWarning("QDateTimeParser::parse Internal error 4 (%s)",
5099 qPrintable(sectionName(sn.type)));
5105 int max = toMax != -1 ? getDigit(maximum, i) : absoluteMax(i, newCurrentValue);
5106 int pos = cursorPosition - sn.pos;
5107 if (pos < 0 || pos >= t.size())
5109 if (!potentialValue(t.simplified(), min, max, i, newCurrentValue, pos)) {
5110 QDTPDEBUG << "invalid because potentialValue(" << t.simplified() << min << max
5111 << sectionName(sn.type) << "returned" << toMax << toMin << pos;
5116 state = Intermediate;
5123 if (context == FromString) {
5125 Q_ASSERT(getMaximum().date().toJulianDay() == 4642999);
5126 if (newCurrentValue.date().toJulianDay() > 4642999)
5129 if (newCurrentValue > getMaximum())
5133 QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << getMinimum() << getMaximum();
5139 node.conflicts = conflicts;
5140 node.value = newCurrentValue.toTimeSpec(spec);
5144 #endif // QT_NO_DATESTRING
5146 #ifndef QT_NO_TEXTDATE
5148 \internal finds the first possible monthname that \a str1 can
5149 match. Starting from \a index; str should already by lowered
5152 int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionIndex,
5153 QString *usedMonth, int *used) const
5157 if (!str1.isEmpty()) {
5158 const SectionNode &sn = sectionNode(sectionIndex);
5159 if (sn.type != MonthSection) {
5160 qWarning("QDateTimeParser::findMonth Internal error");
5164 QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
5165 QLocale l = locale();
5167 for (int month=startMonth; month<=12; ++month) {
5168 QString str2 = l.monthName(month, type).toLower();
5170 if (str1.startsWith(str2)) {
5172 QDTPDEBUG << "used is set to" << str2.size();
5173 *used = str2.size();
5176 *usedMonth = l.monthName(month, type);
5180 if (context == FromString)
5183 const int limit = qMin(str1.size(), str2.size());
5185 QDTPDEBUG << "limit is" << limit << str1 << str2;
5187 for (int i=0; i<limit; ++i) {
5188 if (str1.at(i) != str2.at(i)) {
5190 if (i > bestCount) {
5201 *usedMonth = l.monthName(month, type);
5205 if (usedMonth && bestMatch != -1)
5206 *usedMonth = l.monthName(bestMatch, type);
5209 QDTPDEBUG << "used is set to" << bestCount;
5215 int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex, QString *usedDay, int *used) const
5219 if (!str1.isEmpty()) {
5220 const SectionNode &sn = sectionNode(sectionIndex);
5221 if (!(sn.type & (DaySection|DayOfWeekSection))) {
5222 qWarning("QDateTimeParser::findDay Internal error");
5225 const QLocale l = locale();
5226 for (int day=startDay; day<=7; ++day) {
5227 const QString str2 = l.dayName(day, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
5229 if (str1.startsWith(str2.toLower())) {
5231 *used = str2.size();
5237 if (context == FromString)
5240 const int limit = qMin(str1.size(), str2.size());
5242 for (int i=0; i<limit; ++i) {
5243 if (str1.at(i) != str2.at(i) && !str1.at(i).isSpace()) {
5244 if (i > bestCount) {
5262 if (usedDay && bestMatch != -1) {
5263 *usedDay = l.dayName(bestMatch, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
5271 #endif // QT_NO_TEXTDATE
5277 0 if str == QDateTimeEdit::tr("AM")
5278 1 if str == QDateTimeEdit::tr("PM")
5279 2 if str can become QDateTimeEdit::tr("AM")
5280 3 if str can become QDateTimeEdit::tr("PM")
5281 4 if str can become QDateTimeEdit::tr("PM") and can become QDateTimeEdit::tr("AM")
5282 -1 can't become anything sensible
5286 int QDateTimeParser::findAmPm(QString &str, int index, int *used) const
5288 const SectionNode &s = sectionNode(index);
5289 if (s.type != AmPmSection) {
5290 qWarning("QDateTimeParser::findAmPm Internal error");
5295 if (str.trimmed().isEmpty()) {
5296 return PossibleBoth;
5298 const QLatin1Char space(' ');
5299 int size = sectionMaxSize(index);
5306 ampm[amindex] = getAmPmText(AmText, s.count == 1 ? UpperCase : LowerCase);
5307 ampm[pmindex] = getAmPmText(PmText, s.count == 1 ? UpperCase : LowerCase);
5308 for (int i=0; i<2; ++i)
5309 ampm[i].truncate(size);
5311 QDTPDEBUG << "findAmPm" << str << ampm[0] << ampm[1];
5313 if (str.indexOf(ampm[amindex], 0, Qt::CaseInsensitive) == 0) {
5314 str = ampm[amindex];
5316 } else if (str.indexOf(ampm[pmindex], 0, Qt::CaseInsensitive) == 0) {
5317 str = ampm[pmindex];
5319 } else if (context == FromString || (str.count(space) == 0 && str.size() >= size)) {
5322 size = qMin(size, str.size());
5324 bool broken[2] = {false, false};
5325 for (int i=0; i<size; ++i) {
5326 if (str.at(i) != space) {
5327 for (int j=0; j<2; ++j) {
5329 int index = ampm[j].indexOf(str.at(i));
5330 QDTPDEBUG << "looking for" << str.at(i)
5331 << "in" << ampm[j] << "and got" << index;
5333 if (str.at(i).category() == QChar::Letter_Uppercase) {
5334 index = ampm[j].indexOf(str.at(i).toLower());
5335 QDTPDEBUG << "trying with" << str.at(i).toLower()
5336 << "in" << ampm[j] << "and got" << index;
5337 } else if (str.at(i).category() == QChar::Letter_Lowercase) {
5338 index = ampm[j].indexOf(str.at(i).toUpper());
5339 QDTPDEBUG << "trying with" << str.at(i).toUpper()
5340 << "in" << ampm[j] << "and got" << index;
5344 if (broken[amindex] && broken[pmindex]) {
5345 QDTPDEBUG << str << "didn't make it";
5350 str[i] = ampm[j].at(index); // fix case
5353 ampm[j].remove(index, 1);
5358 if (!broken[pmindex] && !broken[amindex])
5359 return PossibleBoth;
5360 return (!broken[amindex] ? PossibleAM : PossiblePM);
5365 Max number of units that can be changed by this section.
5368 int QDateTimeParser::maxChange(int index) const
5370 const SectionNode &sn = sectionNode(index);
5372 // Time. unit is msec
5373 case MSecSection: return 999;
5374 case SecondSection: return 59 * 1000;
5375 case MinuteSection: return 59 * 60 * 1000;
5376 case Hour24Section: case Hour12Section: return 59 * 60 * 60 * 1000;
5378 // Date. unit is day
5379 case DayOfWeekSection: return 7;
5380 case DaySection: return 30;
5381 case MonthSection: return 365 - 31;
5382 case YearSection: return 9999 * 365;
5383 case YearSection2Digits: return 100 * 365;
5385 qWarning("QDateTimeParser::maxChange() Internal error (%s)",
5386 qPrintable(sectionName(sectionType(index))));
5392 QDateTimeParser::FieldInfo QDateTimeParser::fieldInfo(int index) const
5395 const SectionNode &sn = sectionNode(index);
5396 const Section s = sn.type;
5406 case YearSection2Digits:
5408 if (s != YearSection) {
5409 ret |= AllowPartial;
5411 if (sn.count != 1) {
5422 ret |= (Numeric|AllowPartial);
5426 case DayOfWeekSection:
5434 qWarning("QDateTimeParser::fieldInfo Internal error 2 (%d %s %d)",
5435 index, qPrintable(sectionName(sn.type)), sn.count);
5442 \internal Get a number that str can become which is between min
5443 and max or -1 if this is not possible.
5447 QString QDateTimeParser::sectionFormat(int index) const
5449 const SectionNode &sn = sectionNode(index);
5450 return sectionFormat(sn.type, sn.count);
5453 QString QDateTimeParser::sectionFormat(Section s, int count) const
5457 case AmPmSection: return count == 1 ? QLatin1String("AP") : QLatin1String("ap");
5458 case MSecSection: fillChar = QLatin1Char('z'); break;
5459 case SecondSection: fillChar = QLatin1Char('s'); break;
5460 case MinuteSection: fillChar = QLatin1Char('m'); break;
5461 case Hour24Section: fillChar = QLatin1Char('H'); break;
5462 case Hour12Section: fillChar = QLatin1Char('h'); break;
5463 case DayOfWeekSection:
5464 case DaySection: fillChar = QLatin1Char('d'); break;
5465 case MonthSection: fillChar = QLatin1Char('M'); break;
5466 case YearSection2Digits:
5467 case YearSection: fillChar = QLatin1Char('y'); break;
5469 qWarning("QDateTimeParser::sectionFormat Internal error (%s)",
5470 qPrintable(sectionName(s)));
5473 if (fillChar.isNull()) {
5474 qWarning("QDateTimeParser::sectionFormat Internal error 2");
5479 str.fill(fillChar, count);
5484 /*! \internal Returns true if str can be modified to represent a
5485 number that is within min and max.
5488 bool QDateTimeParser::potentialValue(const QString &str, int min, int max, int index,
5489 const QDateTime ¤tValue, int insert) const
5491 if (str.isEmpty()) {
5494 const int size = sectionMaxSize(index);
5495 int val = (int)locale().toUInt(str);
5496 const SectionNode &sn = sectionNode(index);
5497 if (sn.type == YearSection2Digits) {
5498 val += currentValue.date().year() - (currentValue.date().year() % 100);
5500 if (val >= min && val <= max && str.size() == size) {
5502 } else if (val > max) {
5504 } else if (str.size() == size && val < min) {
5508 const int len = size - str.size();
5509 for (int i=0; i<len; ++i) {
5510 for (int j=0; j<10; ++j) {
5511 if (potentialValue(str + QLatin1Char('0' + j), min, max, index, currentValue, insert)) {
5513 } else if (insert >= 0) {
5515 tmp.insert(insert, QLatin1Char('0' + j));
5516 if (potentialValue(tmp, min, max, index, currentValue, insert))
5525 bool QDateTimeParser::skipToNextSection(int index, const QDateTime ¤t, const QString &text) const
5527 Q_ASSERT(current >= getMinimum() && current <= getMaximum());
5529 const SectionNode &node = sectionNode(index);
5530 Q_ASSERT(text.size() < sectionMaxSize(index));
5532 const QDateTime maximum = getMaximum();
5533 const QDateTime minimum = getMinimum();
5534 QDateTime tmp = current;
5535 int min = absoluteMin(index);
5536 setDigit(tmp, index, min);
5537 if (tmp < minimum) {
5538 min = getDigit(minimum, index);
5541 int max = absoluteMax(index, current);
5542 setDigit(tmp, index, max);
5543 if (tmp > maximum) {
5544 max = getDigit(maximum, index);
5546 int pos = cursorPosition() - node.pos;
5547 if (pos < 0 || pos >= text.size())
5550 const bool potential = potentialValue(text, min, max, index, current, pos);
5553 /* If the value potentially can become another valid entry we
5554 * don't want to skip to the next. E.g. In a M field (month
5555 * without leading 0 if you type 1 we don't want to autoskip but
5556 * if you type 3 we do
5562 For debugging. Returns the name of the section \a s.
5565 QString QDateTimeParser::sectionName(int s) const
5568 case QDateTimeParser::AmPmSection: return QLatin1String("AmPmSection");
5569 case QDateTimeParser::DaySection: return QLatin1String("DaySection");
5570 case QDateTimeParser::DayOfWeekSection: return QLatin1String("DayOfWeekSection");
5571 case QDateTimeParser::Hour24Section: return QLatin1String("Hour24Section");
5572 case QDateTimeParser::Hour12Section: return QLatin1String("Hour12Section");
5573 case QDateTimeParser::MSecSection: return QLatin1String("MSecSection");
5574 case QDateTimeParser::MinuteSection: return QLatin1String("MinuteSection");
5575 case QDateTimeParser::MonthSection: return QLatin1String("MonthSection");
5576 case QDateTimeParser::SecondSection: return QLatin1String("SecondSection");
5577 case QDateTimeParser::YearSection: return QLatin1String("YearSection");
5578 case QDateTimeParser::YearSection2Digits: return QLatin1String("YearSection2Digits");
5579 case QDateTimeParser::NoSection: return QLatin1String("NoSection");
5580 case QDateTimeParser::FirstSection: return QLatin1String("FirstSection");
5581 case QDateTimeParser::LastSection: return QLatin1String("LastSection");
5582 default: return QLatin1String("Unknown section ") + QString::number(s);
5588 For debugging. Returns the name of the state \a s.
5591 QString QDateTimeParser::stateName(int s) const
5594 case Invalid: return QLatin1String("Invalid");
5595 case Intermediate: return QLatin1String("Intermediate");
5596 case Acceptable: return QLatin1String("Acceptable");
5597 default: return QLatin1String("Unknown state ") + QString::number(s);
5601 #ifndef QT_NO_DATESTRING
5602 bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) const
5604 QDateTime val(QDate(1900, 1, 1), QDATETIMEEDIT_TIME_MIN);
5607 const StateNode tmp = parse(text, copy, val, false);
5608 if (tmp.state != Acceptable || tmp.conflicts) {
5612 const QTime t = tmp.value.time();
5620 const QDate d = tmp.value.date();
5628 #endif // QT_NO_DATESTRING
5630 QDateTime QDateTimeParser::getMinimum() const
5632 return QDateTime(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN, spec);
5635 QDateTime QDateTimeParser::getMaximum() const
5637 return QDateTime(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX, spec);
5640 QString QDateTimeParser::getAmPmText(AmPm ap, Case cs) const
5643 return (cs == UpperCase ? QLatin1String("AM") : QLatin1String("am"));
5645 return (cs == UpperCase ? QLatin1String("PM") : QLatin1String("pm"));
5652 I give arg2 preference because arg1 is always a QDateTime.
5655 bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::SectionNode &s2)
5657 return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count);
5660 #endif // QT_BOOTSTRAPPED