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 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 doc/src/snippets/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 doc/src/snippets/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 doc/src/snippets/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 doc/src/snippets/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 doc/src/snippets/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(int 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 doc/src/snippets/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 const int second(s.mid(6, 2).toInt(&ok));
1809 const QString msec_s(QLatin1String("0.") + s.mid(9, 4));
1810 const float msec(msec_s.toFloat(&ok));
1812 return QTime(hour, minute, second, 0);
1813 return QTime(hour, minute, second, qMin(qRound(msec * 1000.0), 999));
1819 \fn QTime::fromString(const QString &string, const QString &format)
1821 Returns the QTime represented by the \a string, using the \a
1822 format given, or an invalid time if the string cannot be parsed.
1824 These expressions may be used for the format:
1827 \header \li Expression \li Output
1829 \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
1831 \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
1832 \row \li m \li the minute without a leading zero (0 to 59)
1833 \row \li mm \li the minute with a leading zero (00 to 59)
1834 \row \li s \li the second without a leading zero (0 to 59)
1835 \row \li ss \li the second with a leading zero (00 to 59)
1836 \row \li z \li the milliseconds without leading zeroes (0 to 999)
1837 \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
1839 \li interpret as an AM/PM time. \e AP must be either "AM" or "PM".
1841 \li Interpret as an AM/PM time. \e ap must be either "am" or "pm".
1844 All other input characters will be treated as text. Any sequence
1845 of characters that are enclosed in single quotes will also be
1846 treated as text and not be used as an expression.
1848 \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 6
1850 If the format is not satisfied an invalid QTime is returned.
1851 Expressions that do not expect leading zeroes to be given (h, m, s
1852 and z) are greedy. This means that they will use two digits even if
1853 this puts them outside the range of accepted values and leaves too
1854 few digits for other sections. For example, the following string
1855 could have meant 00:07:10, but the m will grab two digits, resulting
1858 \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 7
1860 Any field that is not represented in the format will be set to zero.
1863 \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 8
1865 \sa QDateTime::fromString() QDate::fromString() QDate::toString()
1866 QDateTime::toString() QTime::toString()
1869 QTime QTime::fromString(const QString &string, const QString &format)
1872 #ifndef QT_BOOTSTRAPPED
1873 QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
1874 if (dt.parseFormat(format))
1875 dt.fromString(string, 0, &time);
1883 #endif // QT_NO_DATESTRING
1889 Returns true if the specified time is valid; otherwise returns
1892 The time is valid if \a h is in the range 0 to 23, \a m and
1893 \a s are in the range 0 to 59, and \a ms is in the range 0 to 999.
1897 \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 9
1900 bool QTime::isValid(int h, int m, int s, int ms)
1902 return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
1907 Sets this time to the current time. This is practical for timing:
1909 \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 10
1911 \sa restart(), elapsed(), currentTime()
1916 *this = currentTime();
1920 Sets this time to the current time and returns the number of
1921 milliseconds that have elapsed since the last time start() or
1922 restart() was called.
1924 This function is guaranteed to be atomic and is thus very handy
1925 for repeated measurements. Call start() to start the first
1926 measurement, and restart() for each later measurement.
1928 Note that the counter wraps to zero 24 hours after the last call
1929 to start() or restart().
1931 \warning If the system's clock setting has been changed since the
1932 last time start() or restart() was called, the result is
1933 undefined. This can happen when daylight savings time is turned on
1936 \sa start(), elapsed(), currentTime()
1939 int QTime::restart()
1941 QTime t = currentTime();
1943 if (n < 0) // passed midnight
1950 Returns the number of milliseconds that have elapsed since the
1951 last time start() or restart() was called.
1953 Note that the counter wraps to zero 24 hours after the last call
1954 to start() or restart.
1956 Note that the accuracy depends on the accuracy of the underlying
1957 operating system; not all systems provide 1-millisecond accuracy.
1959 \warning If the system's clock setting has been changed since the
1960 last time start() or restart() was called, the result is
1961 undefined. This can happen when daylight savings time is turned on
1964 \sa start(), restart()
1967 int QTime::elapsed() const
1969 int n = msecsTo(currentTime());
1970 if (n < 0) // passed midnight
1976 /*****************************************************************************
1977 QDateTime member functions
1978 *****************************************************************************/
1983 \brief The QDateTime class provides date and time functions.
1986 A QDateTime object contains a calendar date and a clock time (a
1987 "datetime"). It is a combination of the QDate and QTime classes.
1988 It can read the current datetime from the system clock. It
1989 provides functions for comparing datetimes and for manipulating a
1990 datetime by adding a number of seconds, days, months, or years.
1992 A QDateTime object is typically created either by giving a date
1993 and time explicitly in the constructor, or by using the static
1994 function currentDateTime() that returns a QDateTime object set
1995 to the system clock's time. The date and time can be changed with
1996 setDate() and setTime(). A datetime can also be set using the
1997 setTime_t() function that takes a POSIX-standard "number of
1998 seconds since 00:00:00 on January 1, 1970" value. The fromString()
1999 function returns a QDateTime, given a string and a date format
2000 used to interpret the date within the string.
2002 The date() and time() functions provide access to the date and
2003 time parts of the datetime. The same information is provided in
2004 textual format by the toString() function.
2006 QDateTime provides a full set of operators to compare two
2007 QDateTime objects where smaller means earlier and larger means
2010 You can increment (or decrement) a datetime by a given number of
2011 milliseconds using addMSecs(), seconds using addSecs(), or days
2012 using addDays(). Similarly you can use addMonths() and addYears().
2013 The daysTo() function returns the number of days between two datetimes,
2014 secsTo() returns the number of seconds between two datetimes, and
2015 msecsTo() returns the number of milliseconds between two datetimes.
2017 QDateTime can store datetimes as \l{Qt::LocalTime}{local time} or
2018 as \l{Qt::UTC}{UTC}. QDateTime::currentDateTime() returns a
2019 QDateTime expressed as local time; use toUTC() to convert it to
2020 UTC. You can also use timeSpec() to find out if a QDateTime
2021 object stores a UTC time or a local time. Operations such as
2022 addSecs() and secsTo() are aware of daylight saving time (DST).
2024 \note QDateTime does not account for leap seconds.
2030 There is no year 0. Dates in that year are considered invalid. The
2031 year -1 is the year "1 before Christ" or "1 before current era."
2032 The day before 1 January 1 CE is 31 December 1 BCE.
2034 \section2 Range of Valid Dates
2036 Dates are stored internally as a Julian Day number, an interger count of
2037 every day in a contiguous range, with 24 November 4714 BCE in the Gregorian
2038 calendar being Julian Day 0 (1 January 4713 BCE in the Julian calendar).
2039 As well as being an efficient and accurate way of storing an absolute date,
2040 it is suitable for converting a Date into other calendar systems such as
2041 Hebrew, Islamic or Chinese. The Julian Day number can be obtained using
2042 QDate::toJulianDay() and can be set using QDate::fromJulianDay().
2044 The range of dates able to be stored by QDate as a Julian Day number is
2045 limited for convenience from std::numeric_limits<qint64>::min() / 2 to
2046 std::numeric_limits<qint64>::max() / 2, which on most platforms means
2047 from around 2.5 quadrillion BCE to around 2.5 quadrillion CE, effectively
2048 covering the full range of astronomical time. The range of Julian Days
2049 able to be accurately converted to and from valid YMD form Dates is
2050 restricted to 1 January 4800 BCE to 31 December 1400000 CE due to
2051 shortcomings in the available conversion formulas. Conversions outside this
2052 range are not guaranteed to be correct. This may change in the future.
2055 Use of System Timezone
2057 QDateTime uses the system's time zone information to determine the
2058 offset of local time from UTC. If the system is not configured
2059 correctly or not up-to-date, QDateTime will give wrong results as
2062 \section2 Daylight Savings Time (DST)
2064 QDateTime takes into account the system's time zone information
2065 when dealing with DST. On modern Unix systems, this means it
2066 applies the correct historical DST data whenever possible. On
2067 Windows and Windows CE, where the system doesn't support
2068 historical DST data, historical accuracy is not maintained with
2071 The range of valid dates taking DST into account is 1970-01-01 to
2072 the present, and rules are in place for handling DST correctly
2073 until 2037-12-31, but these could change. For dates falling
2074 outside that range, QDateTime makes a \e{best guess} using the
2075 rules for year 1970 or 2037, but we can't guarantee accuracy. This
2076 means QDateTime doesn't take into account changes in a locale's
2077 time zone before 1970, even if the system's time zone database
2078 supports that information.
2080 \sa QDate QTime QDateTimeEdit
2084 Constructs a null datetime (i.e. null date and null time). A null
2085 datetime is invalid, since the date is invalid.
2089 QDateTime::QDateTime()
2090 : d(new QDateTimePrivate)
2096 Constructs a datetime with the given \a date, a valid
2097 time(00:00:00.000), and sets the timeSpec() to Qt::LocalTime.
2100 QDateTime::QDateTime(const QDate &date)
2101 : d(new QDateTimePrivate)
2104 d->time = QTime(0, 0, 0);
2108 Constructs a datetime with the given \a date and \a time, using
2109 the time specification defined by \a spec.
2111 If \a date is valid and \a time is not, the time will be set to midnight.
2114 QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec)
2115 : d(new QDateTimePrivate)
2118 d->time = date.isValid() && !time.isValid() ? QTime(0, 0, 0) : time;
2119 d->spec = (spec == Qt::UTC) ? QDateTimePrivate::UTC : QDateTimePrivate::LocalUnknown;
2123 Constructs a copy of the \a other datetime.
2126 QDateTime::QDateTime(const QDateTime &other)
2132 Destroys the datetime.
2134 QDateTime::~QDateTime()
2139 Makes a copy of the \a other datetime and returns a reference to the
2143 QDateTime &QDateTime::operator=(const QDateTime &other)
2150 Returns true if both the date and the time are null; otherwise
2151 returns false. A null datetime is invalid.
2153 \sa QDate::isNull(), QTime::isNull(), isValid()
2156 bool QDateTime::isNull() const
2158 return d->date.isNull() && d->time.isNull();
2162 Returns true if both the date and the time are valid; otherwise
2165 \sa QDate::isValid(), QTime::isValid()
2168 bool QDateTime::isValid() const
2170 return d->date.isValid() && d->time.isValid();
2174 Returns the date part of the datetime.
2176 \sa setDate(), time(), timeSpec()
2179 QDate QDateTime::date() const
2185 Returns the time part of the datetime.
2187 \sa setTime(), date(), timeSpec()
2190 QTime QDateTime::time() const
2196 Returns the time specification of the datetime.
2198 \sa setTimeSpec(), date(), time(), Qt::TimeSpec
2201 Qt::TimeSpec QDateTime::timeSpec() const
2205 case QDateTimePrivate::UTC:
2207 case QDateTimePrivate::OffsetFromUTC:
2208 return Qt::OffsetFromUTC;
2210 return Qt::LocalTime;
2215 Sets the date part of this datetime to \a date.
2216 If no time is set, it is set to midnight.
2218 \sa date(), setTime(), setTimeSpec()
2221 void QDateTime::setDate(const QDate &date)
2225 if (d->spec == QDateTimePrivate::LocalStandard
2226 || d->spec == QDateTimePrivate::LocalDST)
2227 d->spec = QDateTimePrivate::LocalUnknown;
2228 if (date.isValid() && !d->time.isValid())
2229 d->time = QTime(0, 0, 0);
2233 Sets the time part of this datetime to \a time.
2235 \sa time(), setDate(), setTimeSpec()
2238 void QDateTime::setTime(const QTime &time)
2241 if (d->spec == QDateTimePrivate::LocalStandard
2242 || d->spec == QDateTimePrivate::LocalDST)
2243 d->spec = QDateTimePrivate::LocalUnknown;
2248 Sets the time specification used in this datetime to \a spec.
2250 \sa timeSpec(), setDate(), setTime(), Qt::TimeSpec
2253 void QDateTime::setTimeSpec(Qt::TimeSpec spec)
2260 d->spec = QDateTimePrivate::UTC;
2262 case Qt::OffsetFromUTC:
2263 d->spec = QDateTimePrivate::OffsetFromUTC;
2266 d->spec = QDateTimePrivate::LocalUnknown;
2271 qint64 toMSecsSinceEpoch_helper(qint64 jd, int msecs)
2273 qint64 days = jd - JULIAN_DAY_FOR_EPOCH;
2274 qint64 retval = (days * MSECS_PER_DAY) + msecs;
2281 Returns the datetime as the number of milliseconds that have passed
2282 since 1970-01-01T00:00:00.000, Coordinated Universal Time (Qt::UTC).
2284 On systems that do not support time zones, this function will
2285 behave as if local time were Qt::UTC.
2287 The behavior for this function is undefined if the datetime stored in
2288 this object is not valid. However, for all valid dates, this function
2289 returns a unique value.
2291 \sa toTime_t(), setMSecsSinceEpoch()
2293 qint64 QDateTime::toMSecsSinceEpoch() const
2297 d->getUTC(utcDate, utcTime);
2299 return toMSecsSinceEpoch_helper(utcDate.toJulianDay(), QTime(0, 0, 0).msecsTo(utcTime));
2303 Returns the datetime as the number of seconds that have passed
2304 since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC).
2306 On systems that do not support time zones, this function will
2307 behave as if local time were Qt::UTC.
2309 \note This function returns a 32-bit unsigned integer, so it does not
2310 support dates before 1970, but it does support dates after
2311 2038-01-19T03:14:06, which may not be valid time_t values. Be careful
2312 when passing those time_t values to system functions, which could
2313 interpret them as negative dates.
2315 If the date is outside the range 1970-01-01T00:00:00 to
2316 2106-02-07T06:28:14, this function returns -1 cast to an unsigned integer
2319 To get an extended range, use toMSecsSinceEpoch().
2321 \sa toMSecsSinceEpoch(), setTime_t()
2324 uint QDateTime::toTime_t() const
2326 qint64 retval = toMSecsSinceEpoch() / 1000;
2327 if (quint64(retval) >= Q_UINT64_C(0xFFFFFFFF))
2329 return uint(retval);
2335 Sets the date and time given the number of milliseconds,\a msecs, that have
2336 passed since 1970-01-01T00:00:00.000, Coordinated Universal Time
2337 (Qt::UTC). On systems that do not support time zones this function
2338 will behave as if local time were Qt::UTC.
2340 Note that there are possible values for \a msecs that lie outside the
2341 valid range of QDateTime, both negative and positive. The behavior of
2342 this function is undefined for those values.
2344 \sa toMSecsSinceEpoch(), setTime_t()
2346 void QDateTime::setMSecsSinceEpoch(qint64 msecs)
2350 QDateTimePrivate::Spec oldSpec = d->spec;
2352 int ddays = msecs / MSECS_PER_DAY;
2353 msecs %= MSECS_PER_DAY;
2357 msecs += MSECS_PER_DAY;
2360 d->date = QDate(1970, 1, 1).addDays(ddays);
2361 d->time = QTime(0, 0, 0).addMSecs(msecs);
2362 d->spec = QDateTimePrivate::UTC;
2364 if (oldSpec != QDateTimePrivate::UTC)
2365 d->spec = d->getLocal(d->date, d->time);
2369 \fn void QDateTime::setTime_t(uint seconds)
2371 Sets the date and time given the number of \a seconds that have
2372 passed since 1970-01-01T00:00:00, Coordinated Universal Time
2373 (Qt::UTC). On systems that do not support time zones this function
2374 will behave as if local time were Qt::UTC.
2379 void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
2383 QDateTimePrivate::Spec oldSpec = d->spec;
2385 d->date = QDate(1970, 1, 1).addDays(secsSince1Jan1970UTC / SECS_PER_DAY);
2386 d->time = QTime(0, 0, 0).addSecs(secsSince1Jan1970UTC % SECS_PER_DAY);
2387 d->spec = QDateTimePrivate::UTC;
2389 if (oldSpec != QDateTimePrivate::UTC)
2390 d->spec = d->getLocal(d->date, d->time);
2393 #ifndef QT_NO_DATESTRING
2395 \fn QString QDateTime::toString(Qt::DateFormat format) const
2399 Returns the datetime as a string in the \a format given.
2401 If the \a format is Qt::TextDate, the string is formatted in
2402 the default way. QDate::shortDayName(), QDate::shortMonthName(),
2403 and QTime::toString() are used to generate the string, so the
2404 day and month names will be localized names. An example of this
2405 formatting is "Wed May 20 03:40:13 1998".
2407 If the \a format is Qt::ISODate, the string format corresponds
2408 to the ISO 8601 extended specification for representations of
2409 dates and times, taking the form YYYY-MM-DDTHH:MM:SS[Z|[+|-]HH:MM],
2410 depending on the timeSpec() of the QDateTime. If the timeSpec()
2411 is Qt::UTC, Z will be appended to the string; if the timeSpec() is
2412 Qt::OffsetFromUTC the offset in hours and minutes from UTC will
2413 be appended to the string.
2415 If the \a format is Qt::SystemLocaleShortDate or
2416 Qt::SystemLocaleLongDate, the string format depends on the locale
2417 settings of the system. Identical to calling
2418 QLocale::system().toString(datetime, QLocale::ShortFormat) or
2419 QLocale::system().toString(datetime, QLocale::LongFormat).
2421 If the \a format is Qt::DefaultLocaleShortDate or
2422 Qt::DefaultLocaleLongDate, the string format depends on the
2423 default application locale. This is the locale set with
2424 QLocale::setDefault(), or the system locale if no default locale
2425 has been set. Identical to calling QLocale().toString(datetime,
2426 QLocale::ShortFormat) or QLocale().toString(datetime,
2427 QLocale::LongFormat).
2429 If the datetime is invalid, an empty string will be returned.
2431 \warning The Qt::ISODate format is only valid for years in the
2432 range 0 to 9999. This restriction may apply to locale-aware
2433 formats as well, depending on the locale settings.
2435 \sa QDate::toString() QTime::toString() Qt::DateFormat
2438 QString QDateTime::toString(Qt::DateFormat f) const
2444 if (f == Qt::ISODate) {
2445 buf = d->date.toString(Qt::ISODate);
2447 return QString(); // failed to convert
2448 buf += QLatin1Char('T');
2449 buf += d->time.toString(Qt::ISODate);
2451 case QDateTimePrivate::UTC:
2452 buf += QLatin1Char('Z');
2454 case QDateTimePrivate::OffsetFromUTC: {
2455 int sign = d->utcOffset >= 0 ? 1: -1;
2456 buf += QString::fromLatin1("%1%2:%3").
2457 arg(sign == 1 ? QLatin1Char('+') : QLatin1Char('-')).
2458 arg(d->utcOffset * sign / SECS_PER_HOUR, 2, 10, QLatin1Char('0')).
2459 arg((d->utcOffset / 60) % 60, 2, 10, QLatin1Char('0'));
2466 #ifndef QT_NO_TEXTDATE
2467 else if (f == Qt::TextDate) {
2469 buf = d->date.shortDayName(d->date.dayOfWeek());
2470 buf += QLatin1Char(' ');
2471 buf += d->date.shortMonthName(d->date.month());
2472 buf += QLatin1Char(' ');
2473 buf += QString::number(d->date.day());
2476 GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255);
2477 QString winstr = QString::fromWCharArray(out);
2478 switch (winstr.toInt()) {
2480 buf = d->date.shortDayName(d->date.dayOfWeek());
2481 buf += QLatin1Char(' ');
2482 buf += QString::number(d->date.day());
2483 buf += QLatin1String(". ");
2484 buf += d->date.shortMonthName(d->date.month());
2487 buf = d->date.shortDayName(d->date.dayOfWeek());
2488 buf += QLatin1Char(' ');
2489 buf += d->date.shortMonthName(d->date.month());
2490 buf += QLatin1Char(' ');
2491 buf += QString::number(d->date.day());
2494 buf += QLatin1Char(' ');
2495 buf += d->time.toString();
2496 buf += QLatin1Char(' ');
2497 buf += QString::number(d->date.year());
2501 buf = d->date.toString(f);
2503 return QString(); // failed to convert
2504 buf += QLatin1Char(' ');
2505 buf += d->time.toString(f);
2512 Returns the datetime as a string. The \a format parameter
2513 determines the format of the result string.
2515 These expressions may be used for the date:
2518 \header \li Expression \li Output
2519 \row \li d \li the day as number without a leading zero (1 to 31)
2520 \row \li dd \li the day as number with a leading zero (01 to 31)
2522 \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
2523 Uses QDate::shortDayName().
2525 \li the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
2526 Uses QDate::longDayName().
2527 \row \li M \li the month as number without a leading zero (1-12)
2528 \row \li MM \li the month as number with a leading zero (01-12)
2530 \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
2531 Uses QDate::shortMonthName().
2533 \li the long localized month name (e.g. 'January' to 'December').
2534 Uses QDate::longMonthName().
2535 \row \li yy \li the year as two digit number (00-99)
2536 \row \li yyyy \li the year as four digit number
2539 These expressions may be used for the time:
2542 \header \li Expression \li Output
2544 \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
2546 \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
2547 \row \li m \li the minute without a leading zero (0 to 59)
2548 \row \li mm \li the minute with a leading zero (00 to 59)
2549 \row \li s \li the second without a leading zero (0 to 59)
2550 \row \li ss \li the second with a leading zero (00 to 59)
2551 \row \li z \li the milliseconds without leading zeroes (0 to 999)
2552 \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
2554 \li use AM/PM display. \e AP will be replaced by either "AM" or "PM".
2556 \li use am/pm display. \e ap will be replaced by either "am" or "pm".
2559 All other input characters will be ignored. Any sequence of characters that
2560 are enclosed in singlequotes will be treated as text and not be used as an
2561 expression. Two consecutive singlequotes ("''") are replaced by a singlequote
2564 Example format strings (assumed that the QDateTime is 21 May 2001
2568 \header \li Format \li Result
2569 \row \li dd.MM.yyyy \li 21.05.2001
2570 \row \li ddd MMMM d yy \li Tue May 21 01
2571 \row \li hh:mm:ss.zzz \li 14:13:09.042
2572 \row \li h:m:s ap \li 2:13:9 pm
2575 If the datetime is invalid, an empty string will be returned.
2577 \sa QDate::toString() QTime::toString()
2579 QString QDateTime::toString(const QString& format) const
2581 return fmtDateTime(format, &d->time, &d->date);
2583 #endif //QT_NO_DATESTRING
2586 Returns a QDateTime object containing a datetime \a ndays days
2587 later than the datetime of this object (or earlier if \a ndays is
2590 \sa daysTo(), addMonths(), addYears(), addSecs()
2593 QDateTime QDateTime::addDays(qint64 ndays) const
2595 return QDateTime(d->date.addDays(ndays), d->time, timeSpec());
2599 Returns a QDateTime object containing a datetime \a nmonths months
2600 later than the datetime of this object (or earlier if \a nmonths
2603 \sa daysTo(), addDays(), addYears(), addSecs()
2606 QDateTime QDateTime::addMonths(int nmonths) const
2608 return QDateTime(d->date.addMonths(nmonths), d->time, timeSpec());
2612 Returns a QDateTime object containing a datetime \a nyears years
2613 later than the datetime of this object (or earlier if \a nyears is
2616 \sa daysTo(), addDays(), addMonths(), addSecs()
2619 QDateTime QDateTime::addYears(int nyears) const
2621 return QDateTime(d->date.addYears(nyears), d->time, timeSpec());
2624 QDateTime QDateTimePrivate::addMSecs(const QDateTime &dt, qint64 msecs)
2628 dt.d->getUTC(utcDate, utcTime);
2630 addMSecs(utcDate, utcTime, msecs);
2632 return QDateTime(utcDate, utcTime, Qt::UTC).toTimeSpec(dt.timeSpec());
2636 Adds \a msecs to utcDate and \a utcTime as appropriate. It is assumed that
2637 utcDate and utcTime are adjusted to UTC.
2642 void QDateTimePrivate::addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs)
2644 qint64 dd = utcDate.toJulianDay();
2645 int tt = QTime(0, 0, 0).msecsTo(utcTime);
2651 if (msecs >= int(MSECS_PER_DAY)) {
2652 dd += sign * (msecs / MSECS_PER_DAY);
2653 msecs %= MSECS_PER_DAY;
2658 tt = MSECS_PER_DAY - tt - 1;
2659 dd -= tt / MSECS_PER_DAY;
2660 tt = tt % MSECS_PER_DAY;
2661 tt = MSECS_PER_DAY - tt - 1;
2662 } else if (tt >= int(MSECS_PER_DAY)) {
2663 dd += tt / MSECS_PER_DAY;
2664 tt = tt % MSECS_PER_DAY;
2667 utcDate = QDate::fromJulianDay(dd);
2668 utcTime = QTime(0, 0, 0).addMSecs(tt);
2672 Returns a QDateTime object containing a datetime \a s seconds
2673 later than the datetime of this object (or earlier if \a s is
2676 \sa addMSecs(), secsTo(), addDays(), addMonths(), addYears()
2679 QDateTime QDateTime::addSecs(int s) const
2681 return d->addMSecs(*this, qint64(s) * 1000);
2685 Returns a QDateTime object containing a datetime \a msecs miliseconds
2686 later than the datetime of this object (or earlier if \a msecs is
2689 \sa addSecs(), msecsTo(), addDays(), addMonths(), addYears()
2691 QDateTime QDateTime::addMSecs(qint64 msecs) const
2693 return d->addMSecs(*this, msecs);
2697 Returns the number of days from this datetime to the \a other
2698 datetime. If the \a other datetime is earlier than this datetime,
2699 the value returned is negative.
2701 \sa addDays(), secsTo(), msecsTo()
2704 qint64 QDateTime::daysTo(const QDateTime &other) const
2706 return d->date.daysTo(other.d->date);
2710 Returns the number of seconds from this datetime to the \a other
2711 datetime. If the \a other datetime is earlier than this datetime,
2712 the value returned is negative.
2714 Before performing the comparison, the two datetimes are converted
2715 to Qt::UTC to ensure that the result is correct if one of the two
2716 datetimes has daylight saving time (DST) and the other doesn't.
2718 Returns 0 if either time is invalid.
2721 \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 11
2723 \sa addSecs(), daysTo(), QTime::secsTo()
2726 int QDateTime::secsTo(const QDateTime &other) const
2728 if (!isValid() || !other.isValid())
2734 d->getUTC(date1, time1);
2735 other.d->getUTC(date2, time2);
2737 return (date1.daysTo(date2) * SECS_PER_DAY) + time1.secsTo(time2);
2741 Returns the number of milliseconds from this datetime to the \a other
2742 datetime. If the \a other datetime is earlier than this datetime,
2743 the value returned is negative.
2745 Before performing the comparison, the two datetimes are converted
2746 to Qt::UTC to ensure that the result is correct if one of the two
2747 datetimes has daylight saving time (DST) and the other doesn't.
2749 Returns 0 if either time is null.
2751 \sa addMSecs(), daysTo(), QTime::msecsTo()
2754 qint64 QDateTime::msecsTo(const QDateTime &other) const
2756 if (!isValid() || !other.isValid())
2764 d->getUTC(selfDate, selfTime);
2765 other.d->getUTC(otherDate, otherTime);
2767 return (static_cast<qint64>(selfDate.daysTo(otherDate)) * static_cast<qint64>(MSECS_PER_DAY))
2768 + static_cast<qint64>(selfTime.msecsTo(otherTime));
2773 \fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec specification) const
2775 Returns a copy of this datetime configured to use the given time
2778 \sa timeSpec(), toUTC(), toLocalTime()
2781 QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
2783 if ((d->spec == QDateTimePrivate::UTC) == (spec == Qt::UTC))
2787 if (spec == Qt::UTC) {
2788 d->getUTC(ret.d->date, ret.d->time);
2789 ret.d->spec = QDateTimePrivate::UTC;
2791 ret.d->spec = d->getLocal(ret.d->date, ret.d->time);
2797 Returns true if this datetime is equal to the \a other datetime;
2798 otherwise returns false.
2803 bool QDateTime::operator==(const QDateTime &other) const
2805 if (d->spec == other.d->spec && d->utcOffset == other.d->utcOffset)
2806 return d->time == other.d->time && d->date == other.d->date;
2811 d->getUTC(date1, time1);
2812 other.d->getUTC(date2, time2);
2813 return time1 == time2 && date1 == date2;
2818 \fn bool QDateTime::operator!=(const QDateTime &other) const
2820 Returns true if this datetime is different from the \a other
2821 datetime; otherwise returns false.
2823 Two datetimes are different if either the date, the time, or the
2824 time zone components are different.
2830 Returns true if this datetime is earlier than the \a other
2831 datetime; otherwise returns false.
2834 bool QDateTime::operator<(const QDateTime &other) const
2836 if (d->spec == other.d->spec && d->spec != QDateTimePrivate::OffsetFromUTC) {
2837 if (d->date != other.d->date)
2838 return d->date < other.d->date;
2839 return d->time < other.d->time;
2843 d->getUTC(date1, time1);
2844 other.d->getUTC(date2, time2);
2846 return date1 < date2;
2847 return time1 < time2;
2852 \fn bool QDateTime::operator<=(const QDateTime &other) const
2854 Returns true if this datetime is earlier than or equal to the
2855 \a other datetime; otherwise returns false.
2859 \fn bool QDateTime::operator>(const QDateTime &other) const
2861 Returns true if this datetime is later than the \a other datetime;
2862 otherwise returns false.
2866 \fn bool QDateTime::operator>=(const QDateTime &other) const
2868 Returns true if this datetime is later than or equal to the
2869 \a other datetime; otherwise returns false.
2873 \fn QDateTime QDateTime::currentDateTime()
2874 Returns the current datetime, as reported by the system clock, in
2875 the local time zone.
2877 \sa currentDateTimeUtc(), QDate::currentDate(), QTime::currentTime(), toTimeSpec()
2881 \fn QDateTime QDateTime::currentDateTimeUtc()
2883 Returns the current datetime, as reported by the system clock, in
2886 \sa currentDateTime(), QDate::currentDate(), QTime::currentTime(), toTimeSpec()
2890 \fn qint64 QDateTime::currentMSecsSinceEpoch()
2893 Returns the number of milliseconds since 1970-01-01T00:00:00 Universal
2894 Coordinated Time. This number is like the POSIX time_t variable, but
2895 expressed in milliseconds instead.
2897 \sa currentDateTime(), currentDateTimeUtc(), toTime_t(), toTimeSpec()
2900 static inline uint msecsFromDecomposed(int hour, int minute, int sec, int msec = 0)
2902 return MSECS_PER_HOUR * hour + MSECS_PER_MIN * minute + 1000 * sec + msec;
2905 #if defined(Q_OS_WIN)
2906 QDate QDate::currentDate()
2910 memset(&st, 0, sizeof(SYSTEMTIME));
2912 d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
2916 QTime QTime::currentTime()
2920 memset(&st, 0, sizeof(SYSTEMTIME));
2922 ct.setHMS(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
2923 #if defined(Q_OS_WINCE)
2924 ct.startTick = GetTickCount() % MSECS_PER_DAY;
2929 QDateTime QDateTime::currentDateTime()
2934 memset(&st, 0, sizeof(SYSTEMTIME));
2936 d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
2937 t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
2938 return QDateTime(d, t);
2941 QDateTime QDateTime::currentDateTimeUtc()
2946 memset(&st, 0, sizeof(SYSTEMTIME));
2948 d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
2949 t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
2950 return QDateTime(d, t, Qt::UTC);
2953 qint64 QDateTime::currentMSecsSinceEpoch()
2958 memset(&st, 0, sizeof(SYSTEMTIME));
2961 return msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds) +
2962 qint64(julianDayFromDate(st.wYear, st.wMonth, st.wDay)
2963 - julianDayFromDate(1970, 1, 1)) * Q_INT64_C(86400000);
2966 #elif defined(Q_OS_UNIX)
2967 QDate QDate::currentDate()
2970 // posix compliant system
2975 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
2976 // use the reentrant version of localtime() where available
2979 t = localtime_r(<ime, &res);
2981 t = localtime(<ime);
2982 #endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
2984 d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
2988 QTime QTime::currentTime()
2991 // posix compliant system
2993 gettimeofday(&tv, 0);
2994 time_t ltime = tv.tv_sec;
2997 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
2998 // use the reentrant version of localtime() where available
3001 t = localtime_r(<ime, &res);
3003 t = localtime(<ime);
3007 ct.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
3011 QDateTime QDateTime::currentDateTime()
3013 // posix compliant system
3014 // we have milliseconds
3016 gettimeofday(&tv, 0);
3017 time_t ltime = tv.tv_sec;
3020 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3021 // use the reentrant version of localtime() where available
3024 t = localtime_r(<ime, &res);
3026 t = localtime(<ime);
3030 dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
3032 dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
3033 dt.d->spec = t->tm_isdst > 0 ? QDateTimePrivate::LocalDST :
3034 t->tm_isdst == 0 ? QDateTimePrivate::LocalStandard :
3035 QDateTimePrivate::LocalUnknown;
3039 QDateTime QDateTime::currentDateTimeUtc()
3041 // posix compliant system
3042 // we have milliseconds
3044 gettimeofday(&tv, 0);
3045 time_t ltime = tv.tv_sec;
3048 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3049 // use the reentrant version of localtime() where available
3051 t = gmtime_r(<ime, &res);
3057 dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
3059 dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
3060 dt.d->spec = QDateTimePrivate::UTC;
3064 qint64 QDateTime::currentMSecsSinceEpoch()
3066 // posix compliant system
3067 // we have milliseconds
3069 gettimeofday(&tv, 0);
3070 return qint64(tv.tv_sec) * Q_INT64_C(1000) + tv.tv_usec / 1000;
3074 #error "What system is this?"
3080 Returns a datetime whose date and time are the number of \a seconds
3081 that have passed since 1970-01-01T00:00:00, Coordinated Universal
3082 Time (Qt::UTC). On systems that do not support time zones, the time
3083 will be set as if local time were Qt::UTC.
3085 \sa toTime_t(), setTime_t()
3087 QDateTime QDateTime::fromTime_t(uint seconds)
3090 d.setTime_t(seconds);
3097 Returns a datetime whose date and time are the number of milliseconds, \a msecs,
3098 that have passed since 1970-01-01T00:00:00.000, Coordinated Universal
3099 Time (Qt::UTC). On systems that do not support time zones, the time
3100 will be set as if local time were Qt::UTC.
3102 Note that there are possible values for \a msecs that lie outside the valid
3103 range of QDateTime, both negative and positive. The behavior of this
3104 function is undefined for those values.
3106 \sa toTime_t(), setTime_t()
3108 QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs)
3111 d.setMSecsSinceEpoch(msecs);
3119 Sets the offset from UTC to \a seconds, and also sets timeSpec() to
3122 The maximum and minimum offset is 14 positive or negative hours. If
3123 \a seconds is larger or smaller than that, the result is undefined.
3125 0 as offset is identical to UTC. Therefore, if \a seconds is 0, the
3126 timeSpec() will be set to Qt::UTC. Hence the UTC offset always
3127 relates to UTC, and can never relate to local time.
3129 \sa isValid(), utcOffset()
3131 void QDateTime::setUtcOffset(int seconds)
3135 /* The motivation to also setting d->spec is to ensure that the QDateTime
3136 * instance stay in well-defined states all the time, instead of that
3137 * we instruct the user to ensure it. */
3139 d->spec = QDateTimePrivate::UTC;
3141 d->spec = QDateTimePrivate::OffsetFromUTC;
3143 /* Even if seconds is 0 we assign it to utcOffset. */
3144 d->utcOffset = seconds;
3151 Returns the UTC offset in seconds. If the timeSpec() isn't
3152 Qt::OffsetFromUTC, 0 is returned. However, since 0 is a valid UTC
3153 offset the return value of this function cannot be used to determine
3154 whether a utcOffset() is used or is valid, timeSpec() must be
3157 Likewise, if this QDateTime() is invalid or if timeSpec() isn't
3158 Qt::OffsetFromUTC, 0 is returned.
3160 The UTC offset only applies if the timeSpec() is Qt::OffsetFromUTC.
3162 \sa isValid(), setUtcOffset()
3164 int QDateTime::utcOffset() const
3166 if(isValid() && d->spec == QDateTimePrivate::OffsetFromUTC)
3167 return d->utcOffset;
3172 #ifndef QT_NO_DATESTRING
3174 static int fromShortMonthName(const QString &monthName)
3176 // Assume that English monthnames are the default
3177 for (int i = 0; i < 12; ++i) {
3178 if (monthName == QLatin1String(qt_shortMonthNames[i]))
3181 // If English names can't be found, search the localized ones
3182 for (int i = 1; i <= 12; ++i) {
3183 if (monthName == QDate::shortMonthName(i))
3190 \fn QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
3192 Returns the QDateTime represented by the \a string, using the
3193 \a format given, or an invalid datetime if this is not possible.
3195 Note for Qt::TextDate: It is recommended that you use the
3196 English short month names (e.g. "Jan"). Although localized month
3197 names can also be used, they depend on the user's locale settings.
3199 QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
3208 Qt::TimeSpec ts = Qt::LocalTime;
3209 const QDate date = QDate::fromString(tmp.left(10), Qt::ISODate);
3210 if (tmp.size() == 10)
3211 return QDateTime(date);
3215 // Recognize UTC specifications
3216 if (tmp.endsWith(QLatin1Char('Z'))) {
3221 // Recognize timezone specifications
3222 QRegExp rx(QLatin1String("[+-]"));
3223 if (tmp.contains(rx)) {
3224 int idx = tmp.indexOf(rx);
3225 QString tmp2 = tmp.mid(idx);
3226 tmp = tmp.left(idx);
3230 if ( tmp2.indexOf(QLatin1Char(':')) == 3 )
3232 const int tzhour(tmp2.mid(ntzhour, 2).toInt(&ok));
3233 const int tzminute(tmp2.mid(ntzminute, 2).toInt(&ok));
3234 QTime tzt(tzhour, tzminute);
3235 int utcOffset = (tzt.hour() * 60 + tzt.minute()) * 60;
3236 if ( utcOffset != 0 ) {
3237 ts = Qt::OffsetFromUTC;
3238 QDateTime dt(date, QTime::fromString(tmp, Qt::ISODate), ts);
3239 dt.setUtcOffset( utcOffset * (tmp2.startsWith(QLatin1Char('-')) ? -1 : 1) );
3243 return QDateTime(date, QTime::fromString(tmp, Qt::ISODate), ts);
3245 case Qt::SystemLocaleDate:
3246 case Qt::SystemLocaleShortDate:
3247 case Qt::SystemLocaleLongDate:
3248 return fromString(s, QLocale::system().dateTimeFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
3249 : QLocale::ShortFormat));
3250 case Qt::LocaleDate:
3251 case Qt::DefaultLocaleShortDate:
3252 case Qt::DefaultLocaleLongDate:
3253 return fromString(s, QLocale().dateTimeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
3254 : QLocale::ShortFormat));
3255 #if !defined(QT_NO_TEXTDATE)
3256 case Qt::TextDate: {
3257 QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts);
3259 if ((parts.count() < 5) || (parts.count() > 6)) {
3263 // Accept "Sun Dec 1 13:02:00 1974" and "Sun 1. Dec 13:02:00 1974"
3264 int month = -1, day = -1;
3267 month = fromShortMonthName(parts.at(1));
3269 day = parts.at(2).toInt(&ok);
3274 if (month == -1 || day == -1) {
3275 // first variant failed, lets try the other
3276 month = fromShortMonthName(parts.at(2));
3278 QString dayStr = parts.at(1);
3279 if (dayStr.endsWith(QLatin1Char('.'))) {
3281 day = dayStr.toInt(&ok);
3290 if (month == -1 || day == -1) {
3291 // both variants failed, give up
3296 QStringList timeParts = parts.at(3).split(QLatin1Char(':'));
3297 if ((timeParts.count() == 3) || (timeParts.count() == 2)) {
3298 year = parts.at(4).toInt(&ok);
3302 timeParts = parts.at(4).split(QLatin1Char(':'));
3303 if ((timeParts.count() != 3) && (timeParts.count() != 2))
3305 year = parts.at(3).toInt(&ok);
3310 int hour = timeParts.at(0).toInt(&ok);
3315 int minute = timeParts.at(1).toInt(&ok);
3320 int second = (timeParts.count() > 2) ? timeParts.at(2).toInt(&ok) : 0;
3325 QDate date(year, month, day);
3326 QTime time(hour, minute, second);
3328 if (parts.count() == 5)
3329 return QDateTime(date, time, Qt::LocalTime);
3331 QString tz = parts.at(5);
3332 if (!tz.startsWith(QLatin1String("GMT"), Qt::CaseInsensitive))
3334 QDateTime dt(date, time, Qt::UTC);
3335 if (tz.length() > 3) {
3337 QChar sign = tz.at(3);
3338 if ((sign != QLatin1Char('+'))
3339 && (sign != QLatin1Char('-'))) {
3342 int tzhour = tz.mid(4, 2).toInt(&ok);
3345 int tzminute = tz.mid(6).toInt(&ok);
3348 tzoffset = (tzhour*60 + tzminute) * 60;
3349 if (sign == QLatin1Char('-'))
3350 tzoffset = -tzoffset;
3351 dt.setUtcOffset(tzoffset);
3353 return dt.toLocalTime();
3355 #endif //QT_NO_TEXTDATE
3362 \fn QDateTime::fromString(const QString &string, const QString &format)
3364 Returns the QDateTime represented by the \a string, using the \a
3365 format given, or an invalid datetime if the string cannot be parsed.
3367 These expressions may be used for the date part of the format string:
3370 \header \li Expression \li Output
3371 \row \li d \li the day as number without a leading zero (1 to 31)
3372 \row \li dd \li the day as number with a leading zero (01 to 31)
3374 \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
3375 Uses QDate::shortDayName().
3377 \li the long localized day name (e.g. 'Monday' to 'Sunday').
3378 Uses QDate::longDayName().
3379 \row \li M \li the month as number without a leading zero (1-12)
3380 \row \li MM \li the month as number with a leading zero (01-12)
3382 \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
3383 Uses QDate::shortMonthName().
3385 \li the long localized month name (e.g. 'January' to 'December').
3386 Uses QDate::longMonthName().
3387 \row \li yy \li the year as two digit number (00-99)
3388 \row \li yyyy \li the year as four digit number
3391 \note Unlike the other version of this function, day and month names must
3392 be given in the user's local language. It is only possible to use the English
3393 names if the user's language is English.
3395 These expressions may be used for the time part of the format string:
3398 \header \li Expression \li Output
3400 \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
3402 \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
3404 \li the hour without a leading zero (0 to 23, even with AM/PM display)
3406 \li the hour with a leading zero (00 to 23, even with AM/PM display)
3407 \row \li m \li the minute without a leading zero (0 to 59)
3408 \row \li mm \li the minute with a leading zero (00 to 59)
3409 \row \li s \li the second without a leading zero (0 to 59)
3410 \row \li ss \li the second with a leading zero (00 to 59)
3411 \row \li z \li the milliseconds without leading zeroes (0 to 999)
3412 \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
3414 \li interpret as an AM/PM time. \e AP must be either "AM" or "PM".
3416 \li Interpret as an AM/PM time. \e ap must be either "am" or "pm".
3419 All other input characters will be treated as text. Any sequence
3420 of characters that are enclosed in singlequotes will also be
3421 treated as text and not be used as an expression.
3423 \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 12
3425 If the format is not satisfied an invalid QDateTime is returned.
3426 The expressions that don't have leading zeroes (d, M, h, m, s, z) will be
3427 greedy. This means that they will use two digits even if this will
3428 put them outside the range and/or leave too few digits for other
3431 \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 13
3433 This could have meant 1 January 00:30.00 but the M will grab
3436 For any field that is not represented in the format the following
3440 \header \li Field \li Default value
3441 \row \li Year \li 1900
3442 \row \li Month \li 1 (January)
3445 \row \li Minute \li 0
3446 \row \li Second \li 0
3451 \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 14
3453 \sa QDate::fromString() QTime::fromString() QDate::toString()
3454 QDateTime::toString() QTime::toString()
3457 QDateTime QDateTime::fromString(const QString &string, const QString &format)
3459 #ifndef QT_BOOTSTRAPPED
3463 QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString);
3464 if (dt.parseFormat(format) && dt.fromString(string, &date, &time))
3465 return QDateTime(date, time);
3470 return QDateTime(QDate(), QTime(-1, -1, -1));
3473 #endif // QT_NO_DATESTRING
3475 \fn QDateTime QDateTime::toLocalTime() const
3477 Returns a datetime containing the date and time information in
3478 this datetime, but specified using the Qt::LocalTime definition.
3484 \fn QDateTime QDateTime::toUTC() const
3486 Returns a datetime containing the date and time information in
3487 this datetime, but specified using the Qt::UTC definition.
3494 void QDateTime::detach()
3499 /*****************************************************************************
3500 Date/time stream functions
3501 *****************************************************************************/
3503 #ifndef QT_NO_DATASTREAM
3507 Writes the \a date to stream \a out.
3509 \sa {Serializing Qt Data Types}
3512 QDataStream &operator<<(QDataStream &out, const QDate &date)
3514 if (out.version() < QDataStream::Qt_5_0)
3515 return out << quint32(date.jd);
3517 return out << qint64(date.jd);
3523 Reads a date from stream \a in into the \a date.
3525 \sa {Serializing Qt Data Types}
3528 QDataStream &operator>>(QDataStream &in, QDate &date)
3530 if (in.version() < QDataStream::Qt_5_0) {
3546 Writes \a time to stream \a out.
3548 \sa {Serializing Qt Data Types}
3551 QDataStream &operator<<(QDataStream &out, const QTime &time)
3553 return out << quint32(time.mds);
3559 Reads a time from stream \a in into the given \a time.
3561 \sa {Serializing Qt Data Types}
3564 QDataStream &operator>>(QDataStream &in, QTime &time)
3575 Writes \a dateTime to the \a out stream.
3577 \sa {Serializing Qt Data Types}
3579 QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime)
3581 out << dateTime.d->date << dateTime.d->time;
3582 if (out.version() >= 7)
3583 out << (qint8)dateTime.d->spec;
3590 Reads a datetime from the stream \a in into \a dateTime.
3592 \sa {Serializing Qt Data Types}
3595 QDataStream &operator>>(QDataStream &in, QDateTime &dateTime)
3599 qint8 ts = (qint8)QDateTimePrivate::LocalUnknown;
3600 in >> dateTime.d->date >> dateTime.d->time;
3601 if (in.version() >= 7)
3603 dateTime.d->spec = (QDateTimePrivate::Spec)ts;
3606 #endif // QT_NO_DATASTREAM
3610 // checks if there is an unqoted 'AP' or 'ap' in the string
3611 static bool hasUnquotedAP(const QString &f)
3613 const QLatin1Char quote('\'');
3614 bool inquote = false;
3615 const int max = f.size();
3616 for (int i=0; i<max; ++i) {
3617 if (f.at(i) == quote) {
3619 } else if (!inquote && f.at(i).toUpper() == QLatin1Char('A')) {
3626 #ifndef QT_NO_DATESTRING
3627 /*****************************************************************************
3628 Some static function used by QDate, QTime and QDateTime
3629 *****************************************************************************/
3631 // Replaces tokens by their value. See QDateTime::toString() for a list of valid tokens
3632 static QString getFmtString(const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = false)
3641 if (f.startsWith(QLatin1String("hh")) || f.startsWith(QLatin1String("HH"))) {
3642 const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
3643 if (hour12 && dt->hour() > 12)
3644 buf = QString::number(dt->hour() - 12).rightJustified(2, QLatin1Char('0'), true);
3645 else if (hour12 && dt->hour() == 0)
3646 buf = QLatin1String("12");
3648 buf = QString::number(dt->hour()).rightJustified(2, QLatin1Char('0'), true);
3650 } else if (f.at(0) == QLatin1Char('h') || f.at(0) == QLatin1Char('H')) {
3651 const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
3652 if (hour12 && dt->hour() > 12)
3653 buf = QString::number(dt->hour() - 12);
3654 else if (hour12 && dt->hour() == 0)
3655 buf = QLatin1String("12");
3657 buf = QString::number(dt->hour());
3659 } else if (f.startsWith(QLatin1String("mm"))) {
3660 buf = QString::number(dt->minute()).rightJustified(2, QLatin1Char('0'), true);
3662 } else if (f.at(0) == (QLatin1Char('m'))) {
3663 buf = QString::number(dt->minute());
3665 } else if (f.startsWith(QLatin1String("ss"))) {
3666 buf = QString::number(dt->second()).rightJustified(2, QLatin1Char('0'), true);
3668 } else if (f.at(0) == QLatin1Char('s')) {
3669 buf = QString::number(dt->second());
3670 } else if (f.startsWith(QLatin1String("zzz"))) {
3671 buf = QString::number(dt->msec()).rightJustified(3, QLatin1Char('0'), true);
3673 } else if (f.at(0) == QLatin1Char('z')) {
3674 buf = QString::number(dt->msec());
3676 } else if (f.at(0).toUpper() == QLatin1Char('A')) {
3677 const bool upper = f.at(0) == QLatin1Char('A');
3678 buf = dt->hour() < 12 ? QLatin1String("am") : QLatin1String("pm");
3680 buf = buf.toUpper();
3681 if (f.size() > 1 && f.at(1).toUpper() == QLatin1Char('P') &&
3682 f.at(0).isUpper() == f.at(1).isUpper()) {
3691 if (f.startsWith(QLatin1String("dddd"))) {
3692 buf = dd->longDayName(dd->dayOfWeek());
3694 } else if (f.startsWith(QLatin1String("ddd"))) {
3695 buf = dd->shortDayName(dd->dayOfWeek());
3697 } else if (f.startsWith(QLatin1String("dd"))) {
3698 buf = QString::number(dd->day()).rightJustified(2, QLatin1Char('0'), true);
3700 } else if (f.at(0) == QLatin1Char('d')) {
3701 buf = QString::number(dd->day());
3703 } else if (f.startsWith(QLatin1String("MMMM"))) {
3704 buf = dd->longMonthName(dd->month());
3706 } else if (f.startsWith(QLatin1String("MMM"))) {
3707 buf = dd->shortMonthName(dd->month());
3709 } else if (f.startsWith(QLatin1String("MM"))) {
3710 buf = QString::number(dd->month()).rightJustified(2, QLatin1Char('0'), true);
3712 } else if (f.at(0) == QLatin1Char('M')) {
3713 buf = QString::number(dd->month());
3715 } else if (f.startsWith(QLatin1String("yyyy"))) {
3716 const int year = dd->year();
3717 buf = QString::number(qAbs(year)).rightJustified(4, QLatin1Char('0'));
3722 buf.prepend(QLatin1Char('-'));
3726 } else if (f.startsWith(QLatin1String("yy"))) {
3727 buf = QString::number(dd->year()).right(2).rightJustified(2, QLatin1Char('0'));
3731 if (removed == 0 || removed >= f.size()) {
3735 return buf + getFmtString(f.mid(removed), dt, dd, am_pm);
3738 // Parses the format string and uses getFmtString to get the values for the tokens. Ret
3739 static QString fmtDateTime(const QString& f, const QTime* dt, const QDate* dd)
3741 const QLatin1Char quote('\'');
3744 if (dt && !dt->isValid())
3746 if (dd && !dd->isValid())
3749 const bool ap = hasUnquotedAP(f);
3753 QChar status(QLatin1Char('0'));
3755 for (int i = 0; i < (int)f.length(); ++i) {
3756 if (f.at(i) == quote) {
3757 if (status == quote) {
3758 if (i > 0 && f.at(i - 1) == quote)
3759 buf += QLatin1Char('\'');
3760 status = QLatin1Char('0');
3762 if (!frm.isEmpty()) {
3763 buf += getFmtString(frm, dt, dd, ap);
3768 } else if (status == quote) {
3770 } else if (f.at(i) == status) {
3771 if ((ap) && ((f.at(i) == QLatin1Char('P')) || (f.at(i) == QLatin1Char('p'))))
3772 status = QLatin1Char('0');
3775 buf += getFmtString(frm, dt, dd, ap);
3777 if ((f.at(i) == QLatin1Char('h')) || (f.at(i) == QLatin1Char('m'))
3778 || (f.at(i) == QLatin1Char('H'))
3779 || (f.at(i) == QLatin1Char('s')) || (f.at(i) == QLatin1Char('z'))) {
3782 } else if ((f.at(i) == QLatin1Char('d')) || (f.at(i) == QLatin1Char('M')) || (f.at(i) == QLatin1Char('y'))) {
3785 } else if ((ap) && (f.at(i) == QLatin1Char('A'))) {
3786 status = QLatin1Char('P');
3788 } else if((ap) && (f.at(i) == QLatin1Char('a'))) {
3789 status = QLatin1Char('p');
3793 status = QLatin1Char('0');
3798 buf += getFmtString(frm, dt, dd, ap);
3802 #endif // QT_NO_DATESTRING
3805 static const int LowerYear = 1980;
3807 static const int LowerYear = 1970;
3809 static const int UpperYear = 2037;
3811 static QDate adjustDate(QDate date)
3813 QDate lowerLimit(LowerYear, 1, 2);
3814 QDate upperLimit(UpperYear, 12, 30);
3816 if (date > lowerLimit && date < upperLimit)
3819 int month = date.month();
3820 int day = date.day();
3822 // neither 1970 nor 2037 are leap years, so make sure date isn't Feb 29
3823 if (month == 2 && day == 29)
3826 if (date < lowerLimit)
3827 date.setDate(LowerYear, month, day);
3829 date.setDate(UpperYear, month, day);
3834 static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time)
3836 QDate fakeDate = adjustDate(date);
3838 // won't overflow because of fakeDate
3839 time_t secsSince1Jan1970UTC = toMSecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime(0, 0, 0).msecsTo(time)) / 1000;
3842 #if defined(Q_OS_WINCE)
3844 FILETIME utcTime = time_tToFt(secsSince1Jan1970UTC);
3845 FILETIME resultTime;
3846 FileTimeToLocalFileTime(&utcTime , &resultTime);
3848 FileTimeToSystemTime(&resultTime , &sysTime);
3850 res.tm_sec = sysTime.wSecond;
3851 res.tm_min = sysTime.wMinute;
3852 res.tm_hour = sysTime.wHour;
3853 res.tm_mday = sysTime.wDay;
3854 res.tm_mon = sysTime.wMonth - 1;
3855 res.tm_year = sysTime.wYear - 1900;
3857 #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3858 // use the reentrant version of localtime() where available
3861 brokenDown = localtime_r(&secsSince1Jan1970UTC, &res);
3862 #elif defined(_MSC_VER) && _MSC_VER >= 1400
3864 if (!_localtime64_s(&res, &secsSince1Jan1970UTC))
3867 brokenDown = localtime(&secsSince1Jan1970UTC);
3870 date = QDate(1970, 1, 1);
3872 return QDateTimePrivate::LocalUnknown;
3874 int deltaDays = fakeDate.daysTo(date);
3875 date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
3876 time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());
3877 date = date.addDays(deltaDays);
3878 if (brokenDown->tm_isdst > 0)
3879 return QDateTimePrivate::LocalDST;
3880 else if (brokenDown->tm_isdst < 0)
3881 return QDateTimePrivate::LocalUnknown;
3883 return QDateTimePrivate::LocalStandard;
3887 static void localToUtc(QDate &date, QTime &time, int isdst)
3889 if (!date.isValid())
3892 QDate fakeDate = adjustDate(date);
3895 localTM.tm_sec = time.second();
3896 localTM.tm_min = time.minute();
3897 localTM.tm_hour = time.hour();
3898 localTM.tm_mday = fakeDate.day();
3899 localTM.tm_mon = fakeDate.month() - 1;
3900 localTM.tm_year = fakeDate.year() - 1900;
3901 localTM.tm_isdst = (int)isdst;
3902 #if defined(Q_OS_WINCE)
3903 time_t secsSince1Jan1970UTC = (toMSecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime().msecsTo(time)) / 1000);
3905 #if defined(Q_OS_WIN)
3908 time_t secsSince1Jan1970UTC = mktime(&localTM);
3911 #if defined(Q_OS_WINCE)
3913 FILETIME localTime = time_tToFt(secsSince1Jan1970UTC);
3915 FileTimeToSystemTime(&localTime, &sysTime);
3916 FILETIME resultTime;
3917 LocalFileTimeToFileTime(&localTime , &resultTime);
3918 FileTimeToSystemTime(&resultTime , &sysTime);
3919 res.tm_sec = sysTime.wSecond;
3920 res.tm_min = sysTime.wMinute;
3921 res.tm_hour = sysTime.wHour;
3922 res.tm_mday = sysTime.wDay;
3923 res.tm_mon = sysTime.wMonth - 1;
3924 res.tm_year = sysTime.wYear - 1900;
3925 res.tm_isdst = (int)isdst;
3927 #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3928 // use the reentrant version of gmtime() where available
3930 brokenDown = gmtime_r(&secsSince1Jan1970UTC, &res);
3931 #elif defined(_MSC_VER) && _MSC_VER >= 1400
3933 if (!_gmtime64_s(&res, &secsSince1Jan1970UTC))
3936 brokenDown = gmtime(&secsSince1Jan1970UTC);
3937 #endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
3939 date = QDate(1970, 1, 1);
3942 int deltaDays = fakeDate.daysTo(date);
3943 date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
3944 time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());
3945 date = date.addDays(deltaDays);
3949 QDateTimePrivate::Spec QDateTimePrivate::getLocal(QDate &outDate, QTime &outTime) const
3953 if (spec == QDateTimePrivate::UTC)
3954 return utcToLocal(outDate, outTime);
3958 void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const
3962 const bool isOffset = spec == QDateTimePrivate::OffsetFromUTC;
3964 if (spec != QDateTimePrivate::UTC && !isOffset)
3965 localToUtc(outDate, outTime, (int)spec);
3968 addMSecs(outDate, outTime, -(qint64(utcOffset) * 1000));
3971 #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
3972 QDebug operator<<(QDebug dbg, const QDate &date)
3974 dbg.nospace() << "QDate(" << date.toString() << ')';
3978 QDebug operator<<(QDebug dbg, const QTime &time)
3980 dbg.nospace() << "QTime(" << time.toString() << ')';
3984 QDebug operator<<(QDebug dbg, const QDateTime &date)
3986 dbg.nospace() << "QDateTime(" << date.toString() << ')';
3991 #ifndef QT_BOOTSTRAPPED
3995 Gets the digit from a datetime. E.g.
3997 QDateTime var(QDate(2004, 02, 02));
3998 int digit = getDigit(var, Year);
4002 int QDateTimeParser::getDigit(const QDateTime &t, int index) const
4004 if (index < 0 || index >= sectionNodes.size()) {
4005 #ifndef QT_NO_DATESTRING
4006 qWarning("QDateTimeParser::getDigit() Internal error (%s %d)",
4007 qPrintable(t.toString()), index);
4009 qWarning("QDateTimeParser::getDigit() Internal error (%d)", index);
4013 const SectionNode &node = sectionNodes.at(index);
4014 switch (node.type) {
4015 case Hour24Section: case Hour12Section: return t.time().hour();
4016 case MinuteSection: return t.time().minute();
4017 case SecondSection: return t.time().second();
4018 case MSecSection: return t.time().msec();
4019 case YearSection2Digits:
4020 case YearSection: return t.date().year();
4021 case MonthSection: return t.date().month();
4022 case DaySection: return t.date().day();
4023 case DayOfWeekSection: return t.date().day();
4024 case AmPmSection: return t.time().hour() > 11 ? 1 : 0;
4029 #ifndef QT_NO_DATESTRING
4030 qWarning("QDateTimeParser::getDigit() Internal error 2 (%s %d)",
4031 qPrintable(t.toString()), index);
4033 qWarning("QDateTimeParser::getDigit() Internal error 2 (%d)", index);
4040 Sets a digit in a datetime. E.g.
4042 QDateTime var(QDate(2004, 02, 02));
4043 int digit = getDigit(var, Year);
4045 setDigit(&var, Year, 2005);
4046 digit = getDigit(var, Year);
4050 bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
4052 if (index < 0 || index >= sectionNodes.size()) {
4053 #ifndef QT_NO_DATESTRING
4054 qWarning("QDateTimeParser::setDigit() Internal error (%s %d %d)",
4055 qPrintable(v.toString()), index, newVal);
4057 qWarning("QDateTimeParser::setDigit() Internal error (%d %d)", index, newVal);
4061 const SectionNode &node = sectionNodes.at(index);
4063 int year, month, day, hour, minute, second, msec;
4064 year = v.date().year();
4065 month = v.date().month();
4066 day = v.date().day();
4067 hour = v.time().hour();
4068 minute = v.time().minute();
4069 second = v.time().second();
4070 msec = v.time().msec();
4072 switch (node.type) {
4073 case Hour24Section: case Hour12Section: hour = newVal; break;
4074 case MinuteSection: minute = newVal; break;
4075 case SecondSection: second = newVal; break;
4076 case MSecSection: msec = newVal; break;
4077 case YearSection2Digits:
4078 case YearSection: year = newVal; break;
4079 case MonthSection: month = newVal; break;
4081 case DayOfWeekSection:
4083 // have to keep legacy behavior. setting the
4084 // date to 32 should return false. Setting it
4085 // to 31 for february should return true
4090 case AmPmSection: hour = (newVal == 0 ? hour % 12 : (hour % 12) + 12); break;
4092 qWarning("QDateTimeParser::setDigit() Internal error (%s)",
4093 qPrintable(sectionName(node.type)));
4097 if (!(node.type & (DaySection|DayOfWeekSection))) {
4098 if (day < cachedDay)
4100 const int max = QDate(year, month, 1).daysInMonth();
4105 if (QDate::isValid(year, month, day) && QTime::isValid(hour, minute, second, msec)) {
4106 v = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);
4117 Returns the absolute maximum for a section
4120 int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
4122 const SectionNode &sn = sectionNode(s);
4125 case Hour12Section: return 23; // this is special-cased in
4126 // parseSection. We want it to be
4127 // 23 for the stepBy case.
4129 case SecondSection: return 59;
4130 case MSecSection: return 999;
4131 case YearSection2Digits:
4132 case YearSection: return 9999; // sectionMaxSize will prevent
4133 // people from typing in a larger
4134 // number in count == 2 sections.
4135 // stepBy() will work on real years anyway
4136 case MonthSection: return 12;
4138 case DayOfWeekSection: return cur.isValid() ? cur.date().daysInMonth() : 31;
4139 case AmPmSection: return 1;
4142 qWarning("QDateTimeParser::absoluteMax() Internal error (%s)",
4143 qPrintable(sectionName(sn.type)));
4150 Returns the absolute minimum for a section
4153 int QDateTimeParser::absoluteMin(int s) const
4155 const SectionNode &sn = sectionNode(s);
4162 case YearSection2Digits:
4163 case YearSection: return 0;
4166 case DayOfWeekSection: return 1;
4167 case AmPmSection: return 0;
4170 qWarning("QDateTimeParser::absoluteMin() Internal error (%s, %0x)",
4171 qPrintable(sectionName(sn.type)), sn.type);
4178 Returns the sectionNode for the Section \a s.
4181 const QDateTimeParser::SectionNode &QDateTimeParser::sectionNode(int sectionIndex) const
4183 if (sectionIndex < 0) {
4184 switch (sectionIndex) {
4185 case FirstSectionIndex:
4187 case LastSectionIndex:
4189 case NoSectionIndex:
4192 } else if (sectionIndex < sectionNodes.size()) {
4193 return sectionNodes.at(sectionIndex);
4196 qWarning("QDateTimeParser::sectionNode() Internal error (%d)",
4201 QDateTimeParser::Section QDateTimeParser::sectionType(int sectionIndex) const
4203 return sectionNode(sectionIndex).type;
4210 Returns the starting position for section \a s.
4213 int QDateTimeParser::sectionPos(int sectionIndex) const
4215 return sectionPos(sectionNode(sectionIndex));
4218 int QDateTimeParser::sectionPos(const SectionNode &sn) const
4221 case FirstSection: return 0;
4222 case LastSection: return displayText().size() - 1;
4226 qWarning("QDateTimeParser::sectionPos Internal error (%s)", qPrintable(sectionName(sn.type)));
4234 \internal helper function for parseFormat. removes quotes that are
4235 not escaped and removes the escaping on those that are escaped
4239 static QString unquote(const QString &str)
4241 const QChar quote(QLatin1Char('\''));
4242 const QChar slash(QLatin1Char('\\'));
4243 const QChar zero(QLatin1Char('0'));
4246 const int max = str.size();
4247 for (int i=0; i<max; ++i) {
4248 if (str.at(i) == quote) {
4249 if (status != quote) {
4251 } else if (!ret.isEmpty() && str.at(i - 1) == slash) {
4252 ret[ret.size() - 1] = quote;
4265 Parses the format \a newFormat. If successful, returns true and
4266 sets up the format. Else keeps the old format and returns false.
4270 static inline int countRepeat(const QString &str, int index, int maxCount)
4273 const QChar ch(str.at(index));
4274 const int max = qMin(index + maxCount, str.size());
4275 while (index + count < max && str.at(index + count) == ch) {
4281 static inline void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote)
4283 QString str(string.mid(from, size));
4284 if (lastQuote >= from)
4290 bool QDateTimeParser::parseFormat(const QString &newFormat)
4292 const QLatin1Char quote('\'');
4293 const QLatin1Char slash('\\');
4294 const QLatin1Char zero('0');
4295 if (newFormat == displayFormat && !newFormat.isEmpty()) {
4299 QDTPDEBUGN("parseFormat: %s", newFormat.toLatin1().constData());
4301 QVector<SectionNode> newSectionNodes;
4302 Sections newDisplay = 0;
4303 QStringList newSeparators;
4307 const int max = newFormat.size();
4309 for (i = 0; i<max; ++i) {
4310 if (newFormat.at(i) == quote) {
4313 if (status != quote) {
4315 } else if (newFormat.at(i - 1) != slash) {
4318 } else if (status != quote) {
4319 const char sect = newFormat.at(i).toLatin1();
4323 if (parserType != QVariant::Date) {
4324 const Section hour = (sect == 'h') ? Hour12Section : Hour24Section;
4325 const SectionNode sn = { hour, i - add, countRepeat(newFormat, i, 2) };
4326 newSectionNodes.append(sn);
4327 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4334 if (parserType != QVariant::Date) {
4335 const SectionNode sn = { MinuteSection, i - add, countRepeat(newFormat, i, 2) };
4336 newSectionNodes.append(sn);
4337 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4340 newDisplay |= MinuteSection;
4344 if (parserType != QVariant::Date) {
4345 const SectionNode sn = { SecondSection, i - add, countRepeat(newFormat, i, 2) };
4346 newSectionNodes.append(sn);
4347 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4350 newDisplay |= SecondSection;
4355 if (parserType != QVariant::Date) {
4356 const SectionNode sn = { MSecSection, i - add, countRepeat(newFormat, i, 3) < 3 ? 1 : 3 };
4357 newSectionNodes.append(sn);
4358 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4361 newDisplay |= MSecSection;
4366 if (parserType != QVariant::Date) {
4367 const bool cap = (sect == 'A');
4368 const SectionNode sn = { AmPmSection, i - add, (cap ? 1 : 0) };
4369 newSectionNodes.append(sn);
4370 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4371 newDisplay |= AmPmSection;
4372 if (i + 1 < newFormat.size()
4373 && newFormat.at(i+1) == (cap ? QLatin1Char('P') : QLatin1Char('p'))) {
4380 if (parserType != QVariant::Time) {
4381 const int repeat = countRepeat(newFormat, i, 4);
4383 const SectionNode sn = { repeat == 4 ? YearSection : YearSection2Digits,
4384 i - add, repeat == 4 ? 4 : 2 };
4385 newSectionNodes.append(sn);
4386 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4389 newDisplay |= sn.type;
4394 if (parserType != QVariant::Time) {
4395 const SectionNode sn = { MonthSection, i - add, countRepeat(newFormat, i, 4) };
4396 newSectionNodes.append(sn);
4397 newSeparators.append(unquote(newFormat.mid(index, i - index)));
4400 newDisplay |= MonthSection;
4404 if (parserType != QVariant::Time) {
4405 const int repeat = countRepeat(newFormat, i, 4);
4406 const SectionNode sn = { repeat >= 3 ? DayOfWeekSection : DaySection, i - add, repeat };
4407 newSectionNodes.append(sn);
4408 appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4411 newDisplay |= sn.type;
4420 if (newSectionNodes.isEmpty() && context == DateTimeEdit) {
4424 if ((newDisplay & (AmPmSection|Hour12Section)) == Hour12Section) {
4425 const int max = newSectionNodes.size();
4426 for (int i=0; i<max; ++i) {
4427 SectionNode &node = newSectionNodes[i];
4428 if (node.type == Hour12Section)
4429 node.type = Hour24Section;
4433 if (index < newFormat.size()) {
4434 appendSeparator(&newSeparators, newFormat, index, index - max, lastQuote);
4436 newSeparators.append(QString());
4439 displayFormat = newFormat;
4440 separators = newSeparators;
4441 sectionNodes = newSectionNodes;
4442 display = newDisplay;
4445 // for (int i=0; i<sectionNodes.size(); ++i) {
4446 // QDTPDEBUG << sectionName(sectionNodes.at(i).type) << sectionNodes.at(i).count;
4449 QDTPDEBUG << newFormat << displayFormat;
4450 QDTPDEBUGN("separators:\n'%s'", separators.join(QLatin1String("\n")).toLatin1().constData());
4458 Returns the size of section \a s.
4461 int QDateTimeParser::sectionSize(int sectionIndex) const
4463 if (sectionIndex < 0)
4466 if (sectionIndex >= sectionNodes.size()) {
4467 qWarning("QDateTimeParser::sectionSize Internal error (%d)", sectionIndex);
4470 if (sectionIndex == sectionNodes.size() - 1) {
4471 return displayText().size() - sectionPos(sectionIndex) - separators.last().size();
4473 return sectionPos(sectionIndex + 1) - sectionPos(sectionIndex)
4474 - separators.at(sectionIndex + 1).size();
4479 int QDateTimeParser::sectionMaxSize(Section s, int count) const
4481 #ifndef QT_NO_TEXTDATE
4488 case LastSection: return 0;
4491 const int lowerMax = qMin(getAmPmText(AmText, LowerCase).size(),
4492 getAmPmText(PmText, LowerCase).size());
4493 const int upperMax = qMin(getAmPmText(AmText, UpperCase).size(),
4494 getAmPmText(PmText, UpperCase).size());
4495 return qMin(4, qMin(lowerMax, upperMax));
4502 case DaySection: return 2;
4503 case DayOfWeekSection:
4504 #ifdef QT_NO_TEXTDATE
4514 #ifdef QT_NO_TEXTDATE
4519 const QLocale l = locale();
4520 for (int i=1; i<=mcount; ++i) {
4521 const QString str = (s == MonthSection
4522 ? l.monthName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat)
4523 : l.dayName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat));
4524 ret = qMax(str.size(), ret);
4529 case MSecSection: return 3;
4530 case YearSection: return 4;
4531 case YearSection2Digits: return 2;
4533 case CalendarPopupSection:
4535 case TimeSectionMask:
4536 case DateSectionMask:
4537 qWarning("QDateTimeParser::sectionMaxSize: Invalid section %s",
4538 sectionName(s).toLatin1().constData());
4540 case NoSectionIndex:
4541 case FirstSectionIndex:
4542 case LastSectionIndex:
4543 case CalendarPopupIndex:
4544 // these cases can't happen
4551 int QDateTimeParser::sectionMaxSize(int index) const
4553 const SectionNode &sn = sectionNode(index);
4554 return sectionMaxSize(sn.type, sn.count);
4560 Returns the text of section \a s. This function operates on the
4561 arg text rather than edit->text().
4565 QString QDateTimeParser::sectionText(const QString &text, int sectionIndex, int index) const
4567 const SectionNode &sn = sectionNode(sectionIndex);
4569 case NoSectionIndex:
4570 case FirstSectionIndex:
4571 case LastSectionIndex:
4576 return text.mid(index, sectionSize(sectionIndex));
4579 QString QDateTimeParser::sectionText(int sectionIndex) const
4581 const SectionNode &sn = sectionNode(sectionIndex);
4583 case NoSectionIndex:
4584 case FirstSectionIndex:
4585 case LastSectionIndex:
4590 return displayText().mid(sn.pos, sectionSize(sectionIndex));
4594 #ifndef QT_NO_TEXTDATE
4596 \internal:skipToNextSection
4598 Parses the part of \a text that corresponds to \a s and returns
4599 the value of that field. Sets *stateptr to the right state if
4603 int QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex,
4604 QString &text, int &cursorPosition, int index,
4605 State &state, int *usedptr) const
4609 const SectionNode &sn = sectionNode(sectionIndex);
4610 if ((sn.type & Internal) == Internal) {
4611 qWarning("QDateTimeParser::parseSection Internal error (%s %d)",
4612 qPrintable(sectionName(sn.type)), sectionIndex);
4616 const int sectionmaxsize = sectionMaxSize(sectionIndex);
4617 QString sectiontext = text.mid(index, sectionmaxsize);
4618 int sectiontextSize = sectiontext.size();
4620 QDTPDEBUG << "sectionValue for" << sectionName(sn.type)
4621 << "with text" << text << "and st" << sectiontext
4622 << text.mid(index, sectionmaxsize)
4628 const int ampm = findAmPm(sectiontext, sectionIndex, &used);
4630 case AM: // sectiontext == AM
4631 case PM: // sectiontext == PM
4635 case PossibleAM: // sectiontext => AM
4636 case PossiblePM: // sectiontext => PM
4638 state = Intermediate;
4640 case PossibleBoth: // sectiontext => AM|PM
4642 state = Intermediate;
4646 QDTPDEBUG << "invalid because findAmPm(" << sectiontext << ") returned -1";
4649 QDTPDEBUGN("This should never happen (findAmPm returned %d)", ampm);
4652 if (state != Invalid) {
4654 text.replace(index, used, sectiontext.left(used));
4658 case DayOfWeekSection:
4659 if (sn.count >= 3) {
4660 if (sn.type == MonthSection) {
4662 const QDate minDate = getMinimum().date();
4663 if (currentValue.date().year() == minDate.year()) {
4664 min = minDate.month();
4666 num = findMonth(sectiontext.toLower(), min, sectionIndex, §iontext, &used);
4668 num = findDay(sectiontext.toLower(), 1, sectionIndex, §iontext, &used);
4672 state = (used == sectiontext.size() ? Acceptable : Intermediate);
4674 text.replace(index, used, sectiontext.left(used));
4676 state = Intermediate;
4682 case YearSection2Digits:
4688 if (sectiontextSize == 0) {
4691 state = Intermediate;
4693 const int absMax = absoluteMax(sectionIndex);
4699 QString digitsStr(sectiontext);
4700 for (int i = 0; i < sectiontextSize; ++i) {
4701 if (digitsStr.at(i).isSpace()) {
4702 sectiontextSize = i;
4707 const int max = qMin(sectionmaxsize, sectiontextSize);
4708 for (int digits = max; digits >= 1; --digits) {
4709 digitsStr.truncate(digits);
4710 int tmp = (int)loc.toUInt(digitsStr, &ok);
4711 if (ok && sn.type == Hour12Section) {
4715 } else if (tmp == 12) {
4719 if (ok && tmp <= absMax) {
4720 QDTPDEBUG << sectiontext.left(digits) << tmp << digits;
4728 QChar first(sectiontext.at(0));
4729 if (separators.at(sectionIndex + 1).startsWith(first)) {
4731 state = Intermediate;
4734 QDTPDEBUG << "invalid because" << sectiontext << "can't become a uint" << last << ok;
4738 const FieldInfo fi = fieldInfo(sectionIndex);
4739 const bool done = (used == sectionmaxsize);
4740 if (!done && fi & Fraction) { // typing 2 in a zzz field should be .200, not .002
4741 for (int i=used; i<sectionmaxsize; ++i) {
4745 const int absMin = absoluteMin(sectionIndex);
4747 state = done ? Invalid : Intermediate;
4749 QDTPDEBUG << "invalid because" << num << "is less than absoluteMin" << absMin;
4750 } else if (num > absMax) {
4751 state = Intermediate;
4752 } else if (!done && (fi & (FixedWidth|Numeric)) == (FixedWidth|Numeric)) {
4753 if (skipToNextSection(sectionIndex, currentValue, digitsStr)) {
4755 const int missingZeroes = sectionmaxsize - digitsStr.size();
4756 text.insert(index, QString().fill(QLatin1Char('0'), missingZeroes));
4757 used = sectionmaxsize;
4758 cursorPosition += missingZeroes;
4760 state = Intermediate;;
4769 qWarning("QDateTimeParser::parseSection Internal error (%s %d)",
4770 qPrintable(sectionName(sn.type)), sectionIndex);
4777 return (state != Invalid ? num : -1);
4779 #endif // QT_NO_TEXTDATE
4781 #ifndef QT_NO_DATESTRING
4786 QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPosition,
4787 const QDateTime ¤tValue, bool fixup) const
4789 const QDateTime minimum = getMinimum();
4790 const QDateTime maximum = getMaximum();
4792 State state = Acceptable;
4794 QDateTime newCurrentValue;
4796 bool conflicts = false;
4797 const int sectionNodesCount = sectionNodes.size();
4799 QDTPDEBUG << "parse" << input;
4801 int year, month, day, hour12, hour, minute, second, msec, ampm, dayofweek, year2digits;
4802 getDateFromJulianDay(currentValue.date().toJulianDay(), &year, &month, &day);
4803 year2digits = year % 100;
4804 hour = currentValue.time().hour();
4806 minute = currentValue.time().minute();
4807 second = currentValue.time().second();
4808 msec = currentValue.time().msec();
4809 dayofweek = currentValue.date().dayOfWeek();
4812 Sections isSet = NoSection;
4816 for (int index=0; state != Invalid && index<sectionNodesCount; ++index) {
4817 if (QStringRef(&input, pos, separators.at(index).size()) != separators.at(index)) {
4818 QDTPDEBUG << "invalid because" << input.mid(pos, separators.at(index).size())
4819 << "!=" << separators.at(index)
4820 << index << pos << currentSectionIndex;
4824 pos += separators.at(index).size();
4825 sectionNodes[index].pos = pos;
4827 const SectionNode sn = sectionNodes.at(index);
4830 num = parseSection(currentValue, index, input, cursorPosition, pos, tmpstate, &used);
4831 QDTPDEBUG << "sectionValue" << sectionName(sectionType(index)) << input
4832 << "pos" << pos << "used" << used << stateName(tmpstate);
4833 if (fixup && tmpstate == Intermediate && used < sn.count) {
4834 const FieldInfo fi = fieldInfo(index);
4835 if ((fi & (Numeric|FixedWidth)) == (Numeric|FixedWidth)) {
4836 const QString newText = QString::fromLatin1("%1").arg(num, sn.count, 10, QLatin1Char('0'));
4837 input.replace(pos, used, newText);
4841 pos += qMax(0, used);
4843 state = qMin<State>(state, tmpstate);
4844 if (state == Intermediate && context == FromString) {
4849 QDTPDEBUG << index << sectionName(sectionType(index)) << "is set to"
4850 << pos << "state is" << stateName(state);
4853 if (state != Invalid) {
4855 case Hour24Section: current = &hour; break;
4856 case Hour12Section: current = &hour12; break;
4857 case MinuteSection: current = &minute; break;
4858 case SecondSection: current = &second; break;
4859 case MSecSection: current = &msec; break;
4860 case YearSection: current = &year; break;
4861 case YearSection2Digits: current = &year2digits; break;
4862 case MonthSection: current = &month; break;
4863 case DayOfWeekSection: current = &dayofweek; break;
4864 case DaySection: current = &day; num = qMax<int>(1, num); break;
4865 case AmPmSection: current = &m; break;
4867 qWarning("QDateTimeParser::parse Internal error (%s)",
4868 qPrintable(sectionName(sn.type)));
4872 qWarning("QDateTimeParser::parse Internal error 2");
4875 if (isSet & sn.type && *current != num) {
4876 QDTPDEBUG << "CONFLICT " << sectionName(sn.type) << *current << num;
4878 if (index != currentSectionIndex || num == -1) {
4888 if (state != Invalid && QStringRef(&input, pos, input.size() - pos) != separators.last()) {
4889 QDTPDEBUG << "invalid because" << input.mid(pos)
4890 << "!=" << separators.last() << pos;
4894 if (state != Invalid) {
4895 if (parserType != QVariant::Time) {
4896 if (year % 100 != year2digits) {
4897 switch (isSet & (YearSection2Digits|YearSection)) {
4898 case YearSection2Digits:
4899 year = (year / 100) * 100;
4900 year += year2digits;
4902 case ((uint)YearSection2Digits|(uint)YearSection): {
4904 const SectionNode &sn = sectionNode(currentSectionIndex);
4905 if (sn.type == YearSection2Digits) {
4906 year = (year / 100) * 100;
4907 year += year2digits;
4915 const QDate date(year, month, day);
4916 const int diff = dayofweek - date.dayOfWeek();
4917 if (diff != 0 && state == Acceptable && isSet & DayOfWeekSection) {
4918 conflicts = isSet & DaySection;
4919 const SectionNode &sn = sectionNode(currentSectionIndex);
4920 if (sn.type == DayOfWeekSection || currentSectionIndex == -1) {
4921 // dayofweek should be preferred
4925 } else if (day > date.daysInMonth()) {
4928 QDTPDEBUG << year << month << day << dayofweek
4929 << diff << QDate(year, month, day).dayOfWeek();
4932 bool needfixday = false;
4933 if (sectionType(currentSectionIndex) & (DaySection|DayOfWeekSection)) {
4935 } else if (cachedDay > day) {
4940 if (!QDate::isValid(year, month, day)) {
4944 if (day > 28 && QDate::isValid(year, month, 1)) {
4949 if (context == FromString) {
4953 if (state == Acceptable && fixday) {
4954 day = qMin<int>(day, QDate(year, month, 1).daysInMonth());
4956 const QLocale loc = locale();
4957 for (int i=0; i<sectionNodesCount; ++i) {
4958 if (sectionType(i) & (DaySection|DayOfWeekSection)) {
4959 input.replace(sectionPos(i), sectionSize(i), loc.toString(day));
4963 state = qMin(Intermediate, state);
4968 if (parserType != QVariant::Date) {
4969 if (isSet & Hour12Section) {
4970 const bool hasHour = isSet & Hour24Section;
4973 ampm = (hour < 12 ? 0 : 1);
4975 ampm = 0; // no way to tell if this is am or pm so I assume am
4978 hour12 = (ampm == 0 ? hour12 % 12 : (hour12 % 12) + 12);
4981 } else if (hour != hour12) {
4984 } else if (ampm != -1) {
4985 if (!(isSet & (Hour24Section))) {
4986 hour = (12 * ampm); // special case. Only ap section
4987 } else if ((ampm == 0) != (hour < 12)) {
4994 newCurrentValue = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);
4995 QDTPDEBUG << year << month << day << hour << minute << second << msec;
4997 QDTPDEBUGN("'%s' => '%s'(%s)", input.toLatin1().constData(),
4998 newCurrentValue.toString(QLatin1String("yyyy/MM/dd hh:mm:ss.zzz")).toLatin1().constData(),
4999 stateName(state).toLatin1().constData());
5002 if (newCurrentValue.isValid()) {
5003 if (context != FromString && state != Invalid && newCurrentValue < minimum) {
5004 const QLatin1Char space(' ');
5005 if (newCurrentValue >= minimum)
5006 qWarning("QDateTimeParser::parse Internal error 3 (%s %s)",
5007 qPrintable(newCurrentValue.toString()), qPrintable(minimum.toString()));
5011 for (int i=0; i<sectionNodesCount && !done; ++i) {
5012 const SectionNode &sn = sectionNodes.at(i);
5013 QString t = sectionText(input, i, sn.pos).toLower();
5014 if ((t.size() < sectionMaxSize(i) && (((int)fieldInfo(i) & (FixedWidth|Numeric)) != Numeric))
5015 || t.contains(space)) {
5018 switch (findAmPm(t, i)) {
5030 case PossibleBoth: {
5031 const QDateTime copy(newCurrentValue.addSecs(12 * 60 * 60));
5032 if (copy >= minimum && copy <= maximum) {
5033 state = Intermediate;
5039 if (sn.count >= 3) {
5040 int tmp = newCurrentValue.date().month();
5041 // I know the first possible month makes the date too early
5042 while ((tmp = findMonth(t, tmp + 1, i)) != -1) {
5043 const QDateTime copy(newCurrentValue.addMonths(tmp - newCurrentValue.date().month()));
5044 if (copy >= minimum && copy <= maximum)
5045 break; // break out of while
5050 state = Intermediate;
5059 if (sn.type & TimeSectionMask) {
5060 if (newCurrentValue.daysTo(minimum) != 0) {
5063 toMin = newCurrentValue.time().msecsTo(minimum.time());
5064 if (newCurrentValue.daysTo(maximum) > 0) {
5065 toMax = -1; // can't get to max
5067 toMax = newCurrentValue.time().msecsTo(maximum.time());
5070 toMin = newCurrentValue.daysTo(minimum);
5071 toMax = newCurrentValue.daysTo(maximum);
5073 const int maxChange = QDateTimeParser::maxChange(i);
5074 if (toMin > maxChange) {
5075 QDTPDEBUG << "invalid because toMin > maxChange" << toMin
5076 << maxChange << t << newCurrentValue << minimum;
5080 } else if (toMax > maxChange) {
5081 toMax = -1; // can't get to max
5084 const int min = getDigit(minimum, i);
5086 qWarning("QDateTimeParser::parse Internal error 4 (%s)",
5087 qPrintable(sectionName(sn.type)));
5093 int max = toMax != -1 ? getDigit(maximum, i) : absoluteMax(i, newCurrentValue);
5094 int pos = cursorPosition - sn.pos;
5095 if (pos < 0 || pos >= t.size())
5097 if (!potentialValue(t.simplified(), min, max, i, newCurrentValue, pos)) {
5098 QDTPDEBUG << "invalid because potentialValue(" << t.simplified() << min << max
5099 << sectionName(sn.type) << "returned" << toMax << toMin << pos;
5104 state = Intermediate;
5111 if (context == FromString) {
5113 Q_ASSERT(getMaximum().date().toJulianDay() == 4642999);
5114 if (newCurrentValue.date().toJulianDay() > 4642999)
5117 if (newCurrentValue > getMaximum())
5121 QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << getMinimum() << getMaximum();
5127 node.conflicts = conflicts;
5128 node.value = newCurrentValue.toTimeSpec(spec);
5132 #endif // QT_NO_DATESTRING
5134 #ifndef QT_NO_TEXTDATE
5136 \internal finds the first possible monthname that \a str1 can
5137 match. Starting from \a index; str should already by lowered
5140 int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionIndex,
5141 QString *usedMonth, int *used) const
5145 if (!str1.isEmpty()) {
5146 const SectionNode &sn = sectionNode(sectionIndex);
5147 if (sn.type != MonthSection) {
5148 qWarning("QDateTimeParser::findMonth Internal error");
5152 QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
5153 QLocale l = locale();
5155 for (int month=startMonth; month<=12; ++month) {
5156 QString str2 = l.monthName(month, type).toLower();
5158 if (str1.startsWith(str2)) {
5160 QDTPDEBUG << "used is set to" << str2.size();
5161 *used = str2.size();
5164 *usedMonth = l.monthName(month, type);
5168 if (context == FromString)
5171 const int limit = qMin(str1.size(), str2.size());
5173 QDTPDEBUG << "limit is" << limit << str1 << str2;
5175 for (int i=0; i<limit; ++i) {
5176 if (str1.at(i) != str2.at(i)) {
5178 if (i > bestCount) {
5189 *usedMonth = l.monthName(month, type);
5193 if (usedMonth && bestMatch != -1)
5194 *usedMonth = l.monthName(bestMatch, type);
5197 QDTPDEBUG << "used is set to" << bestCount;
5203 int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex, QString *usedDay, int *used) const
5207 if (!str1.isEmpty()) {
5208 const SectionNode &sn = sectionNode(sectionIndex);
5209 if (!(sn.type & (DaySection|DayOfWeekSection))) {
5210 qWarning("QDateTimeParser::findDay Internal error");
5213 const QLocale l = locale();
5214 for (int day=startDay; day<=7; ++day) {
5215 const QString str2 = l.dayName(day, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
5217 if (str1.startsWith(str2.toLower())) {
5219 *used = str2.size();
5225 if (context == FromString)
5228 const int limit = qMin(str1.size(), str2.size());
5230 for (int i=0; i<limit; ++i) {
5231 if (str1.at(i) != str2.at(i) && !str1.at(i).isSpace()) {
5232 if (i > bestCount) {
5250 if (usedDay && bestMatch != -1) {
5251 *usedDay = l.dayName(bestMatch, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
5259 #endif // QT_NO_TEXTDATE
5265 0 if str == QDateTimeEdit::tr("AM")
5266 1 if str == QDateTimeEdit::tr("PM")
5267 2 if str can become QDateTimeEdit::tr("AM")
5268 3 if str can become QDateTimeEdit::tr("PM")
5269 4 if str can become QDateTimeEdit::tr("PM") and can become QDateTimeEdit::tr("AM")
5270 -1 can't become anything sensible
5274 int QDateTimeParser::findAmPm(QString &str, int index, int *used) const
5276 const SectionNode &s = sectionNode(index);
5277 if (s.type != AmPmSection) {
5278 qWarning("QDateTimeParser::findAmPm Internal error");
5283 if (str.trimmed().isEmpty()) {
5284 return PossibleBoth;
5286 const QLatin1Char space(' ');
5287 int size = sectionMaxSize(index);
5294 ampm[amindex] = getAmPmText(AmText, s.count == 1 ? UpperCase : LowerCase);
5295 ampm[pmindex] = getAmPmText(PmText, s.count == 1 ? UpperCase : LowerCase);
5296 for (int i=0; i<2; ++i)
5297 ampm[i].truncate(size);
5299 QDTPDEBUG << "findAmPm" << str << ampm[0] << ampm[1];
5301 if (str.indexOf(ampm[amindex], 0, Qt::CaseInsensitive) == 0) {
5302 str = ampm[amindex];
5304 } else if (str.indexOf(ampm[pmindex], 0, Qt::CaseInsensitive) == 0) {
5305 str = ampm[pmindex];
5307 } else if (context == FromString || (str.count(space) == 0 && str.size() >= size)) {
5310 size = qMin(size, str.size());
5312 bool broken[2] = {false, false};
5313 for (int i=0; i<size; ++i) {
5314 if (str.at(i) != space) {
5315 for (int j=0; j<2; ++j) {
5317 int index = ampm[j].indexOf(str.at(i));
5318 QDTPDEBUG << "looking for" << str.at(i)
5319 << "in" << ampm[j] << "and got" << index;
5321 if (str.at(i).category() == QChar::Letter_Uppercase) {
5322 index = ampm[j].indexOf(str.at(i).toLower());
5323 QDTPDEBUG << "trying with" << str.at(i).toLower()
5324 << "in" << ampm[j] << "and got" << index;
5325 } else if (str.at(i).category() == QChar::Letter_Lowercase) {
5326 index = ampm[j].indexOf(str.at(i).toUpper());
5327 QDTPDEBUG << "trying with" << str.at(i).toUpper()
5328 << "in" << ampm[j] << "and got" << index;
5332 if (broken[amindex] && broken[pmindex]) {
5333 QDTPDEBUG << str << "didn't make it";
5338 str[i] = ampm[j].at(index); // fix case
5341 ampm[j].remove(index, 1);
5346 if (!broken[pmindex] && !broken[amindex])
5347 return PossibleBoth;
5348 return (!broken[amindex] ? PossibleAM : PossiblePM);
5353 Max number of units that can be changed by this section.
5356 int QDateTimeParser::maxChange(int index) const
5358 const SectionNode &sn = sectionNode(index);
5360 // Time. unit is msec
5361 case MSecSection: return 999;
5362 case SecondSection: return 59 * 1000;
5363 case MinuteSection: return 59 * 60 * 1000;
5364 case Hour24Section: case Hour12Section: return 59 * 60 * 60 * 1000;
5366 // Date. unit is day
5367 case DayOfWeekSection: return 7;
5368 case DaySection: return 30;
5369 case MonthSection: return 365 - 31;
5370 case YearSection: return 9999 * 365;
5371 case YearSection2Digits: return 100 * 365;
5373 qWarning("QDateTimeParser::maxChange() Internal error (%s)",
5374 qPrintable(sectionName(sectionType(index))));
5380 QDateTimeParser::FieldInfo QDateTimeParser::fieldInfo(int index) const
5383 const SectionNode &sn = sectionNode(index);
5384 const Section s = sn.type;
5394 case YearSection2Digits:
5396 if (s != YearSection) {
5397 ret |= AllowPartial;
5399 if (sn.count != 1) {
5410 ret |= (Numeric|AllowPartial);
5414 case DayOfWeekSection:
5422 qWarning("QDateTimeParser::fieldInfo Internal error 2 (%d %s %d)",
5423 index, qPrintable(sectionName(sn.type)), sn.count);
5430 \internal Get a number that str can become which is between min
5431 and max or -1 if this is not possible.
5435 QString QDateTimeParser::sectionFormat(int index) const
5437 const SectionNode &sn = sectionNode(index);
5438 return sectionFormat(sn.type, sn.count);
5441 QString QDateTimeParser::sectionFormat(Section s, int count) const
5445 case AmPmSection: return count == 1 ? QLatin1String("AP") : QLatin1String("ap");
5446 case MSecSection: fillChar = QLatin1Char('z'); break;
5447 case SecondSection: fillChar = QLatin1Char('s'); break;
5448 case MinuteSection: fillChar = QLatin1Char('m'); break;
5449 case Hour24Section: fillChar = QLatin1Char('H'); break;
5450 case Hour12Section: fillChar = QLatin1Char('h'); break;
5451 case DayOfWeekSection:
5452 case DaySection: fillChar = QLatin1Char('d'); break;
5453 case MonthSection: fillChar = QLatin1Char('M'); break;
5454 case YearSection2Digits:
5455 case YearSection: fillChar = QLatin1Char('y'); break;
5457 qWarning("QDateTimeParser::sectionFormat Internal error (%s)",
5458 qPrintable(sectionName(s)));
5461 if (fillChar.isNull()) {
5462 qWarning("QDateTimeParser::sectionFormat Internal error 2");
5467 str.fill(fillChar, count);
5472 /*! \internal Returns true if str can be modified to represent a
5473 number that is within min and max.
5476 bool QDateTimeParser::potentialValue(const QString &str, int min, int max, int index,
5477 const QDateTime ¤tValue, int insert) const
5479 if (str.isEmpty()) {
5482 const int size = sectionMaxSize(index);
5483 int val = (int)locale().toUInt(str);
5484 const SectionNode &sn = sectionNode(index);
5485 if (sn.type == YearSection2Digits) {
5486 val += currentValue.date().year() - (currentValue.date().year() % 100);
5488 if (val >= min && val <= max && str.size() == size) {
5490 } else if (val > max) {
5492 } else if (str.size() == size && val < min) {
5496 const int len = size - str.size();
5497 for (int i=0; i<len; ++i) {
5498 for (int j=0; j<10; ++j) {
5499 if (potentialValue(str + QLatin1Char('0' + j), min, max, index, currentValue, insert)) {
5501 } else if (insert >= 0) {
5503 tmp.insert(insert, QLatin1Char('0' + j));
5504 if (potentialValue(tmp, min, max, index, currentValue, insert))
5513 bool QDateTimeParser::skipToNextSection(int index, const QDateTime ¤t, const QString &text) const
5515 Q_ASSERT(current >= getMinimum() && current <= getMaximum());
5517 const SectionNode &node = sectionNode(index);
5518 Q_ASSERT(text.size() < sectionMaxSize(index));
5520 const QDateTime maximum = getMaximum();
5521 const QDateTime minimum = getMinimum();
5522 QDateTime tmp = current;
5523 int min = absoluteMin(index);
5524 setDigit(tmp, index, min);
5525 if (tmp < minimum) {
5526 min = getDigit(minimum, index);
5529 int max = absoluteMax(index, current);
5530 setDigit(tmp, index, max);
5531 if (tmp > maximum) {
5532 max = getDigit(maximum, index);
5534 int pos = cursorPosition() - node.pos;
5535 if (pos < 0 || pos >= text.size())
5538 const bool potential = potentialValue(text, min, max, index, current, pos);
5541 /* If the value potentially can become another valid entry we
5542 * don't want to skip to the next. E.g. In a M field (month
5543 * without leading 0 if you type 1 we don't want to autoskip but
5544 * if you type 3 we do
5550 For debugging. Returns the name of the section \a s.
5553 QString QDateTimeParser::sectionName(int s) const
5556 case QDateTimeParser::AmPmSection: return QLatin1String("AmPmSection");
5557 case QDateTimeParser::DaySection: return QLatin1String("DaySection");
5558 case QDateTimeParser::DayOfWeekSection: return QLatin1String("DayOfWeekSection");
5559 case QDateTimeParser::Hour24Section: return QLatin1String("Hour24Section");
5560 case QDateTimeParser::Hour12Section: return QLatin1String("Hour12Section");
5561 case QDateTimeParser::MSecSection: return QLatin1String("MSecSection");
5562 case QDateTimeParser::MinuteSection: return QLatin1String("MinuteSection");
5563 case QDateTimeParser::MonthSection: return QLatin1String("MonthSection");
5564 case QDateTimeParser::SecondSection: return QLatin1String("SecondSection");
5565 case QDateTimeParser::YearSection: return QLatin1String("YearSection");
5566 case QDateTimeParser::YearSection2Digits: return QLatin1String("YearSection2Digits");
5567 case QDateTimeParser::NoSection: return QLatin1String("NoSection");
5568 case QDateTimeParser::FirstSection: return QLatin1String("FirstSection");
5569 case QDateTimeParser::LastSection: return QLatin1String("LastSection");
5570 default: return QLatin1String("Unknown section ") + QString::number(s);
5576 For debugging. Returns the name of the state \a s.
5579 QString QDateTimeParser::stateName(int s) const
5582 case Invalid: return QLatin1String("Invalid");
5583 case Intermediate: return QLatin1String("Intermediate");
5584 case Acceptable: return QLatin1String("Acceptable");
5585 default: return QLatin1String("Unknown state ") + QString::number(s);
5589 #ifndef QT_NO_DATESTRING
5590 bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) const
5592 QDateTime val(QDate(1900, 1, 1), QDATETIMEEDIT_TIME_MIN);
5595 const StateNode tmp = parse(text, copy, val, false);
5596 if (tmp.state != Acceptable || tmp.conflicts) {
5600 const QTime t = tmp.value.time();
5608 const QDate d = tmp.value.date();
5616 #endif // QT_NO_DATESTRING
5618 QDateTime QDateTimeParser::getMinimum() const
5620 return QDateTime(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN, spec);
5623 QDateTime QDateTimeParser::getMaximum() const
5625 return QDateTime(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX, spec);
5628 QString QDateTimeParser::getAmPmText(AmPm ap, Case cs) const
5631 return (cs == UpperCase ? QLatin1String("AM") : QLatin1String("am"));
5633 return (cs == UpperCase ? QLatin1String("PM") : QLatin1String("pm"));
5640 I give arg2 preference because arg1 is always a QDateTime.
5643 bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::SectionNode &s2)
5645 return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count);
5648 #endif // QT_BOOTSTRAPPED