src/corelib/tools/qdatetime.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtCore module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qplatformdefs.h"
       
    43 #include "private/qdatetime_p.h"
       
    44 
       
    45 #include "qdatastream.h"
       
    46 #include "qset.h"
       
    47 #include "qlocale.h"
       
    48 #include "qdatetime.h"
       
    49 #include "qregexp.h"
       
    50 #include "qdebug.h"
       
    51 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
       
    52 #include <qt_windows.h>
       
    53 #endif
       
    54 #ifndef Q_WS_WIN
       
    55 #include <locale.h>
       
    56 #endif
       
    57 
       
    58 #include <time.h>
       
    59 #if defined(Q_OS_WINCE)
       
    60 #include "qfunctions_wince.h"
       
    61 #endif
       
    62 
       
    63 //#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
       
    67 #else
       
    68 #  define QDTPDEBUG if (false) qDebug()
       
    69 #  define QDTPDEBUGN if (false) qDebug
       
    70 #endif
       
    71 
       
    72 #if defined(Q_WS_MAC)
       
    73 #include <private/qcore_mac_p.h>
       
    74 #endif
       
    75 
       
    76 #if defined(Q_OS_SYMBIAN)
       
    77 #include <e32std.h>
       
    78 #endif
       
    79 
       
    80 QT_BEGIN_NAMESPACE
       
    81 
       
    82 enum {
       
    83     FIRST_YEAR = -4713,
       
    84     FIRST_MONTH = 1,
       
    85     FIRST_DAY = 2,  // ### Qt 5: make FIRST_DAY = 1, by support jd == 0 as valid
       
    86     SECS_PER_DAY = 86400,
       
    87     MSECS_PER_DAY = 86400000,
       
    88     SECS_PER_HOUR = 3600,
       
    89     MSECS_PER_HOUR = 3600000,
       
    90     SECS_PER_MIN = 60,
       
    91     MSECS_PER_MIN = 60000
       
    92 };
       
    93 
       
    94 static inline QDate fixedDate(int y, int m, int d)
       
    95 {
       
    96     QDate result(y, m, 1);
       
    97     result.setDate(y, m, qMin(d, result.daysInMonth()));
       
    98     return result;
       
    99 }
       
   100 
       
   101 static uint julianDayFromDate(int year, int month, int day)
       
   102 {
       
   103     if (year < 0)
       
   104         ++year;
       
   105 
       
   106     if (year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15)))) {
       
   107         // Gregorian calendar starting from October 15, 1582
       
   108         // Algorithm from Henry F. Fliegel and Thomas C. Van Flandern
       
   109         return (1461 * (year + 4800 + (month - 14) / 12)) / 4
       
   110                + (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12
       
   111                - (3 * ((year + 4900 + (month - 14) / 12) / 100)) / 4
       
   112                + day - 32075;
       
   113     } else if (year < 1582 || (year == 1582 && (month < 10 || (month == 10 && day <= 4)))) {
       
   114         // Julian calendar until October 4, 1582
       
   115         // Algorithm from Frequently Asked Questions about Calendars by Claus Toendering
       
   116         int a = (14 - month) / 12;
       
   117         return (153 * (month + (12 * a) - 3) + 2) / 5
       
   118                + (1461 * (year + 4800 - a)) / 4
       
   119                + day - 32083;
       
   120     } else {
       
   121         // the day following October 4, 1582 is October 15, 1582
       
   122         return 0;
       
   123     }
       
   124 }
       
   125 
       
   126 static void getDateFromJulianDay(uint julianDay, int *year, int *month, int *day)
       
   127 {
       
   128     int y, m, d;
       
   129 
       
   130     if (julianDay >= 2299161) {
       
   131         // Gregorian calendar starting from October 15, 1582
       
   132         // This algorithm is from Henry F. Fliegel and Thomas C. Van Flandern
       
   133         qulonglong ell, n, i, j;
       
   134         ell = qulonglong(julianDay) + 68569;
       
   135         n = (4 * ell) / 146097;
       
   136         ell = ell - (146097 * n + 3) / 4;
       
   137         i = (4000 * (ell + 1)) / 1461001;
       
   138         ell = ell - (1461 * i) / 4 + 31;
       
   139         j = (80 * ell) / 2447;
       
   140         d = ell - (2447 * j) / 80;
       
   141         ell = j / 11;
       
   142         m = j + 2 - (12 * ell);
       
   143         y = 100 * (n - 49) + i + ell;
       
   144     } else {
       
   145         // Julian calendar until October 4, 1582
       
   146         // Algorithm from Frequently Asked Questions about Calendars by Claus Toendering
       
   147         julianDay += 32082;
       
   148         int dd = (4 * julianDay + 3) / 1461;
       
   149         int ee = julianDay - (1461 * dd) / 4;
       
   150         int mm = ((5 * ee) + 2) / 153;
       
   151         d = ee - (153 * mm + 2) / 5 + 1;
       
   152         m = mm + 3 - 12 * (mm / 10);
       
   153         y = dd - 4800 + (mm / 10);
       
   154         if (y <= 0)
       
   155             --y;
       
   156     }
       
   157     if (year)
       
   158         *year = y;
       
   159     if (month)
       
   160         *month = m;
       
   161     if (day)
       
   162         *day = d;
       
   163 }
       
   164 
       
   165 
       
   166 static const char monthDays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
       
   167 
       
   168 #ifndef QT_NO_TEXTDATE
       
   169 static const char * const qt_shortMonthNames[] = {
       
   170     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
       
   171     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
       
   172 #endif
       
   173 #ifndef QT_NO_DATESTRING
       
   174 static QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* dd = 0);
       
   175 #endif
       
   176 
       
   177 /*****************************************************************************
       
   178   QDate member functions
       
   179  *****************************************************************************/
       
   180 
       
   181 /*!
       
   182     \since 4.5
       
   183 
       
   184     \enum QDate::MonthNameType
       
   185 
       
   186     This enum describes the types of the string representation used
       
   187     for the month name.
       
   188 
       
   189     \value DateFormat This type of name can be used for date-to-string formatting.
       
   190     \value StandaloneFormat This type is used when you need to enumerate months or weekdays.
       
   191            Usually standalone names are represented in singular forms with
       
   192            capitalized first letter.
       
   193 */
       
   194 
       
   195 /*!
       
   196     \class QDate
       
   197     \reentrant
       
   198     \brief The QDate class provides date functions.
       
   199 
       
   200 
       
   201     A QDate object contains a calendar date, i.e. year, month, and day
       
   202     numbers, in the Gregorian calendar. (see \l{QDate G and J} {Use of
       
   203     Gregorian and Julian Calendars} for dates prior to 15 October
       
   204     1582). It can read the current date from the system clock. It
       
   205     provides functions for comparing dates, and for manipulating
       
   206     dates. For example, it is possible to add and subtract days,
       
   207     months, and years to dates.
       
   208 
       
   209     A QDate object is typically created either by giving the year,
       
   210     month, and day numbers explicitly. Note that QDate interprets two
       
   211     digit years as is, i.e., years 0 - 99. A QDate can also be
       
   212     constructed with the static function currentDate(), which creates
       
   213     a QDate object containing the system clock's date.  An explicit
       
   214     date can also be set using setDate(). The fromString() function
       
   215     returns a QDate given a string and a date format which is used to
       
   216     interpret the date within the string.
       
   217 
       
   218     The year(), month(), and day() functions provide access to the
       
   219     year, month, and day numbers. Also, dayOfWeek() and dayOfYear()
       
   220     functions are provided. The same information is provided in
       
   221     textual format by the toString(), shortDayName(), longDayName(),
       
   222     shortMonthName(), and longMonthName() functions.
       
   223 
       
   224     QDate provides a full set of operators to compare two QDate
       
   225     objects where smaller means earlier, and larger means later.
       
   226 
       
   227     You can increment (or decrement) a date by a given number of days
       
   228     using addDays(). Similarly you can use addMonths() and addYears().
       
   229     The daysTo() function returns the number of days between two
       
   230     dates.
       
   231 
       
   232     The daysInMonth() and daysInYear() functions return how many days
       
   233     there are in this date's month and year, respectively. The
       
   234     isLeapYear() function indicates whether a date is in a leap year.
       
   235 
       
   236     \section1
       
   237 
       
   238     \target QDate G and J
       
   239     \section2 Use of Gregorian and Julian Calendars
       
   240 
       
   241     QDate uses the Gregorian calendar in all locales, beginning
       
   242     on the date 15 October 1582. For dates up to and including 4
       
   243     October 1582, the Julian calendar is used.  This means there is a
       
   244     10-day gap in the internal calendar between the 4th and the 15th
       
   245     of October 1582. When you use QDateTime for dates in that epoch,
       
   246     the day after 4 October 1582 is 15 October 1582, and the dates in
       
   247     the gap are invalid.
       
   248 
       
   249     The Julian to Gregorian changeover date used here is the date when
       
   250     the Gregorian calendar was first introduced, by Pope Gregory
       
   251     XIII. That change was not universally accepted and some localities
       
   252     only executed it at a later date (if at all).  QDateTime
       
   253     doesn't take any of these historical facts into account. If an
       
   254     application must support a locale-specific dating system, it must
       
   255     do so on its own, remembering to convert the dates using the
       
   256     Julian day.
       
   257 
       
   258     \section2 No Year 0
       
   259 
       
   260     There is no year 0. Dates in that year are considered invalid. The
       
   261     year -1 is the year "1 before Christ" or "1 before current era."
       
   262     The day before 0001-01-01 is December 31st, 1 BCE.
       
   263 
       
   264     \section2 Range of Valid Dates
       
   265 
       
   266     The range of valid dates is from January 2nd, 4713 BCE, to
       
   267     sometime in the year 11 million CE. The Julian Day returned by
       
   268     QDate::toJulianDay() is a number in the contiguous range from 1 to
       
   269     \e{overflow}, even across QDateTime's "date holes". It is suitable
       
   270     for use in applications that must convert a QDateTime to a date in
       
   271     another calendar system, e.g., Hebrew, Islamic or Chinese.
       
   272 
       
   273     \sa QTime, QDateTime, QDateEdit, QDateTimeEdit, QCalendarWidget
       
   274 */
       
   275 
       
   276 /*!
       
   277     \fn QDate::QDate()
       
   278 
       
   279     Constructs a null date. Null dates are invalid.
       
   280 
       
   281     \sa isNull(), isValid()
       
   282 */
       
   283 
       
   284 /*!
       
   285     Constructs a date with year \a y, month \a m and day \a d.
       
   286 
       
   287     If the specified date is invalid, the date is not set and
       
   288     isValid() returns false. A date before 2 January 4713 B.C. is
       
   289     considered invalid.
       
   290 
       
   291     \warning Years 0 to 99 are interpreted as is, i.e., years
       
   292              0-99.
       
   293 
       
   294     \sa isValid()
       
   295 */
       
   296 
       
   297 QDate::QDate(int y, int m, int d)
       
   298 {
       
   299     setDate(y, m, d);
       
   300 }
       
   301 
       
   302 
       
   303 /*!
       
   304     \fn bool QDate::isNull() const
       
   305 
       
   306     Returns true if the date is null; otherwise returns false. A null
       
   307     date is invalid.
       
   308 
       
   309     \note The behavior of this function is equivalent to isValid().
       
   310 
       
   311     \sa isValid()
       
   312 */
       
   313 
       
   314 
       
   315 /*!
       
   316     Returns true if this date is valid; otherwise returns false.
       
   317 
       
   318     \sa isNull()
       
   319 */
       
   320 
       
   321 bool QDate::isValid() const
       
   322 {
       
   323     return !isNull();
       
   324 }
       
   325 
       
   326 
       
   327 /*!
       
   328     Returns the year of this date. Negative numbers indicate years
       
   329     before 1 A.D. = 1 C.E., such that year -44 is 44 B.C.
       
   330 
       
   331     \sa month(), day()
       
   332 */
       
   333 
       
   334 int QDate::year() const
       
   335 {
       
   336     int y;
       
   337     getDateFromJulianDay(jd, &y, 0, 0);
       
   338     return y;
       
   339 }
       
   340 
       
   341 /*!
       
   342     Returns the number corresponding to the month of this date, using
       
   343     the following convention:
       
   344 
       
   345     \list
       
   346     \i 1 = "January"
       
   347     \i 2 = "February"
       
   348     \i 3 = "March"
       
   349     \i 4 = "April"
       
   350     \i 5 = "May"
       
   351     \i 6 = "June"
       
   352     \i 7 = "July"
       
   353     \i 8 = "August"
       
   354     \i 9 = "September"
       
   355     \i 10 = "October"
       
   356     \i 11 = "November"
       
   357     \i 12 = "December"
       
   358     \endlist
       
   359 
       
   360     \sa year(), day()
       
   361 */
       
   362 
       
   363 int QDate::month() const
       
   364 {
       
   365     int m;
       
   366     getDateFromJulianDay(jd, 0, &m, 0);
       
   367     return m;
       
   368 }
       
   369 
       
   370 /*!
       
   371     Returns the day of the month (1 to 31) of this date.
       
   372 
       
   373     \sa year(), month(), dayOfWeek()
       
   374 */
       
   375 
       
   376 int QDate::day() const
       
   377 {
       
   378     int d;
       
   379     getDateFromJulianDay(jd, 0, 0, &d);
       
   380     return d;
       
   381 }
       
   382 
       
   383 /*!
       
   384     Returns the weekday (1 to 7) for this date.
       
   385 
       
   386     \sa day(), dayOfYear(), Qt::DayOfWeek
       
   387 */
       
   388 
       
   389 int QDate::dayOfWeek() const
       
   390 {
       
   391     return (jd % 7) + 1;
       
   392 }
       
   393 
       
   394 /*!
       
   395     Returns the day of the year (1 to 365 or 366 on leap years) for
       
   396     this date.
       
   397 
       
   398     \sa day(), dayOfWeek()
       
   399 */
       
   400 
       
   401 int QDate::dayOfYear() const
       
   402 {
       
   403     return jd - julianDayFromDate(year(), 1, 1) + 1;
       
   404 }
       
   405 
       
   406 /*!
       
   407     Returns the number of days in the month (28 to 31) for this date.
       
   408 
       
   409     \sa day(), daysInYear()
       
   410 */
       
   411 
       
   412 int QDate::daysInMonth() const
       
   413 {
       
   414     int y, m, d;
       
   415     getDateFromJulianDay(jd, &y, &m, &d);
       
   416     if (m == 2 && isLeapYear(y))
       
   417         return 29;
       
   418     else
       
   419         return monthDays[m];
       
   420 }
       
   421 
       
   422 /*!
       
   423     Returns the number of days in the year (365 or 366) for this date.
       
   424 
       
   425     \sa day(), daysInMonth()
       
   426 */
       
   427 
       
   428 int QDate::daysInYear() const
       
   429 {
       
   430     int y, m, d;
       
   431     getDateFromJulianDay(jd, &y, &m, &d);
       
   432     return isLeapYear(y) ? 366 : 365;
       
   433 }
       
   434 
       
   435 /*!
       
   436     Returns the week number (1 to 53), and stores the year in
       
   437     *\a{yearNumber} unless \a yearNumber is null (the default).
       
   438 
       
   439     Returns 0 if the date is invalid.
       
   440 
       
   441     In accordance with ISO 8601, weeks start on Monday and the first
       
   442     Thursday of a year is always in week 1 of that year. Most years
       
   443     have 52 weeks, but some have 53.
       
   444 
       
   445     *\a{yearNumber} is not always the same as year(). For example, 1
       
   446     January 2000 has week number 52 in the year 1999, and 31 December
       
   447     2002 has week number 1 in the year 2003.
       
   448 
       
   449     \legalese
       
   450     Copyright (c) 1989 The Regents of the University of California.
       
   451     All rights reserved.
       
   452 
       
   453     Redistribution and use in source and binary forms are permitted
       
   454     provided that the above copyright notice and this paragraph are
       
   455     duplicated in all such forms and that any documentation,
       
   456     advertising materials, and other materials related to such
       
   457     distribution and use acknowledge that the software was developed
       
   458     by the University of California, Berkeley.  The name of the
       
   459     University may not be used to endorse or promote products derived
       
   460     from this software without specific prior written permission.
       
   461     THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
       
   462     IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
       
   463     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
       
   464 
       
   465     \sa isValid()
       
   466 */
       
   467 
       
   468 int QDate::weekNumber(int *yearNumber) const
       
   469 {
       
   470     if (!isValid())
       
   471         return 0;
       
   472 
       
   473     int year = QDate::year();
       
   474     int yday = dayOfYear() - 1;
       
   475     int wday = dayOfWeek();
       
   476     if (wday == 7)
       
   477         wday = 0;
       
   478     int w;
       
   479 
       
   480     for (;;) {
       
   481         int len;
       
   482         int bot;
       
   483         int top;
       
   484 
       
   485         len = isLeapYear(year) ? 366 : 365;
       
   486         /*
       
   487         ** What yday (-3 ... 3) does
       
   488         ** the ISO year begin on?
       
   489         */
       
   490         bot = ((yday + 11 - wday) % 7) - 3;
       
   491         /*
       
   492         ** What yday does the NEXT
       
   493         ** ISO year begin on?
       
   494         */
       
   495         top = bot - (len % 7);
       
   496         if (top < -3)
       
   497             top += 7;
       
   498         top += len;
       
   499         if (yday >= top) {
       
   500             ++year;
       
   501             w = 1;
       
   502             break;
       
   503         }
       
   504         if (yday >= bot) {
       
   505             w = 1 + ((yday - bot) / 7);
       
   506             break;
       
   507         }
       
   508         --year;
       
   509         yday += isLeapYear(year) ? 366 : 365;
       
   510     }
       
   511     if (yearNumber != 0)
       
   512         *yearNumber = year;
       
   513     return w;
       
   514 }
       
   515 
       
   516 #ifndef QT_NO_TEXTDATE
       
   517 /*!
       
   518     \since 4.5
       
   519 
       
   520     Returns the short name of the \a month for the representation specified
       
   521     by \a type.
       
   522 
       
   523     The months are enumerated using the following convention:
       
   524 
       
   525     \list
       
   526     \i 1 = "Jan"
       
   527     \i 2 = "Feb"
       
   528     \i 3 = "Mar"
       
   529     \i 4 = "Apr"
       
   530     \i 5 = "May"
       
   531     \i 6 = "Jun"
       
   532     \i 7 = "Jul"
       
   533     \i 8 = "Aug"
       
   534     \i 9 = "Sep"
       
   535     \i 10 = "Oct"
       
   536     \i 11 = "Nov"
       
   537     \i 12 = "Dec"
       
   538     \endlist
       
   539 
       
   540     The month names will be localized according to the system's locale
       
   541     settings.
       
   542 
       
   543     \sa toString(), longMonthName(), shortDayName(), longDayName()
       
   544 */
       
   545 
       
   546 QString QDate::shortMonthName(int month, QDate::MonthNameType type)
       
   547 {
       
   548     if (month < 1 || month > 12) {
       
   549         month = 1;
       
   550     }
       
   551     switch (type) {
       
   552     case QDate::DateFormat:
       
   553         return QLocale::system().monthName(month, QLocale::ShortFormat);
       
   554     case QDate::StandaloneFormat:
       
   555         return QLocale::system().standaloneMonthName(month, QLocale::ShortFormat);
       
   556     default:
       
   557         break;
       
   558     }
       
   559     return QString();
       
   560 }
       
   561 
       
   562 /*!
       
   563     Returns the short version of the name of the \a month. The
       
   564     returned name is in normal type which can be used for date formatting.
       
   565 
       
   566     \sa toString(), longMonthName(), shortDayName(), longDayName()
       
   567  */
       
   568 
       
   569 QString QDate::shortMonthName(int month)
       
   570 {
       
   571     return shortMonthName(month, QDate::DateFormat);
       
   572 }
       
   573 
       
   574 /*!
       
   575     \since 4.5
       
   576 
       
   577     Returns the long name of the \a month for the representation specified
       
   578     by \a type.
       
   579 
       
   580     The months are enumerated using the following convention:
       
   581 
       
   582     \list
       
   583     \i 1 = "January"
       
   584     \i 2 = "February"
       
   585     \i 3 = "March"
       
   586     \i 4 = "April"
       
   587     \i 5 = "May"
       
   588     \i 6 = "June"
       
   589     \i 7 = "July"
       
   590     \i 8 = "August"
       
   591     \i 9 = "September"
       
   592     \i 10 = "October"
       
   593     \i 11 = "November"
       
   594     \i 12 = "December"
       
   595     \endlist
       
   596 
       
   597     The month names will be localized according to the system's locale
       
   598     settings.
       
   599 
       
   600     \sa toString(), shortMonthName(), shortDayName(), longDayName()
       
   601 */
       
   602 
       
   603 QString QDate::longMonthName(int month, MonthNameType type)
       
   604 {
       
   605     if (month < 1 || month > 12) {
       
   606         month = 1;
       
   607     }
       
   608     switch (type) {
       
   609     case QDate::DateFormat:
       
   610         return QLocale::system().monthName(month, QLocale::LongFormat);
       
   611     case QDate::StandaloneFormat:
       
   612         return QLocale::system().standaloneMonthName(month, QLocale::LongFormat);
       
   613     default:
       
   614         break;
       
   615     }
       
   616     return QString();
       
   617 }
       
   618 
       
   619 /*!
       
   620     Returns the long version of the name of the \a month. The
       
   621     returned name is in normal type which can be used for date formatting.
       
   622 
       
   623     \sa toString(), shortMonthName(), shortDayName(), longDayName()
       
   624  */
       
   625 
       
   626 QString QDate::longMonthName(int month)
       
   627 {
       
   628     if (month < 1 || month > 12) {
       
   629         month = 1;
       
   630     }
       
   631     return QLocale::system().monthName(month, QLocale::LongFormat);
       
   632 }
       
   633 
       
   634 /*!
       
   635     \since 4.5
       
   636 
       
   637     Returns the short name of the \a weekday for the representation specified
       
   638     by \a type.
       
   639 
       
   640     The days are enumerated using the following convention:
       
   641 
       
   642     \list
       
   643     \i 1 = "Mon"
       
   644     \i 2 = "Tue"
       
   645     \i 3 = "Wed"
       
   646     \i 4 = "Thu"
       
   647     \i 5 = "Fri"
       
   648     \i 6 = "Sat"
       
   649     \i 7 = "Sun"
       
   650     \endlist
       
   651 
       
   652     The day names will be localized according to the system's locale
       
   653     settings.
       
   654 
       
   655     \sa toString(), shortMonthName(), longMonthName(), longDayName()
       
   656 */
       
   657 
       
   658 QString QDate::shortDayName(int weekday, MonthNameType type)
       
   659 {
       
   660     if (weekday < 1 || weekday > 7) {
       
   661         weekday = 1;
       
   662     }
       
   663     switch (type) {
       
   664     case QDate::DateFormat:
       
   665         return QLocale::system().dayName(weekday, QLocale::ShortFormat);
       
   666     case QDate::StandaloneFormat:
       
   667         return QLocale::system().standaloneDayName(weekday, QLocale::ShortFormat);
       
   668     default:
       
   669         break;
       
   670     }
       
   671     return QString();
       
   672 }
       
   673 
       
   674 /*!
       
   675     Returns the short version of the name of the \a weekday. The
       
   676     returned name is in normal type which can be used for date formatting.
       
   677 
       
   678     \sa toString(), longDayName(), shortMonthName(), longMonthName()
       
   679  */
       
   680 
       
   681 QString QDate::shortDayName(int weekday)
       
   682 {
       
   683     if (weekday < 1 || weekday > 7) {
       
   684         weekday = 1;
       
   685     }
       
   686     return QLocale::system().dayName(weekday, QLocale::ShortFormat);
       
   687 }
       
   688 
       
   689 /*!
       
   690     \since 4.5
       
   691 
       
   692     Returns the long name of the \a weekday for the representation specified
       
   693     by \a type.
       
   694 
       
   695     The days are enumerated using the following convention:
       
   696 
       
   697     \list
       
   698     \i 1 = "Monday"
       
   699     \i 2 = "Tuesday"
       
   700     \i 3 = "Wednesday"
       
   701     \i 4 = "Thursday"
       
   702     \i 5 = "Friday"
       
   703     \i 6 = "Saturday"
       
   704     \i 7 = "Sunday"
       
   705     \endlist
       
   706 
       
   707     The day names will be localized according to the system's locale
       
   708     settings.
       
   709 
       
   710     \sa toString(), shortDayName(), shortMonthName(), longMonthName()
       
   711 */
       
   712 
       
   713 QString QDate::longDayName(int weekday, MonthNameType type)
       
   714 {
       
   715     if (weekday < 1 || weekday > 7) {
       
   716         weekday = 1;
       
   717     }
       
   718     switch (type) {
       
   719     case QDate::DateFormat:
       
   720         return QLocale::system().dayName(weekday, QLocale::LongFormat);
       
   721     case QDate::StandaloneFormat:
       
   722         return QLocale::system().standaloneDayName(weekday, QLocale::LongFormat);
       
   723     default:
       
   724         break;
       
   725     }
       
   726     return QLocale::system().dayName(weekday, QLocale::LongFormat);
       
   727 }
       
   728 
       
   729 /*!
       
   730     Returns the long version of the name of the \a weekday. The
       
   731     returned name is in normal type which can be used for date formatting.
       
   732 
       
   733     \sa toString(), shortDayName(), shortMonthName(), longMonthName()
       
   734  */
       
   735 
       
   736 QString QDate::longDayName(int weekday)
       
   737 {
       
   738     if (weekday < 1 || weekday > 7) {
       
   739         weekday = 1;
       
   740     }
       
   741     return QLocale::system().dayName(weekday, QLocale::LongFormat);
       
   742 }
       
   743 #endif //QT_NO_TEXTDATE
       
   744 
       
   745 #ifndef QT_NO_DATESTRING
       
   746 
       
   747 /*!
       
   748     \fn QString QDate::toString(Qt::DateFormat format) const
       
   749 
       
   750     \overload
       
   751 
       
   752     Returns the date as a string. The \a format parameter determines
       
   753     the format of the string.
       
   754 
       
   755     If the \a format is Qt::TextDate, the string is formatted in
       
   756     the default way. QDate::shortDayName() and QDate::shortMonthName()
       
   757     are used to generate the string, so the day and month names will
       
   758     be localized names. An example of this formatting is
       
   759     "Sat May 20 1995".
       
   760 
       
   761     If the \a format is Qt::ISODate, the string format corresponds
       
   762     to the ISO 8601 extended specification for representations of
       
   763     dates and times, taking the form YYYY-MM-DD, where YYYY is the
       
   764     year, MM is the month of the year (between 01 and 12), and DD is
       
   765     the day of the month between 01 and 31.
       
   766 
       
   767     If the \a format is Qt::SystemLocaleShortDate or
       
   768     Qt::SystemLocaleLongDate, the string format depends on the locale
       
   769     settings of the system. Identical to calling
       
   770     QLocale::system().toString(date, QLocale::ShortFormat) or
       
   771     QLocale::system().toString(date, QLocale::LongFormat).
       
   772 
       
   773     If the \a format is Qt::DefaultLocaleShortDate or
       
   774     Qt::DefaultLocaleLongDate, the string format depends on the
       
   775     default application locale. This is the locale set with
       
   776     QLocale::setDefault(), or the system locale if no default locale
       
   777     has been set. Identical to calling QLocale().toString(date,
       
   778     QLocale::ShortFormat) or QLocale().toString(date,
       
   779     QLocale::LongFormat).
       
   780 
       
   781     If the date is invalid, an empty string will be returned.
       
   782 
       
   783     \warning The Qt::ISODate format is only valid for years in the
       
   784     range 0 to 9999. This restriction may apply to locale-aware
       
   785     formats as well, depending on the locale settings.
       
   786 
       
   787     \sa shortDayName(), shortMonthName()
       
   788 */
       
   789 QString QDate::toString(Qt::DateFormat f) const
       
   790 {
       
   791     if (!isValid())
       
   792         return QString();
       
   793     int y, m, d;
       
   794     getDateFromJulianDay(jd, &y, &m, &d);
       
   795     switch (f) {
       
   796     case Qt::SystemLocaleDate:
       
   797     case Qt::SystemLocaleShortDate:
       
   798     case Qt::SystemLocaleLongDate:
       
   799         return QLocale::system().toString(*this, f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
       
   800                                                                                : QLocale::ShortFormat);
       
   801     case Qt::LocaleDate:
       
   802     case Qt::DefaultLocaleShortDate:
       
   803     case Qt::DefaultLocaleLongDate:
       
   804         return QLocale().toString(*this, f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
       
   805                                                                         : QLocale::ShortFormat);
       
   806     default:
       
   807 #ifndef QT_NO_TEXTDATE
       
   808     case Qt::TextDate:
       
   809         {
       
   810             return QString::fromLatin1("%0 %1 %2 %3")
       
   811                 .arg(shortDayName(dayOfWeek()))
       
   812                 .arg(shortMonthName(m))
       
   813                 .arg(d)
       
   814                 .arg(y);
       
   815         }
       
   816 #endif
       
   817     case Qt::ISODate:
       
   818         {
       
   819             if (year() < 0 || year() > 9999)
       
   820                 return QString();
       
   821             QString month(QString::number(m).rightJustified(2, QLatin1Char('0')));
       
   822             QString day(QString::number(d).rightJustified(2, QLatin1Char('0')));
       
   823             return QString::number(y) + QLatin1Char('-') + month + QLatin1Char('-') + day;
       
   824         }
       
   825     }
       
   826 }
       
   827 
       
   828 /*!
       
   829     Returns the date as a string. The \a format parameter determines
       
   830     the format of the result string.
       
   831 
       
   832     These expressions may be used:
       
   833 
       
   834     \table
       
   835     \header \i Expression \i Output
       
   836     \row \i d \i the day as number without a leading zero (1 to 31)
       
   837     \row \i dd \i the day as number with a leading zero (01 to 31)
       
   838     \row \i ddd
       
   839          \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
       
   840             Uses QDate::shortDayName().
       
   841     \row \i dddd
       
   842          \i the long localized day name (e.g. 'Monday' to 'Sunday').
       
   843             Uses QDate::longDayName().
       
   844     \row \i M \i the month as number without a leading zero (1 to 12)
       
   845     \row \i MM \i the month as number with a leading zero (01 to 12)
       
   846     \row \i MMM
       
   847          \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
       
   848             Uses QDate::shortMonthName().
       
   849     \row \i MMMM
       
   850          \i the long localized month name (e.g. 'January' to 'December').
       
   851             Uses QDate::longMonthName().
       
   852     \row \i yy \i the year as two digit number (00 to 99)
       
   853     \row \i yyyy \i the year as four digit number. If the year is negative,
       
   854             a minus sign is prepended in addition.
       
   855     \endtable
       
   856 
       
   857     All other input characters will be ignored. Any sequence of characters that
       
   858     are enclosed in singlequotes will be treated as text and not be used as an
       
   859     expression. Two consecutive singlequotes ("''") are replaced by a singlequote
       
   860     in the output.
       
   861 
       
   862     Example format strings (assuming that the QDate is the 20 July
       
   863     1969):
       
   864 
       
   865     \table
       
   866     \header \o Format            \o Result
       
   867     \row    \o dd.MM.yyyy        \o 20.07.1969
       
   868     \row    \o ddd MMMM d yy     \o Sun July 20 69
       
   869     \row    \o 'The day is' dddd \o The day is Sunday
       
   870     \endtable
       
   871 
       
   872     If the datetime is invalid, an empty string will be returned.
       
   873 
       
   874     \warning The Qt::ISODate format is only valid for years in the
       
   875     range 0 to 9999. This restriction may apply to locale-aware
       
   876     formats as well, depending on the locale settings.
       
   877 
       
   878     \sa QDateTime::toString() QTime::toString()
       
   879 
       
   880 */
       
   881 QString QDate::toString(const QString& format) const
       
   882 {
       
   883     if (year() > 9999)
       
   884         return QString();
       
   885     return fmtDateTime(format, 0, this);
       
   886 }
       
   887 #endif //QT_NO_DATESTRING
       
   888 
       
   889 /*!
       
   890     \obsolete
       
   891 
       
   892     Sets the date's year \a y, month \a m, and day \a d.
       
   893 
       
   894     If \a y is in the range 0 to 99, it is interpreted as 1900 to
       
   895     1999.
       
   896 
       
   897     Use setDate() instead.
       
   898 */
       
   899 
       
   900 bool QDate::setYMD(int y, int m, int d)
       
   901 {
       
   902     if (uint(y) <= 99)
       
   903         y += 1900;
       
   904     return setDate(y, m, d);
       
   905 }
       
   906 
       
   907 /*!
       
   908     \since 4.2
       
   909 
       
   910     Sets the date's \a year, \a month, and \a day. Returns true if
       
   911     the date is valid; otherwise returns false.
       
   912 
       
   913     If the specified date is invalid, the QDate object is set to be
       
   914     invalid. Any date before 2 January 4713 B.C. is considered
       
   915     invalid.
       
   916 
       
   917     \sa isValid()
       
   918 */
       
   919 bool QDate::setDate(int year, int month, int day)
       
   920 {
       
   921     if (!isValid(year, month, day)) {
       
   922         jd = 0;
       
   923     } else {
       
   924         jd = julianDayFromDate(year, month, day);
       
   925     }
       
   926     return jd != 0;
       
   927 }
       
   928 
       
   929 /*!
       
   930     \since 4.5
       
   931 
       
   932     Extracts the date's year, month, and day, and assigns them to
       
   933     *\a year, *\a month, and *\a day. The pointers may be null.
       
   934 
       
   935     \sa year(), month(), day(), isValid()
       
   936 */
       
   937 void QDate::getDate(int *year, int *month, int *day)
       
   938 {
       
   939     getDateFromJulianDay(jd, year, month, day);
       
   940 }
       
   941 
       
   942 /*!
       
   943     Returns a QDate object containing a date \a ndays later than the
       
   944     date of this object (or earlier if \a ndays is negative).
       
   945 
       
   946     \sa addMonths() addYears() daysTo()
       
   947 */
       
   948 
       
   949 QDate QDate::addDays(int ndays) const
       
   950 {
       
   951     QDate d;
       
   952     // this is basically "d.jd = jd + ndays" with checks for integer overflow
       
   953     if (ndays >= 0)
       
   954         d.jd = (jd + ndays >= jd) ? jd + ndays : 0;
       
   955     else
       
   956         d.jd = (jd + ndays < jd) ? jd + ndays : 0;
       
   957     return d;
       
   958 }
       
   959 
       
   960 /*!
       
   961     Returns a QDate object containing a date \a nmonths later than the
       
   962     date of this object (or earlier if \a nmonths is negative).
       
   963 
       
   964     \note If the ending day/month combination does not exist in the
       
   965     resulting month/year, this function will return a date that is the
       
   966     latest valid date.
       
   967 
       
   968     \warning QDate has a date hole around the days introducing the
       
   969     Gregorian calendar (the days 5 to 14 October 1582, inclusive, do
       
   970     not exist). If the calculation ends in one of those days, QDate
       
   971     will return either October 4 or October 15.
       
   972 
       
   973     \sa addDays() addYears()
       
   974 */
       
   975 
       
   976 QDate QDate::addMonths(int nmonths) const
       
   977 {
       
   978     if (!isValid())
       
   979         return QDate();
       
   980     if (!nmonths)
       
   981         return *this;
       
   982 
       
   983     int old_y, y, m, d;
       
   984     getDateFromJulianDay(jd, &y, &m, &d);
       
   985     old_y = y;
       
   986 
       
   987     bool increasing = nmonths > 0;
       
   988 
       
   989     while (nmonths != 0) {
       
   990         if (nmonths < 0 && nmonths + 12 <= 0) {
       
   991             y--;
       
   992             nmonths+=12;
       
   993         } else if (nmonths < 0) {
       
   994             m+= nmonths;
       
   995             nmonths = 0;
       
   996             if (m <= 0) {
       
   997                 --y;
       
   998                 m += 12;
       
   999             }
       
  1000         } else if (nmonths - 12 >= 0) {
       
  1001             y++;
       
  1002             nmonths -= 12;
       
  1003         } else if (m == 12) {
       
  1004             y++;
       
  1005             m = 0;
       
  1006         } else {
       
  1007             m += nmonths;
       
  1008             nmonths = 0;
       
  1009             if (m > 12) {
       
  1010                 ++y;
       
  1011                 m -= 12;
       
  1012             }
       
  1013         }
       
  1014     }
       
  1015 
       
  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 += increasing ? +1 : -1;
       
  1021 
       
  1022     // did we end up in the Gregorian/Julian conversion hole?
       
  1023     if (y == 1582 && m == 10 && d > 4 && d < 15)
       
  1024         d = increasing ? 15 : 4;
       
  1025 
       
  1026     return fixedDate(y, m, d);
       
  1027 }
       
  1028 
       
  1029 /*!
       
  1030     Returns a QDate object containing a date \a nyears later than the
       
  1031     date of this object (or earlier if \a nyears is negative).
       
  1032 
       
  1033     \note If the ending day/month combination does not exist in the
       
  1034     resulting year (i.e., if the date was Feb 29 and the final year is
       
  1035     not a leap year), this function will return a date that is the
       
  1036     latest valid date (that is, Feb 28).
       
  1037 
       
  1038     \sa addDays(), addMonths()
       
  1039 */
       
  1040 
       
  1041 QDate QDate::addYears(int nyears) const
       
  1042 {
       
  1043     if (!isValid())
       
  1044         return QDate();
       
  1045 
       
  1046     int y, m, d;
       
  1047     getDateFromJulianDay(jd, &y, &m, &d);
       
  1048 
       
  1049     int old_y = y;
       
  1050     y += nyears;
       
  1051 
       
  1052     // was there a sign change?
       
  1053     if ((old_y > 0 && y <= 0) ||
       
  1054         (old_y < 0 && y >= 0))
       
  1055         // yes, adjust the date by +1 or -1 years
       
  1056         y += nyears > 0 ? +1 : -1;
       
  1057 
       
  1058     return fixedDate(y, m, d);
       
  1059 }
       
  1060 
       
  1061 /*!
       
  1062     Returns the number of days from this date to \a d (which is
       
  1063     negative if \a d is earlier than this date).
       
  1064 
       
  1065     Example:
       
  1066     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 0
       
  1067 
       
  1068     \sa addDays()
       
  1069 */
       
  1070 
       
  1071 int QDate::daysTo(const QDate &d) const
       
  1072 {
       
  1073     return d.jd - jd;
       
  1074 }
       
  1075 
       
  1076 
       
  1077 /*!
       
  1078     \fn bool QDate::operator==(const QDate &d) const
       
  1079 
       
  1080     Returns true if this date is equal to \a d; otherwise returns
       
  1081     false.
       
  1082 
       
  1083 */
       
  1084 
       
  1085 /*!
       
  1086     \fn bool QDate::operator!=(const QDate &d) const
       
  1087 
       
  1088     Returns true if this date is different from \a d; otherwise
       
  1089     returns false.
       
  1090 */
       
  1091 
       
  1092 /*!
       
  1093     \fn bool QDate::operator<(const QDate &d) const
       
  1094 
       
  1095     Returns true if this date is earlier than \a d; otherwise returns
       
  1096     false.
       
  1097 */
       
  1098 
       
  1099 /*!
       
  1100     \fn bool QDate::operator<=(const QDate &d) const
       
  1101 
       
  1102     Returns true if this date is earlier than or equal to \a d;
       
  1103     otherwise returns false.
       
  1104 */
       
  1105 
       
  1106 /*!
       
  1107     \fn bool QDate::operator>(const QDate &d) const
       
  1108 
       
  1109     Returns true if this date is later than \a d; otherwise returns
       
  1110     false.
       
  1111 */
       
  1112 
       
  1113 /*!
       
  1114     \fn bool QDate::operator>=(const QDate &d) const
       
  1115 
       
  1116     Returns true if this date is later than or equal to \a d;
       
  1117     otherwise returns false.
       
  1118 */
       
  1119 
       
  1120 /*!
       
  1121     \overload
       
  1122     Returns the current date, as reported by the system clock.
       
  1123 
       
  1124     \sa QTime::currentTime(), QDateTime::currentDateTime()
       
  1125 */
       
  1126 
       
  1127 QDate QDate::currentDate()
       
  1128 {
       
  1129     QDate d;
       
  1130 #if defined(Q_OS_WIN)
       
  1131     SYSTEMTIME st;
       
  1132     memset(&st, 0, sizeof(SYSTEMTIME));
       
  1133     GetLocalTime(&st);
       
  1134     d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
       
  1135 #elif defined(Q_OS_SYMBIAN)
       
  1136     TTime localTime;
       
  1137     localTime.HomeTime();
       
  1138     TDateTime localDateTime = localTime.DateTime();
       
  1139     // months and days are zero indexed
       
  1140     d.jd = julianDayFromDate(localDateTime.Year(), localDateTime.Month() + 1, localDateTime.Day() + 1 );
       
  1141 #else
       
  1142     // posix compliant system
       
  1143     time_t ltime;
       
  1144     time(&ltime);
       
  1145     tm *t = 0;
       
  1146 
       
  1147 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
       
  1148     // use the reentrant version of localtime() where available
       
  1149     tzset();
       
  1150     tm res;
       
  1151     t = localtime_r(&ltime, &res);
       
  1152 #else
       
  1153     t = localtime(&ltime);
       
  1154 #endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
       
  1155 
       
  1156     d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
       
  1157 #endif
       
  1158     return d;
       
  1159 }
       
  1160 
       
  1161 #ifndef QT_NO_DATESTRING
       
  1162 /*!
       
  1163     \fn QDate QDate::fromString(const QString &string, Qt::DateFormat format)
       
  1164 
       
  1165     Returns the QDate represented by the \a string, using the
       
  1166     \a format given, or an invalid date if the string cannot be
       
  1167     parsed.
       
  1168 
       
  1169     Note for Qt::TextDate: It is recommended that you use the
       
  1170     English short month names (e.g. "Jan"). Although localized month
       
  1171     names can also be used, they depend on the user's locale settings.
       
  1172 */
       
  1173 QDate QDate::fromString(const QString& s, Qt::DateFormat f)
       
  1174 {
       
  1175     if (s.isEmpty())
       
  1176         return QDate();
       
  1177 
       
  1178     switch (f) {
       
  1179     case Qt::ISODate:
       
  1180         {
       
  1181             int year(s.mid(0, 4).toInt());
       
  1182             int month(s.mid(5, 2).toInt());
       
  1183             int day(s.mid(8, 2).toInt());
       
  1184             if (year && month && day)
       
  1185                 return QDate(year, month, day);
       
  1186         }
       
  1187         break;
       
  1188     case Qt::SystemLocaleDate:
       
  1189     case Qt::SystemLocaleShortDate:
       
  1190     case Qt::SystemLocaleLongDate:
       
  1191         return fromString(s, QLocale::system().dateFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
       
  1192                                                                                         : QLocale::ShortFormat));
       
  1193     case Qt::LocaleDate:
       
  1194     case Qt::DefaultLocaleShortDate:
       
  1195     case Qt::DefaultLocaleLongDate:
       
  1196         return fromString(s, QLocale().dateFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
       
  1197                                                                                  : QLocale::ShortFormat));
       
  1198     default:
       
  1199 #ifndef QT_NO_TEXTDATE
       
  1200     case Qt::TextDate: {
       
  1201         QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts);
       
  1202 
       
  1203         if (parts.count() != 4) {
       
  1204             return QDate();
       
  1205         }
       
  1206 
       
  1207         QString monthName = parts.at(1);
       
  1208         int month = -1;
       
  1209         // Assume that English monthnames are the default
       
  1210         for (int i = 0; i < 12; ++i) {
       
  1211             if (monthName == QLatin1String(qt_shortMonthNames[i])) {
       
  1212                 month = i + 1;
       
  1213                 break;
       
  1214             }
       
  1215         }
       
  1216         // If English names can't be found, search the localized ones
       
  1217         if (month == -1) {
       
  1218             for (int i = 1; i <= 12; ++i) {
       
  1219                 if (monthName == QDate::shortMonthName(i)) {
       
  1220                     month = i;
       
  1221                     break;
       
  1222                 }
       
  1223             }
       
  1224         }
       
  1225         if (month < 1 || month > 12) {
       
  1226             return QDate();
       
  1227         }
       
  1228 
       
  1229         bool ok;
       
  1230         int day = parts.at(2).toInt(&ok);
       
  1231         if (!ok) {
       
  1232             return QDate();
       
  1233         }
       
  1234 
       
  1235         int year = parts.at(3).toInt(&ok);
       
  1236         if (!ok) {
       
  1237             return QDate();
       
  1238         }
       
  1239 
       
  1240         return QDate(year, month, day);
       
  1241     }
       
  1242 #else
       
  1243         break;
       
  1244 #endif
       
  1245     }
       
  1246     return QDate();
       
  1247 }
       
  1248 
       
  1249 /*!
       
  1250     \fn QDate::fromString(const QString &string, const QString &format)
       
  1251 
       
  1252     Returns the QDate represented by the \a string, using the \a
       
  1253     format given, or an invalid date if the string cannot be parsed.
       
  1254 
       
  1255     These expressions may be used for the format:
       
  1256 
       
  1257     \table
       
  1258     \header \i Expression \i Output
       
  1259     \row \i d \i The day as a number without a leading zero (1 to 31)
       
  1260     \row \i dd \i The day as a number with a leading zero (01 to 31)
       
  1261     \row \i ddd
       
  1262          \i The abbreviated localized day name (e.g. 'Mon' to 'Sun').
       
  1263             Uses QDate::shortDayName().
       
  1264     \row \i dddd
       
  1265          \i The long localized day name (e.g. 'Monday' to 'Sunday').
       
  1266             Uses QDate::longDayName().
       
  1267     \row \i M \i The month as a number without a leading zero (1 to 12)
       
  1268     \row \i MM \i The month as a number with a leading zero (01 to 12)
       
  1269     \row \i MMM
       
  1270          \i The abbreviated localized month name (e.g. 'Jan' to 'Dec').
       
  1271             Uses QDate::shortMonthName().
       
  1272     \row \i MMMM
       
  1273          \i The long localized month name (e.g. 'January' to 'December').
       
  1274             Uses QDate::longMonthName().
       
  1275     \row \i yy \i The year as two digit number (00 to 99)
       
  1276     \row \i yyyy \i The year as four digit number. If the year is negative,
       
  1277             a minus sign is prepended in addition.
       
  1278     \endtable
       
  1279 
       
  1280     All other input characters will be treated as text. Any sequence
       
  1281     of characters that are enclosed in single quotes will also be
       
  1282     treated as text and will not be used as an expression. For example:
       
  1283 
       
  1284     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 1
       
  1285 
       
  1286     If the format is not satisfied, an invalid QDate is returned. The
       
  1287     expressions that don't expect leading zeroes (d, M) will be
       
  1288     greedy. This means that they will use two digits even if this
       
  1289     will put them outside the accepted range of values and leaves too
       
  1290     few digits for other sections. For example, the following format
       
  1291     string could have meant January 30 but the M will grab two
       
  1292     digits, resulting in an invalid date:
       
  1293 
       
  1294     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 2
       
  1295 
       
  1296     For any field that is not represented in the format the following
       
  1297     defaults are used:
       
  1298 
       
  1299     \table
       
  1300     \header \i Field  \i Default value
       
  1301     \row    \i Year   \i 1900
       
  1302     \row    \i Month  \i 1
       
  1303     \row    \i Day    \i 1
       
  1304     \endtable
       
  1305 
       
  1306     The following examples demonstrate the default values:
       
  1307 
       
  1308     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 3
       
  1309 
       
  1310     \sa QDateTime::fromString(), QTime::fromString(), QDate::toString(),
       
  1311         QDateTime::toString(), QTime::toString()
       
  1312 */
       
  1313 
       
  1314 QDate QDate::fromString(const QString &string, const QString &format)
       
  1315 {
       
  1316     QDate date;
       
  1317 #ifndef QT_BOOTSTRAPPED
       
  1318     QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
       
  1319     if (dt.parseFormat(format))
       
  1320         dt.fromString(string, &date, 0);
       
  1321 #else
       
  1322     Q_UNUSED(string);
       
  1323     Q_UNUSED(format);
       
  1324 #endif
       
  1325     return date;
       
  1326 }
       
  1327 #endif // QT_NO_DATESTRING
       
  1328 
       
  1329 /*!
       
  1330     \overload
       
  1331 
       
  1332     Returns true if the specified date (\a year, \a month, and \a
       
  1333     day) is valid; otherwise returns false.
       
  1334 
       
  1335     Example:
       
  1336     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 4
       
  1337 
       
  1338     \sa isNull(), setDate()
       
  1339 */
       
  1340 
       
  1341 bool QDate::isValid(int year, int month, int day)
       
  1342 {
       
  1343     if (year < FIRST_YEAR
       
  1344         || (year == FIRST_YEAR &&
       
  1345             (month < FIRST_MONTH
       
  1346              || (month == FIRST_MONTH && day < FIRST_DAY)))
       
  1347         || year == 0) // there is no year 0 in the Julian calendar
       
  1348         return false;
       
  1349 
       
  1350     // passage from Julian to Gregorian calendar
       
  1351     if (year == 1582 && month == 10 && day > 4 && day < 15)
       
  1352         return 0;
       
  1353 
       
  1354     return (day > 0 && month > 0 && month <= 12) &&
       
  1355            (day <= monthDays[month] || (day == 29 && month == 2 && isLeapYear(year)));
       
  1356 }
       
  1357 
       
  1358 /*!
       
  1359     \fn bool QDate::isLeapYear(int year)
       
  1360 
       
  1361     Returns true if the specified \a year is a leap year; otherwise
       
  1362     returns false.
       
  1363 */
       
  1364 
       
  1365 bool QDate::isLeapYear(int y)
       
  1366 {
       
  1367     if (y < 1582) {
       
  1368         return qAbs(y) % 4 == 0;
       
  1369     } else {
       
  1370         return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
       
  1371     }
       
  1372 }
       
  1373 
       
  1374 /*!
       
  1375     \internal
       
  1376 
       
  1377     This function has a confusing name and shouldn't be part of the
       
  1378     API anyway, since we have toJulian() and fromJulian().
       
  1379     ### Qt 5: remove it
       
  1380 */
       
  1381 uint QDate::gregorianToJulian(int y, int m, int d)
       
  1382 {
       
  1383     return julianDayFromDate(y, m, d);
       
  1384 }
       
  1385 
       
  1386 /*!
       
  1387     \internal
       
  1388 
       
  1389     This function has a confusing name and shouldn't be part of the
       
  1390     API anyway, since we have toJulian() and fromJulian().
       
  1391     ### Qt 5: remove it
       
  1392 */
       
  1393 void QDate::julianToGregorian(uint jd, int &y, int &m, int &d)
       
  1394 {
       
  1395     getDateFromJulianDay(jd, &y, &m, &d);
       
  1396 }
       
  1397 
       
  1398 /*! \fn static QDate QDate::fromJulianDay(int jd)
       
  1399 
       
  1400     Converts the Julian day \a jd to a QDate.
       
  1401 
       
  1402     \sa toJulianDay()
       
  1403 */
       
  1404 
       
  1405 /*! \fn int QDate::toJulianDay() const
       
  1406 
       
  1407     Converts the date to a Julian day.
       
  1408 
       
  1409     \sa fromJulianDay()
       
  1410 */
       
  1411 
       
  1412 /*****************************************************************************
       
  1413   QTime member functions
       
  1414  *****************************************************************************/
       
  1415 
       
  1416 /*!
       
  1417     \class QTime
       
  1418     \reentrant
       
  1419 
       
  1420     \brief The QTime class provides clock time functions.
       
  1421 
       
  1422 
       
  1423     A QTime object contains a clock time, i.e. the number of hours,
       
  1424     minutes, seconds, and milliseconds since midnight. It can read the
       
  1425     current time from the system clock and measure a span of elapsed
       
  1426     time. It provides functions for comparing times and for
       
  1427     manipulating a time by adding a number of milliseconds.
       
  1428 
       
  1429     QTime uses the 24-hour clock format; it has no concept of AM/PM.
       
  1430     Unlike QDateTime, QTime knows nothing about time zones or
       
  1431     daylight savings time (DST).
       
  1432 
       
  1433     A QTime object is typically created either by giving the number
       
  1434     of hours, minutes, seconds, and milliseconds explicitly, or by
       
  1435     using the static function currentTime(), which creates a QTime
       
  1436     object that contains the system's local time. Note that the
       
  1437     accuracy depends on the accuracy of the underlying operating
       
  1438     system; not all systems provide 1-millisecond accuracy.
       
  1439 
       
  1440     The hour(), minute(), second(), and msec() functions provide
       
  1441     access to the number of hours, minutes, seconds, and milliseconds
       
  1442     of the time. The same information is provided in textual format by
       
  1443     the toString() function.
       
  1444 
       
  1445     QTime provides a full set of operators to compare two QTime
       
  1446     objects. One time is considered smaller than another if it is
       
  1447     earlier than the other.
       
  1448 
       
  1449     The time a given number of seconds or milliseconds later than a
       
  1450     given time can be found using the addSecs() or addMSecs()
       
  1451     functions. Correspondingly, the number of seconds or milliseconds
       
  1452     between two times can be found using secsTo() or msecsTo().
       
  1453 
       
  1454     QTime can be used to measure a span of elapsed time using the
       
  1455     start(), restart(), and elapsed() functions.
       
  1456 
       
  1457     \sa QDate, QDateTime
       
  1458 */
       
  1459 
       
  1460 /*!
       
  1461     \fn QTime::QTime()
       
  1462 
       
  1463     Constructs a null time object. A null time can be a QTime(0, 0, 0, 0)
       
  1464     (i.e., midnight) object, except that isNull() returns true and isValid()
       
  1465     returns false.
       
  1466 
       
  1467     \sa isNull(), isValid()
       
  1468 */
       
  1469 
       
  1470 /*!
       
  1471     Constructs a time with hour \a h, minute \a m, seconds \a s and
       
  1472     milliseconds \a ms.
       
  1473 
       
  1474     \a h must be in the range 0 to 23, \a m and \a s must be in the
       
  1475     range 0 to 59, and \a ms must be in the range 0 to 999.
       
  1476 
       
  1477     \sa isValid()
       
  1478 */
       
  1479 
       
  1480 QTime::QTime(int h, int m, int s, int ms)
       
  1481 {
       
  1482     setHMS(h, m, s, ms);
       
  1483 }
       
  1484 
       
  1485 
       
  1486 /*!
       
  1487     \fn bool QTime::isNull() const
       
  1488 
       
  1489     Returns true if the time is null (i.e., the QTime object was
       
  1490     constructed using the default constructor); otherwise returns
       
  1491     false. A null time is also an invalid time.
       
  1492 
       
  1493     \sa isValid()
       
  1494 */
       
  1495 
       
  1496 /*!
       
  1497     Returns true if the time is valid; otherwise returns false. For example,
       
  1498     the time 23:30:55.746 is valid, but 24:12:30 is invalid.
       
  1499 
       
  1500     \sa isNull()
       
  1501 */
       
  1502 
       
  1503 bool QTime::isValid() const
       
  1504 {
       
  1505     return mds > NullTime && mds < MSECS_PER_DAY;
       
  1506 }
       
  1507 
       
  1508 
       
  1509 /*!
       
  1510     Returns the hour part (0 to 23) of the time.
       
  1511 
       
  1512     \sa minute(), second(), msec()
       
  1513 */
       
  1514 
       
  1515 int QTime::hour() const
       
  1516 {
       
  1517     return ds() / MSECS_PER_HOUR;
       
  1518 }
       
  1519 
       
  1520 /*!
       
  1521     Returns the minute part (0 to 59) of the time.
       
  1522 
       
  1523     \sa hour(), second(), msec()
       
  1524 */
       
  1525 
       
  1526 int QTime::minute() const
       
  1527 {
       
  1528     return (ds() % MSECS_PER_HOUR) / MSECS_PER_MIN;
       
  1529 }
       
  1530 
       
  1531 /*!
       
  1532     Returns the second part (0 to 59) of the time.
       
  1533 
       
  1534     \sa hour(), minute(), msec()
       
  1535 */
       
  1536 
       
  1537 int QTime::second() const
       
  1538 {
       
  1539     return (ds() / 1000)%SECS_PER_MIN;
       
  1540 }
       
  1541 
       
  1542 /*!
       
  1543     Returns the millisecond part (0 to 999) of the time.
       
  1544 
       
  1545     \sa hour(), minute(), second()
       
  1546 */
       
  1547 
       
  1548 int QTime::msec() const
       
  1549 {
       
  1550     return ds() % 1000;
       
  1551 }
       
  1552 
       
  1553 #ifndef QT_NO_DATESTRING
       
  1554 /*!
       
  1555     \overload
       
  1556 
       
  1557     Returns the time as a string. Milliseconds are not included. The
       
  1558     \a format parameter determines the format of the string.
       
  1559 
       
  1560     If \a format is Qt::TextDate, the string format is HH:MM:SS; e.g. 1
       
  1561     second before midnight would be "23:59:59".
       
  1562 
       
  1563     If \a format is Qt::ISODate, the string format corresponds to the
       
  1564     ISO 8601 extended specification for representations of dates,
       
  1565     which is also HH:MM:SS. (However, contrary to ISO 8601, dates
       
  1566     before 15 October 1582 are handled as Julian dates, not Gregorian
       
  1567     dates. See \l{QDate G and J} {Use of Gregorian and Julian
       
  1568     Calendars}. This might change in a future version of Qt.)
       
  1569 
       
  1570     If the \a format is Qt::SystemLocaleShortDate or
       
  1571     Qt::SystemLocaleLongDate, the string format depends on the locale
       
  1572     settings of the system. Identical to calling
       
  1573     QLocale::system().toString(time, QLocale::ShortFormat) or
       
  1574     QLocale::system().toString(time, QLocale::LongFormat).
       
  1575 
       
  1576     If the \a format is Qt::DefaultLocaleShortDate or
       
  1577     Qt::DefaultLocaleLongDate, the string format depends on the
       
  1578     default application locale. This is the locale set with
       
  1579     QLocale::setDefault(), or the system locale if no default locale
       
  1580     has been set. Identical to calling QLocale().toString(time,
       
  1581     QLocale::ShortFormat) or QLocale().toString(time,
       
  1582     QLocale::LongFormat).
       
  1583 
       
  1584     If the time is invalid, an empty string will be returned.
       
  1585 */
       
  1586 
       
  1587 QString QTime::toString(Qt::DateFormat format) const
       
  1588 {
       
  1589     if (!isValid())
       
  1590         return QString();
       
  1591 
       
  1592     switch (format) {
       
  1593     case Qt::SystemLocaleDate:
       
  1594     case Qt::SystemLocaleShortDate:
       
  1595     case Qt::SystemLocaleLongDate:
       
  1596         return QLocale::system().toString(*this, format == Qt::SystemLocaleLongDate ? QLocale::LongFormat
       
  1597                                           : QLocale::ShortFormat);
       
  1598     case Qt::LocaleDate:
       
  1599     case Qt::DefaultLocaleShortDate:
       
  1600     case Qt::DefaultLocaleLongDate:
       
  1601         return QLocale().toString(*this, format == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
       
  1602                                   : QLocale::ShortFormat);
       
  1603 
       
  1604     default:
       
  1605     case Qt::ISODate:
       
  1606     case Qt::TextDate:
       
  1607         return QString::fromLatin1("%1:%2:%3")
       
  1608             .arg(hour(), 2, 10, QLatin1Char('0'))
       
  1609             .arg(minute(), 2, 10, QLatin1Char('0'))
       
  1610             .arg(second(), 2, 10, QLatin1Char('0'));
       
  1611     }
       
  1612 }
       
  1613 
       
  1614 /*!
       
  1615     Returns the time as a string. The \a format parameter determines
       
  1616     the format of the result string.
       
  1617 
       
  1618     These expressions may be used:
       
  1619 
       
  1620     \table
       
  1621     \header \i Expression \i Output
       
  1622     \row \i h
       
  1623          \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
       
  1624     \row \i hh
       
  1625          \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
       
  1626     \row \i H
       
  1627          \i the hour without a leading zero (0 to 23, even with AM/PM display)
       
  1628     \row \i HH
       
  1629          \i the hour with a leading zero (00 to 23, even with AM/PM display)
       
  1630     \row \i m \i the minute without a leading zero (0 to 59)
       
  1631     \row \i mm \i the minute with a leading zero (00 to 59)
       
  1632     \row \i s \i the second without a leading zero (0 to 59)
       
  1633     \row \i ss \i the second with a leading zero (00 to 59)
       
  1634     \row \i z \i the milliseconds without leading zeroes (0 to 999)
       
  1635     \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
       
  1636     \row \i AP or A
       
  1637          \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
       
  1638     \row \i ap or a
       
  1639          \i use am/pm display. \e ap will be replaced by either "am" or "pm".
       
  1640     \endtable
       
  1641 
       
  1642     All other input characters will be ignored. Any sequence of characters that
       
  1643     are enclosed in singlequotes will be treated as text and not be used as an
       
  1644     expression. Two consecutive singlequotes ("''") are replaced by a singlequote
       
  1645     in the output.
       
  1646 
       
  1647     Example format strings (assuming that the QTime is 14:13:09.042)
       
  1648 
       
  1649     \table
       
  1650     \header \i Format \i Result
       
  1651     \row \i hh:mm:ss.zzz \i 14:13:09.042
       
  1652     \row \i h:m:s ap     \i 2:13:9 pm
       
  1653     \row \i H:m:s a      \i 14:13:9 pm
       
  1654     \endtable
       
  1655 
       
  1656     If the datetime is invalid, an empty string will be returned.
       
  1657 
       
  1658     \sa QDate::toString() QDateTime::toString()
       
  1659 */
       
  1660 QString QTime::toString(const QString& format) const
       
  1661 {
       
  1662     return fmtDateTime(format, this, 0);
       
  1663 }
       
  1664 #endif //QT_NO_DATESTRING
       
  1665 /*!
       
  1666     Sets the time to hour \a h, minute \a m, seconds \a s and
       
  1667     milliseconds \a ms.
       
  1668 
       
  1669     \a h must be in the range 0 to 23, \a m and \a s must be in the
       
  1670     range 0 to 59, and \a ms must be in the range 0 to 999.
       
  1671     Returns true if the set time is valid; otherwise returns false.
       
  1672 
       
  1673     \sa isValid()
       
  1674 */
       
  1675 
       
  1676 bool QTime::setHMS(int h, int m, int s, int ms)
       
  1677 {
       
  1678 #if defined(Q_OS_WINCE)
       
  1679     startTick = NullTime;
       
  1680 #endif
       
  1681     if (!isValid(h,m,s,ms)) {
       
  1682         mds = NullTime;                // make this invalid
       
  1683         return false;
       
  1684     }
       
  1685     mds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;
       
  1686     return true;
       
  1687 }
       
  1688 
       
  1689 /*!
       
  1690     Returns a QTime object containing a time \a s seconds later
       
  1691     than the time of this object (or earlier if \a s is negative).
       
  1692 
       
  1693     Note that the time will wrap if it passes midnight.
       
  1694 
       
  1695     Example:
       
  1696 
       
  1697     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 5
       
  1698 
       
  1699     \sa addMSecs(), secsTo(), QDateTime::addSecs()
       
  1700 */
       
  1701 
       
  1702 QTime QTime::addSecs(int s) const
       
  1703 {
       
  1704     return addMSecs(s * 1000);
       
  1705 }
       
  1706 
       
  1707 /*!
       
  1708     Returns the number of seconds from this time to \a t.
       
  1709     If \a t is earlier than this time, the number of seconds returned
       
  1710     is negative.
       
  1711 
       
  1712     Because QTime measures time within a day and there are 86400
       
  1713     seconds in a day, the result is always between -86400 and 86400.
       
  1714 
       
  1715     secsTo() does not take into account any milliseconds.
       
  1716 
       
  1717     \sa addSecs(), QDateTime::secsTo()
       
  1718 */
       
  1719 
       
  1720 int QTime::secsTo(const QTime &t) const
       
  1721 {
       
  1722     return (t.ds() - ds()) / 1000;
       
  1723 }
       
  1724 
       
  1725 /*!
       
  1726     Returns a QTime object containing a time \a ms milliseconds later
       
  1727     than the time of this object (or earlier if \a ms is negative).
       
  1728 
       
  1729     Note that the time will wrap if it passes midnight. See addSecs()
       
  1730     for an example.
       
  1731 
       
  1732     \sa addSecs(), msecsTo()
       
  1733 */
       
  1734 
       
  1735 QTime QTime::addMSecs(int ms) const
       
  1736 {
       
  1737     QTime t;
       
  1738     if (ms < 0) {
       
  1739         // % not well-defined for -ve, but / is.
       
  1740         int negdays = (MSECS_PER_DAY - ms) / MSECS_PER_DAY;
       
  1741         t.mds = (ds() + ms + negdays * MSECS_PER_DAY) % MSECS_PER_DAY;
       
  1742     } else {
       
  1743         t.mds = (ds() + ms) % MSECS_PER_DAY;
       
  1744     }
       
  1745 #if defined(Q_OS_WINCE)
       
  1746     if (startTick > NullTime)
       
  1747         t.startTick = (startTick + ms) % MSECS_PER_DAY;
       
  1748 #endif
       
  1749     return t;
       
  1750 }
       
  1751 
       
  1752 /*!
       
  1753     Returns the number of milliseconds from this time to \a t.
       
  1754     If \a t is earlier than this time, the number of milliseconds returned
       
  1755     is negative.
       
  1756 
       
  1757     Because QTime measures time within a day and there are 86400
       
  1758     seconds in a day, the result is always between -86400000 and
       
  1759     86400000 ms.
       
  1760 
       
  1761     \sa secsTo(), addMSecs()
       
  1762 */
       
  1763 
       
  1764 int QTime::msecsTo(const QTime &t) const
       
  1765 {
       
  1766 #if defined(Q_OS_WINCE)
       
  1767     // GetLocalTime() for Windows CE has no milliseconds resolution
       
  1768     if (t.startTick > NullTime && startTick > NullTime)
       
  1769         return t.startTick - startTick;
       
  1770     else
       
  1771 #endif
       
  1772         return t.ds() - ds();
       
  1773 }
       
  1774 
       
  1775 
       
  1776 /*!
       
  1777     \fn bool QTime::operator==(const QTime &t) const
       
  1778 
       
  1779     Returns true if this time is equal to \a t; otherwise returns false.
       
  1780 */
       
  1781 
       
  1782 /*!
       
  1783     \fn bool QTime::operator!=(const QTime &t) const
       
  1784 
       
  1785     Returns true if this time is different from \a t; otherwise returns false.
       
  1786 */
       
  1787 
       
  1788 /*!
       
  1789     \fn bool QTime::operator<(const QTime &t) const
       
  1790 
       
  1791     Returns true if this time is earlier than \a t; otherwise returns false.
       
  1792 */
       
  1793 
       
  1794 /*!
       
  1795     \fn bool QTime::operator<=(const QTime &t) const
       
  1796 
       
  1797     Returns true if this time is earlier than or equal to \a t;
       
  1798     otherwise returns false.
       
  1799 */
       
  1800 
       
  1801 /*!
       
  1802     \fn bool QTime::operator>(const QTime &t) const
       
  1803 
       
  1804     Returns true if this time is later than \a t; otherwise returns false.
       
  1805 */
       
  1806 
       
  1807 /*!
       
  1808     \fn bool QTime::operator>=(const QTime &t) const
       
  1809 
       
  1810     Returns true if this time is later than or equal to \a t;
       
  1811     otherwise returns false.
       
  1812 */
       
  1813 
       
  1814 /*!
       
  1815     \overload
       
  1816 
       
  1817     Returns the current time as reported by the system clock.
       
  1818 
       
  1819     Note that the accuracy depends on the accuracy of the underlying
       
  1820     operating system; not all systems provide 1-millisecond accuracy.
       
  1821 */
       
  1822 
       
  1823 QTime QTime::currentTime()
       
  1824 {
       
  1825     QTime ct;
       
  1826 
       
  1827 #if defined(Q_OS_WIN)
       
  1828     SYSTEMTIME st;
       
  1829     memset(&st, 0, sizeof(SYSTEMTIME));
       
  1830     GetLocalTime(&st);
       
  1831     ct.mds = MSECS_PER_HOUR * st.wHour + MSECS_PER_MIN * st.wMinute + 1000 * st.wSecond
       
  1832              + st.wMilliseconds;
       
  1833 #if defined(Q_OS_WINCE)
       
  1834     ct.startTick = GetTickCount() % MSECS_PER_DAY;
       
  1835 #endif
       
  1836 #elif defined(Q_OS_SYMBIAN)
       
  1837     TTime localTime;
       
  1838     localTime.HomeTime();
       
  1839     TDateTime localDateTime = localTime.DateTime();
       
  1840     ct.mds = MSECS_PER_HOUR * localDateTime.Hour() + MSECS_PER_MIN * localDateTime.Minute()
       
  1841                  + 1000 * localDateTime.Second() + (localDateTime.MicroSecond() / 1000);
       
  1842 #elif defined(Q_OS_UNIX)
       
  1843     // posix compliant system
       
  1844     struct timeval tv;
       
  1845     gettimeofday(&tv, 0);
       
  1846     time_t ltime = tv.tv_sec;
       
  1847     tm *t = 0;
       
  1848 
       
  1849 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
       
  1850     // use the reentrant version of localtime() where available
       
  1851     tzset();
       
  1852     tm res;
       
  1853     t = localtime_r(&ltime, &res);
       
  1854 #else
       
  1855     t = localtime(&ltime);
       
  1856 #endif
       
  1857     Q_CHECK_PTR(t);
       
  1858     
       
  1859     ct.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec
       
  1860              + tv.tv_usec / 1000;
       
  1861 #else
       
  1862     time_t ltime; // no millisecond resolution
       
  1863     ::time(&ltime);
       
  1864     const tm *const t = localtime(&ltime);
       
  1865     ct.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec;
       
  1866 #endif
       
  1867     return ct;
       
  1868 }
       
  1869 
       
  1870 #ifndef QT_NO_DATESTRING
       
  1871 /*!
       
  1872     \fn QTime QTime::fromString(const QString &string, Qt::DateFormat format)
       
  1873 
       
  1874     Returns the time represented in the \a string as a QTime using the
       
  1875     \a format given, or an invalid time if this is not possible.
       
  1876 
       
  1877     Note that fromString() uses a "C" locale encoded string to convert
       
  1878     milliseconds to a float value. If the default locale is not "C",
       
  1879     this may result in two conversion attempts (if the conversion
       
  1880     fails for the default locale). This should be considered an
       
  1881     implementation detail.
       
  1882 */
       
  1883 QTime QTime::fromString(const QString& s, Qt::DateFormat f)
       
  1884 {
       
  1885     if (s.isEmpty()) {
       
  1886         QTime t;
       
  1887         t.mds = NullTime;
       
  1888         return t;
       
  1889     }
       
  1890 
       
  1891     switch (f) {
       
  1892     case Qt::SystemLocaleDate:
       
  1893     case Qt::SystemLocaleShortDate:
       
  1894     case Qt::SystemLocaleLongDate:
       
  1895         return fromString(s, QLocale::system().timeFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
       
  1896                                                                                         : QLocale::ShortFormat));
       
  1897     case Qt::LocaleDate:
       
  1898     case Qt::DefaultLocaleShortDate:
       
  1899     case Qt::DefaultLocaleLongDate:
       
  1900         return fromString(s, QLocale().timeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
       
  1901                                                                                  : QLocale::ShortFormat));
       
  1902     default:
       
  1903         {
       
  1904             bool ok = true;
       
  1905             const int hour(s.mid(0, 2).toInt(&ok));
       
  1906             if (!ok)
       
  1907                 return QTime();
       
  1908             const int minute(s.mid(3, 2).toInt(&ok));
       
  1909             if (!ok)
       
  1910                 return QTime();
       
  1911             const int second(s.mid(6, 2).toInt(&ok));
       
  1912             if (!ok)
       
  1913                 return QTime();
       
  1914             const QString msec_s(QLatin1String("0.") + s.mid(9, 4));
       
  1915             const float msec(msec_s.toFloat(&ok));
       
  1916             if (!ok)
       
  1917                 return QTime();
       
  1918             return QTime(hour, minute, second, qMin(qRound(msec * 1000.0), 999));
       
  1919         }
       
  1920     }
       
  1921 }
       
  1922 
       
  1923 /*!
       
  1924     \fn QTime::fromString(const QString &string, const QString &format)
       
  1925 
       
  1926     Returns the QTime represented by the \a string, using the \a
       
  1927     format given, or an invalid time if the string cannot be parsed.
       
  1928 
       
  1929     These expressions may be used for the format:
       
  1930 
       
  1931     \table
       
  1932     \header \i Expression \i Output
       
  1933     \row \i h
       
  1934          \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
       
  1935     \row \i hh
       
  1936          \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
       
  1937     \row \i m \i the minute without a leading zero (0 to 59)
       
  1938     \row \i mm \i the minute with a leading zero (00 to 59)
       
  1939     \row \i s \i the second without a leading zero (0 to 59)
       
  1940     \row \i ss \i the second with a leading zero (00 to 59)
       
  1941     \row \i z \i the milliseconds without leading zeroes (0 to 999)
       
  1942     \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
       
  1943     \row \i AP
       
  1944          \i interpret as an AM/PM time. \e AP must be either "AM" or "PM".
       
  1945     \row \i ap
       
  1946          \i Interpret as an AM/PM time. \e ap must be either "am" or "pm".
       
  1947     \endtable
       
  1948 
       
  1949     All other input characters will be treated as text. Any sequence
       
  1950     of characters that are enclosed in single quotes will also be
       
  1951     treated as text and not be used as an expression.
       
  1952 
       
  1953     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 6
       
  1954 
       
  1955     If the format is not satisfied an invalid QTime is returned.
       
  1956     Expressions that do not expect leading zeroes to be given (h, m, s
       
  1957     and z) are greedy. This means that they will use two digits even if
       
  1958     this puts them outside the range of accepted values and leaves too
       
  1959     few digits for other sections. For example, the following string
       
  1960     could have meant 00:07:10, but the m will grab two digits, resulting
       
  1961     in an invalid time:
       
  1962 
       
  1963     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 7
       
  1964 
       
  1965     Any field that is not represented in the format will be set to zero.
       
  1966     For example:
       
  1967 
       
  1968     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 8
       
  1969 
       
  1970     \sa QDateTime::fromString() QDate::fromString() QDate::toString()
       
  1971     QDateTime::toString() QTime::toString()
       
  1972 */
       
  1973 
       
  1974 QTime QTime::fromString(const QString &string, const QString &format)
       
  1975 {
       
  1976     QTime time;
       
  1977 #ifndef QT_BOOTSTRAPPED
       
  1978     QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
       
  1979     if (dt.parseFormat(format))
       
  1980         dt.fromString(string, 0, &time);
       
  1981 #else
       
  1982     Q_UNUSED(string);
       
  1983     Q_UNUSED(format);
       
  1984 #endif
       
  1985     return time;
       
  1986 }
       
  1987 
       
  1988 #endif // QT_NO_DATESTRING
       
  1989 
       
  1990 
       
  1991 /*!
       
  1992     \overload
       
  1993 
       
  1994     Returns true if the specified time is valid; otherwise returns
       
  1995     false.
       
  1996 
       
  1997     The time is valid if \a h is in the range 0 to 23, \a m and
       
  1998     \a s are in the range 0 to 59, and \a ms is in the range 0 to 999.
       
  1999 
       
  2000     Example:
       
  2001 
       
  2002     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 9
       
  2003 */
       
  2004 
       
  2005 bool QTime::isValid(int h, int m, int s, int ms)
       
  2006 {
       
  2007     return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
       
  2008 }
       
  2009 
       
  2010 
       
  2011 /*!
       
  2012     Sets this time to the current time. This is practical for timing:
       
  2013 
       
  2014     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 10
       
  2015 
       
  2016     \sa restart(), elapsed(), currentTime()
       
  2017 */
       
  2018 
       
  2019 void QTime::start()
       
  2020 {
       
  2021     *this = currentTime();
       
  2022 }
       
  2023 
       
  2024 /*!
       
  2025     Sets this time to the current time and returns the number of
       
  2026     milliseconds that have elapsed since the last time start() or
       
  2027     restart() was called.
       
  2028 
       
  2029     This function is guaranteed to be atomic and is thus very handy
       
  2030     for repeated measurements. Call start() to start the first
       
  2031     measurement, and restart() for each later measurement.
       
  2032 
       
  2033     Note that the counter wraps to zero 24 hours after the last call
       
  2034     to start() or restart().
       
  2035 
       
  2036     \warning If the system's clock setting has been changed since the
       
  2037     last time start() or restart() was called, the result is
       
  2038     undefined. This can happen when daylight savings time is turned on
       
  2039     or off.
       
  2040 
       
  2041     \sa start(), elapsed(), currentTime()
       
  2042 */
       
  2043 
       
  2044 int QTime::restart()
       
  2045 {
       
  2046     QTime t = currentTime();
       
  2047     int n = msecsTo(t);
       
  2048     if (n < 0)                                // passed midnight
       
  2049         n += 86400*1000;
       
  2050     *this = t;
       
  2051     return n;
       
  2052 }
       
  2053 
       
  2054 /*!
       
  2055     Returns the number of milliseconds that have elapsed since the
       
  2056     last time start() or restart() was called.
       
  2057 
       
  2058     Note that the counter wraps to zero 24 hours after the last call
       
  2059     to start() or restart.
       
  2060 
       
  2061     Note that the accuracy depends on the accuracy of the underlying
       
  2062     operating system; not all systems provide 1-millisecond accuracy.
       
  2063 
       
  2064     \warning If the system's clock setting has been changed since the
       
  2065     last time start() or restart() was called, the result is
       
  2066     undefined. This can happen when daylight savings time is turned on
       
  2067     or off.
       
  2068 
       
  2069     \sa start(), restart()
       
  2070 */
       
  2071 
       
  2072 int QTime::elapsed() const
       
  2073 {
       
  2074     int n = msecsTo(currentTime());
       
  2075     if (n < 0)                                // passed midnight
       
  2076         n += 86400 * 1000;
       
  2077     return n;
       
  2078 }
       
  2079 
       
  2080 
       
  2081 /*****************************************************************************
       
  2082   QDateTime member functions
       
  2083  *****************************************************************************/
       
  2084 
       
  2085 /*!
       
  2086     \class QDateTime
       
  2087     \reentrant
       
  2088     \brief The QDateTime class provides date and time functions.
       
  2089 
       
  2090 
       
  2091     A QDateTime object contains a calendar date and a clock time (a
       
  2092     "datetime"). It is a combination of the QDate and QTime classes.
       
  2093     It can read the current datetime from the system clock. It
       
  2094     provides functions for comparing datetimes and for manipulating a
       
  2095     datetime by adding a number of seconds, days, months, or years.
       
  2096 
       
  2097     A QDateTime object is typically created either by giving a date
       
  2098     and time explicitly in the constructor, or by using the static
       
  2099     function currentDateTime() that returns a QDateTime object set
       
  2100     to the system clock's time. The date and time can be changed with
       
  2101     setDate() and setTime(). A datetime can also be set using the
       
  2102     setTime_t() function that takes a POSIX-standard "number of
       
  2103     seconds since 00:00:00 on January 1, 1970" value. The fromString()
       
  2104     function returns a QDateTime, given a string and a date format
       
  2105     used to interpret the date within the string.
       
  2106 
       
  2107     The date() and time() functions provide access to the date and
       
  2108     time parts of the datetime. The same information is provided in
       
  2109     textual format by the toString() function.
       
  2110 
       
  2111     QDateTime provides a full set of operators to compare two
       
  2112     QDateTime objects where smaller means earlier and larger means
       
  2113     later.
       
  2114 
       
  2115     You can increment (or decrement) a datetime by a given number of
       
  2116     seconds using addSecs(), or days using addDays(). Similarly you can
       
  2117     use addMonths() and addYears(). The daysTo() function returns the
       
  2118     number of days between two datetimes, and secsTo() returns the
       
  2119     number of seconds between two datetimes.
       
  2120 
       
  2121     QDateTime can store datetimes as \l{Qt::LocalTime}{local time} or
       
  2122     as \l{Qt::UTC}{UTC}. QDateTime::currentDateTime() returns a
       
  2123     QDateTime expressed as local time; use toUTC() to convert it to
       
  2124     UTC. You can also use timeSpec() to find out if a QDateTime
       
  2125     object stores a UTC time or a local time. Operations such as
       
  2126     addSecs() and secsTo() are aware of daylight saving time (DST).
       
  2127 
       
  2128     \note QDateTime does not account for leap seconds.
       
  2129 
       
  2130     \section1
       
  2131 
       
  2132     \target QDateTime G and J
       
  2133     \section2 Use of Gregorian and Julian Calendars
       
  2134 
       
  2135     QDate uses the Gregorian calendar in all locales, beginning
       
  2136     on the date 15 October 1582. For dates up to and including 4
       
  2137     October 1582, the Julian calendar is used.  This means there is a
       
  2138     10-day gap in the internal calendar between the 4th and the 15th
       
  2139     of October 1582. When you use QDateTime for dates in that epoch,
       
  2140     the day after 4 October 1582 is 15 October 1582, and the dates in
       
  2141     the gap are invalid.
       
  2142 
       
  2143     The Julian to Gregorian changeover date used here is the date when
       
  2144     the Gregorian calendar was first introduced, by Pope Gregory
       
  2145     XIII. That change was not universally accepted and some localities
       
  2146     only executed it at a later date (if at all).  QDateTime
       
  2147     doesn't take any of these historical facts into account. If an
       
  2148     application must support a locale-specific dating system, it must
       
  2149     do so on its own, remembering to convert the dates using the
       
  2150     Julian day.
       
  2151 
       
  2152     \section2 No Year 0
       
  2153 
       
  2154     There is no year 0. Dates in that year are considered invalid. The
       
  2155     year -1 is the year "1 before Christ" or "1 before current era."
       
  2156     The day before 0001-01-01 is December 31st, 1 BCE.
       
  2157 
       
  2158     \section2 Range of Valid Dates
       
  2159 
       
  2160     The range of valid dates is from January 2nd, 4713 BCE, to
       
  2161     sometime in the year 11 million CE. The Julian Day returned by
       
  2162     QDate::toJulianDay() is a number in the contiguous range from 1 to
       
  2163     \e{overflow}, even across QDateTime's "date holes". It is suitable
       
  2164     for use in applications that must convert a QDateTime to a date in
       
  2165     another calendar system, e.g., Hebrew, Islamic or Chinese.
       
  2166 
       
  2167     The Gregorian calendar was introduced in different places around
       
  2168     the world on different dates. QDateTime uses QDate to store the
       
  2169     date, so it uses the Gregorian calendar for all locales, beginning
       
  2170     on the date 15 October 1582. For dates up to and including 4
       
  2171     October 1582, QDateTime uses the Julian calendar.  This means
       
  2172     there is a 10-day gap in the QDateTime calendar between the 4th
       
  2173     and the 15th of October 1582. When you use QDateTime for dates in
       
  2174     that epoch, the day after 4 October 1582 is 15 October 1582, and
       
  2175     the dates in the gap are invalid.
       
  2176 
       
  2177     \section2
       
  2178     Use of System Timezone
       
  2179 
       
  2180     QDateTime uses the system's time zone information to determine the
       
  2181     offset of local time from UTC. If the system is not configured
       
  2182     correctly or not up-to-date, QDateTime will give wrong results as
       
  2183     well.
       
  2184 
       
  2185     \section2 Daylight Savings Time (DST)
       
  2186 
       
  2187     QDateTime takes into account the system's time zone information
       
  2188     when dealing with DST. On modern Unix systems, this means it
       
  2189     applies the correct historical DST data whenever possible. On
       
  2190     Windows and Windows CE, where the system doesn't support
       
  2191     historical DST data, historical accuracy is not maintained with
       
  2192     respect to DST.
       
  2193 
       
  2194     The range of valid dates taking DST into account is 1970-01-01 to
       
  2195     the present, and rules are in place for handling DST correctly
       
  2196     until 2037-12-31, but these could change. For dates falling
       
  2197     outside that range, QDateTime makes a \e{best guess} using the
       
  2198     rules for year 1970 or 2037, but we can't guarantee accuracy. This
       
  2199     means QDateTime doesn't take into account changes in a locale's
       
  2200     time zone before 1970, even if the system's time zone database
       
  2201     supports that information.
       
  2202 
       
  2203     \sa QDate QTime QDateTimeEdit
       
  2204 */
       
  2205 
       
  2206 /*!
       
  2207     Constructs a null datetime (i.e. null date and null time). A null
       
  2208     datetime is invalid, since the date is invalid.
       
  2209 
       
  2210     \sa isValid()
       
  2211 */
       
  2212 QDateTime::QDateTime()
       
  2213     : d(new QDateTimePrivate)
       
  2214 {
       
  2215 }
       
  2216 
       
  2217 
       
  2218 /*!
       
  2219     Constructs a datetime with the given \a date, a valid
       
  2220     time(00:00:00.000), and sets the timeSpec() to Qt::LocalTime.
       
  2221 */
       
  2222 
       
  2223 QDateTime::QDateTime(const QDate &date)
       
  2224     : d(new QDateTimePrivate)
       
  2225 {
       
  2226     d->date = date;
       
  2227     d->time = QTime(0, 0, 0);
       
  2228 }
       
  2229 
       
  2230 /*!
       
  2231     Constructs a datetime with the given \a date and \a time, using
       
  2232     the time specification defined by \a spec.
       
  2233 
       
  2234     If \a date is valid and \a time is not, the time will be set to midnight.
       
  2235 */
       
  2236 
       
  2237 QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec)
       
  2238     : d(new QDateTimePrivate)
       
  2239 {
       
  2240     d->date = date;
       
  2241     d->time = date.isValid() && !time.isValid() ? QTime(0, 0, 0) : time;
       
  2242     d->spec = (spec == Qt::UTC) ? QDateTimePrivate::UTC : QDateTimePrivate::LocalUnknown;
       
  2243 }
       
  2244 
       
  2245 /*!
       
  2246     Constructs a copy of the \a other datetime.
       
  2247 */
       
  2248 
       
  2249 QDateTime::QDateTime(const QDateTime &other)
       
  2250     : d(other.d)
       
  2251 {
       
  2252 }
       
  2253 
       
  2254 /*!
       
  2255     Destroys the datetime.
       
  2256 */
       
  2257 QDateTime::~QDateTime()
       
  2258 {
       
  2259 }
       
  2260 
       
  2261 /*!
       
  2262     Makes a copy of the \a other datetime and returns a reference to the
       
  2263     copy.
       
  2264 */
       
  2265 
       
  2266 QDateTime &QDateTime::operator=(const QDateTime &other)
       
  2267 {
       
  2268     d = other.d;
       
  2269     return *this;
       
  2270 }
       
  2271 
       
  2272 /*!
       
  2273     Returns true if both the date and the time are null; otherwise
       
  2274     returns false. A null datetime is invalid.
       
  2275 
       
  2276     \sa QDate::isNull(), QTime::isNull(), isValid()
       
  2277 */
       
  2278 
       
  2279 bool QDateTime::isNull() const
       
  2280 {
       
  2281     return d->date.isNull() && d->time.isNull();
       
  2282 }
       
  2283 
       
  2284 /*!
       
  2285     Returns true if both the date and the time are valid; otherwise
       
  2286     returns false.
       
  2287 
       
  2288     \sa QDate::isValid(), QTime::isValid()
       
  2289 */
       
  2290 
       
  2291 bool QDateTime::isValid() const
       
  2292 {
       
  2293     return d->date.isValid() && d->time.isValid();
       
  2294 }
       
  2295 
       
  2296 /*!
       
  2297     Returns the date part of the datetime.
       
  2298 
       
  2299     \sa setDate(), time(), timeSpec()
       
  2300 */
       
  2301 
       
  2302 QDate QDateTime::date() const
       
  2303 {
       
  2304     return d->date;
       
  2305 }
       
  2306 
       
  2307 /*!
       
  2308     Returns the time part of the datetime.
       
  2309 
       
  2310     \sa setTime(), date(), timeSpec()
       
  2311 */
       
  2312 
       
  2313 QTime QDateTime::time() const
       
  2314 {
       
  2315     return d->time;
       
  2316 }
       
  2317 
       
  2318 /*!
       
  2319     Returns the time specification of the datetime.
       
  2320 
       
  2321     \sa setTimeSpec(), date(), time(), Qt::TimeSpec
       
  2322 */
       
  2323 
       
  2324 Qt::TimeSpec QDateTime::timeSpec() const
       
  2325 {
       
  2326     switch(d->spec)
       
  2327     {
       
  2328         case QDateTimePrivate::UTC:
       
  2329             return Qt::UTC;
       
  2330         case QDateTimePrivate::OffsetFromUTC:
       
  2331             return Qt::OffsetFromUTC;
       
  2332         default:
       
  2333             return Qt::LocalTime;
       
  2334     }
       
  2335 }
       
  2336 
       
  2337 /*!
       
  2338     Sets the date part of this datetime to \a date.
       
  2339     If no time is set, it is set to midnight.
       
  2340 
       
  2341     \sa date(), setTime(), setTimeSpec()
       
  2342 */
       
  2343 
       
  2344 void QDateTime::setDate(const QDate &date)
       
  2345 {
       
  2346     detach();
       
  2347     d->date = date;
       
  2348     if (d->spec == QDateTimePrivate::LocalStandard
       
  2349         || d->spec == QDateTimePrivate::LocalDST)
       
  2350         d->spec = QDateTimePrivate::LocalUnknown;
       
  2351     if (date.isValid() && !d->time.isValid())
       
  2352         d->time = QTime(0, 0, 0);
       
  2353 }
       
  2354 
       
  2355 /*!
       
  2356     Sets the time part of this datetime to \a time.
       
  2357 
       
  2358     \sa time(), setDate(), setTimeSpec()
       
  2359 */
       
  2360 
       
  2361 void QDateTime::setTime(const QTime &time)
       
  2362 {
       
  2363     detach();
       
  2364     if (d->spec == QDateTimePrivate::LocalStandard
       
  2365         || d->spec == QDateTimePrivate::LocalDST)
       
  2366         d->spec = QDateTimePrivate::LocalUnknown;
       
  2367     d->time = time;
       
  2368 }
       
  2369 
       
  2370 /*!
       
  2371     Sets the time specification used in this datetime to \a spec.
       
  2372 
       
  2373     \sa timeSpec(), setDate(), setTime(), Qt::TimeSpec
       
  2374 */
       
  2375 
       
  2376 void QDateTime::setTimeSpec(Qt::TimeSpec spec)
       
  2377 {
       
  2378     detach();
       
  2379 
       
  2380     switch(spec)
       
  2381     {
       
  2382         case Qt::UTC:
       
  2383             d->spec = QDateTimePrivate::UTC;
       
  2384             break;
       
  2385         case Qt::OffsetFromUTC:
       
  2386             d->spec = QDateTimePrivate::OffsetFromUTC;
       
  2387             break;
       
  2388         default:
       
  2389             d->spec = QDateTimePrivate::LocalUnknown;
       
  2390             break;
       
  2391     }
       
  2392 }
       
  2393 
       
  2394 static uint toTime_tHelper(const QDate &utcDate, const QTime &utcTime)
       
  2395 {
       
  2396     int days = QDate(1970, 1, 1).daysTo(utcDate);
       
  2397     int secs = QTime().secsTo(utcTime);
       
  2398     if (days < 0 || (days == 0 && secs < 0))
       
  2399         return uint(-1);
       
  2400 
       
  2401     qlonglong retval = (qlonglong(days) * SECS_PER_DAY) + secs;
       
  2402     if (retval >= Q_INT64_C(0xFFFFFFFF))
       
  2403         return uint(-1);
       
  2404     return uint(retval);
       
  2405 }
       
  2406 
       
  2407 /*!
       
  2408     Returns the datetime as the number of seconds that have passed
       
  2409     since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC).
       
  2410 
       
  2411     On systems that do not support time zones, this function will
       
  2412     behave as if local time were Qt::UTC.
       
  2413 
       
  2414     \sa setTime_t()
       
  2415 */
       
  2416 
       
  2417 uint QDateTime::toTime_t() const
       
  2418 {
       
  2419     QDate utcDate;
       
  2420     QTime utcTime;
       
  2421     d->getUTC(utcDate, utcTime);
       
  2422 
       
  2423     return toTime_tHelper(utcDate, utcTime);
       
  2424 }
       
  2425 
       
  2426 /*!
       
  2427     \fn void QDateTime::setTime_t(uint seconds)
       
  2428 
       
  2429     Sets the date and time given the number of \a seconds that have
       
  2430     passed since 1970-01-01T00:00:00, Coordinated Universal Time
       
  2431     (Qt::UTC). On systems that do not support time zones this function
       
  2432     will behave as if local time were Qt::UTC.
       
  2433 
       
  2434     \sa toTime_t()
       
  2435 */
       
  2436 
       
  2437 void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
       
  2438 {
       
  2439     detach();
       
  2440 
       
  2441     QDateTimePrivate::Spec oldSpec = d->spec;
       
  2442 
       
  2443     d->date = QDate(1970, 1, 1).addDays(secsSince1Jan1970UTC / SECS_PER_DAY);
       
  2444     d->time = QTime().addSecs(secsSince1Jan1970UTC % SECS_PER_DAY);
       
  2445     d->spec = QDateTimePrivate::UTC;
       
  2446 
       
  2447     if (oldSpec != QDateTimePrivate::UTC)
       
  2448         d->spec = d->getLocal(d->date, d->time);
       
  2449 }
       
  2450 
       
  2451 #ifndef QT_NO_DATESTRING
       
  2452 /*!
       
  2453     \fn QString QDateTime::toString(Qt::DateFormat format) const
       
  2454 
       
  2455     \overload
       
  2456 
       
  2457     Returns the datetime as a string in the \a format given.
       
  2458 
       
  2459     If the \a format is Qt::TextDate, the string is formatted in
       
  2460     the default way. QDate::shortDayName(), QDate::shortMonthName(),
       
  2461     and QTime::toString() are used to generate the string, so the
       
  2462     day and month names will be localized names. An example of this
       
  2463     formatting is "Wed May 20 03:40:13 1998".
       
  2464 
       
  2465     If the \a format is Qt::ISODate, the string format corresponds
       
  2466     to the ISO 8601 extended specification for representations of
       
  2467     dates and times, taking the form YYYY-MM-DDTHH:MM:SS.
       
  2468 
       
  2469     If the \a format is Qt::SystemLocaleShortDate or
       
  2470     Qt::SystemLocaleLongDate, the string format depends on the locale
       
  2471     settings of the system. Identical to calling
       
  2472     QLocale::system().toString(datetime, QLocale::ShortFormat) or
       
  2473     QLocale::system().toString(datetime, QLocale::LongFormat).
       
  2474 
       
  2475     If the \a format is Qt::DefaultLocaleShortDate or
       
  2476     Qt::DefaultLocaleLongDate, the string format depends on the
       
  2477     default application locale. This is the locale set with
       
  2478     QLocale::setDefault(), or the system locale if no default locale
       
  2479     has been set. Identical to calling QLocale().toString(datetime,
       
  2480     QLocale::ShortFormat) or QLocale().toString(datetime,
       
  2481     QLocale::LongFormat).
       
  2482 
       
  2483     If the datetime is invalid, an empty string will be returned.
       
  2484 
       
  2485     \warning The Qt::ISODate format is only valid for years in the
       
  2486     range 0 to 9999. This restriction may apply to locale-aware
       
  2487     formats as well, depending on the locale settings.
       
  2488 
       
  2489     \sa QDate::toString() QTime::toString() Qt::DateFormat
       
  2490 */
       
  2491 
       
  2492 QString QDateTime::toString(Qt::DateFormat f) const
       
  2493 {
       
  2494     QString buf;
       
  2495     if (!isValid())
       
  2496         return buf;
       
  2497 
       
  2498     if (f == Qt::ISODate) {
       
  2499         buf = d->date.toString(Qt::ISODate);
       
  2500         if (buf.isEmpty())
       
  2501             return QString();   // failed to convert
       
  2502         buf += QLatin1Char('T');
       
  2503         buf += d->time.toString(Qt::ISODate);
       
  2504     }
       
  2505 #ifndef QT_NO_TEXTDATE
       
  2506     else if (f == Qt::TextDate) {
       
  2507 #ifndef Q_WS_WIN
       
  2508         buf = d->date.shortDayName(d->date.dayOfWeek());
       
  2509         buf += QLatin1Char(' ');
       
  2510         buf += d->date.shortMonthName(d->date.month());
       
  2511         buf += QLatin1Char(' ');
       
  2512         buf += QString::number(d->date.day());
       
  2513 #else
       
  2514         wchar_t out[255];
       
  2515         GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255);
       
  2516         QString winstr = QString::fromWCharArray(out);
       
  2517         switch (winstr.toInt()) {
       
  2518         case 1:
       
  2519             buf = d->date.shortDayName(d->date.dayOfWeek());
       
  2520             buf += QLatin1Char(' ');
       
  2521             buf += QString::number(d->date.day());
       
  2522             buf += QLatin1String(". ");
       
  2523             buf += d->date.shortMonthName(d->date.month());
       
  2524             break;
       
  2525         default:
       
  2526             buf = d->date.shortDayName(d->date.dayOfWeek());
       
  2527             buf += QLatin1Char(' ');
       
  2528             buf += d->date.shortMonthName(d->date.month());
       
  2529             buf += QLatin1Char(' ');
       
  2530             buf += QString::number(d->date.day());
       
  2531         }
       
  2532 #endif
       
  2533         buf += QLatin1Char(' ');
       
  2534         buf += d->time.toString();
       
  2535         buf += QLatin1Char(' ');
       
  2536         buf += QString::number(d->date.year());
       
  2537     }
       
  2538 #endif
       
  2539     else {
       
  2540         buf = d->date.toString(f);
       
  2541         if (buf.isEmpty())
       
  2542             return QString();   // failed to convert
       
  2543         buf += QLatin1Char(' ');
       
  2544         buf += d->time.toString(f);
       
  2545     }
       
  2546 
       
  2547     return buf;
       
  2548 }
       
  2549 
       
  2550 /*!
       
  2551     Returns the datetime as a string. The \a format parameter
       
  2552     determines the format of the result string.
       
  2553 
       
  2554     These expressions may be used for the date:
       
  2555 
       
  2556     \table
       
  2557     \header \i Expression \i Output
       
  2558     \row \i d \i the day as number without a leading zero (1 to 31)
       
  2559     \row \i dd \i the day as number with a leading zero (01 to 31)
       
  2560     \row \i ddd
       
  2561             \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
       
  2562             Uses QDate::shortDayName().
       
  2563     \row \i dddd
       
  2564             \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
       
  2565             Uses QDate::longDayName().
       
  2566     \row \i M \i the month as number without a leading zero (1-12)
       
  2567     \row \i MM \i the month as number with a leading zero (01-12)
       
  2568     \row \i MMM
       
  2569             \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
       
  2570             Uses QDate::shortMonthName().
       
  2571     \row \i MMMM
       
  2572             \i the long localized month name (e.g. 'January' to 'December').
       
  2573             Uses QDate::longMonthName().
       
  2574     \row \i yy \i the year as two digit number (00-99)
       
  2575     \row \i yyyy \i the year as four digit number
       
  2576     \endtable
       
  2577 
       
  2578     These expressions may be used for the time:
       
  2579 
       
  2580     \table
       
  2581     \header \i Expression \i Output
       
  2582     \row \i h
       
  2583          \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
       
  2584     \row \i hh
       
  2585          \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
       
  2586     \row \i m \i the minute without a leading zero (0 to 59)
       
  2587     \row \i mm \i the minute with a leading zero (00 to 59)
       
  2588     \row \i s \i the second without a leading zero (0 to 59)
       
  2589     \row \i ss \i the second with a leading zero (00 to 59)
       
  2590     \row \i z \i the milliseconds without leading zeroes (0 to 999)
       
  2591     \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
       
  2592     \row \i AP
       
  2593             \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
       
  2594     \row \i ap
       
  2595             \i use am/pm display. \e ap will be replaced by either "am" or "pm".
       
  2596     \endtable
       
  2597 
       
  2598     All other input characters will be ignored. Any sequence of characters that
       
  2599     are enclosed in singlequotes will be treated as text and not be used as an
       
  2600     expression. Two consecutive singlequotes ("''") are replaced by a singlequote
       
  2601     in the output.
       
  2602 
       
  2603     Example format strings (assumed that the QDateTime is 21 May 2001
       
  2604     14:13:09):
       
  2605 
       
  2606     \table
       
  2607     \header \i Format       \i Result
       
  2608     \row \i dd.MM.yyyy      \i 21.05.2001
       
  2609     \row \i ddd MMMM d yy   \i Tue May 21 01
       
  2610     \row \i hh:mm:ss.zzz    \i 14:13:09.042
       
  2611     \row \i h:m:s ap        \i 2:13:9 pm
       
  2612     \endtable
       
  2613 
       
  2614     If the datetime is invalid, an empty string will be returned.
       
  2615 
       
  2616     \sa QDate::toString() QTime::toString()
       
  2617 */
       
  2618 QString QDateTime::toString(const QString& format) const
       
  2619 {
       
  2620     return fmtDateTime(format, &d->time, &d->date);
       
  2621 }
       
  2622 #endif //QT_NO_DATESTRING
       
  2623 
       
  2624 /*!
       
  2625     Returns a QDateTime object containing a datetime \a ndays days
       
  2626     later than the datetime of this object (or earlier if \a ndays is
       
  2627     negative).
       
  2628 
       
  2629     \sa daysTo(), addMonths(), addYears(), addSecs()
       
  2630 */
       
  2631 
       
  2632 QDateTime QDateTime::addDays(int ndays) const
       
  2633 {
       
  2634     return QDateTime(d->date.addDays(ndays), d->time, timeSpec());
       
  2635 }
       
  2636 
       
  2637 /*!
       
  2638     Returns a QDateTime object containing a datetime \a nmonths months
       
  2639     later than the datetime of this object (or earlier if \a nmonths
       
  2640     is negative).
       
  2641 
       
  2642     \sa daysTo(), addDays(), addYears(), addSecs()
       
  2643 */
       
  2644 
       
  2645 QDateTime QDateTime::addMonths(int nmonths) const
       
  2646 {
       
  2647     return QDateTime(d->date.addMonths(nmonths), d->time, timeSpec());
       
  2648 }
       
  2649 
       
  2650 /*!
       
  2651     Returns a QDateTime object containing a datetime \a nyears years
       
  2652     later than the datetime of this object (or earlier if \a nyears is
       
  2653     negative).
       
  2654 
       
  2655     \sa daysTo(), addDays(), addMonths(), addSecs()
       
  2656 */
       
  2657 
       
  2658 QDateTime QDateTime::addYears(int nyears) const
       
  2659 {
       
  2660     return QDateTime(d->date.addYears(nyears), d->time, timeSpec());
       
  2661 }
       
  2662 
       
  2663 QDateTime QDateTimePrivate::addMSecs(const QDateTime &dt, qint64 msecs)
       
  2664 {
       
  2665     QDate utcDate;
       
  2666     QTime utcTime;
       
  2667     dt.d->getUTC(utcDate, utcTime);
       
  2668 
       
  2669     addMSecs(utcDate, utcTime, msecs);
       
  2670 
       
  2671     return QDateTime(utcDate, utcTime, Qt::UTC).toTimeSpec(dt.timeSpec());
       
  2672 }
       
  2673 
       
  2674 /*!
       
  2675  Adds \a msecs to utcDate and \a utcTime as appropriate. It is assumed that
       
  2676  utcDate and utcTime are adjusted to UTC.
       
  2677 
       
  2678  \since 4.5
       
  2679  \internal
       
  2680  */
       
  2681 void QDateTimePrivate::addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs)
       
  2682 {
       
  2683     uint dd = utcDate.jd;
       
  2684     int tt = utcTime.ds();
       
  2685     int sign = 1;
       
  2686     if (msecs < 0) {
       
  2687         msecs = -msecs;
       
  2688         sign = -1;
       
  2689     }
       
  2690     if (msecs >= int(MSECS_PER_DAY)) {
       
  2691         dd += sign * (msecs / MSECS_PER_DAY);
       
  2692         msecs %= MSECS_PER_DAY;
       
  2693     }
       
  2694 
       
  2695     tt += sign * msecs;
       
  2696     if (tt < 0) {
       
  2697         tt = MSECS_PER_DAY - tt - 1;
       
  2698         dd -= tt / MSECS_PER_DAY;
       
  2699         tt = tt % MSECS_PER_DAY;
       
  2700         tt = MSECS_PER_DAY - tt - 1;
       
  2701     } else if (tt >= int(MSECS_PER_DAY)) {
       
  2702         dd += tt / MSECS_PER_DAY;
       
  2703         tt = tt % MSECS_PER_DAY;
       
  2704     }
       
  2705 
       
  2706     utcDate.jd = dd;
       
  2707     utcTime.mds = tt;
       
  2708 }
       
  2709 
       
  2710 /*!
       
  2711     Returns a QDateTime object containing a datetime \a s seconds
       
  2712     later than the datetime of this object (or earlier if \a s is
       
  2713     negative).
       
  2714 
       
  2715     \sa addMSecs(), secsTo(), addDays(), addMonths(), addYears()
       
  2716 */
       
  2717 
       
  2718 QDateTime QDateTime::addSecs(int s) const
       
  2719 {
       
  2720     return d->addMSecs(*this, qint64(s) * 1000);
       
  2721 }
       
  2722 
       
  2723 /*!
       
  2724     Returns a QDateTime object containing a datetime \a msecs miliseconds
       
  2725     later than the datetime of this object (or earlier if \a msecs is
       
  2726     negative).
       
  2727 
       
  2728     \sa addSecs(), secsTo(), addDays(), addMonths(), addYears()
       
  2729 */
       
  2730 QDateTime QDateTime::addMSecs(qint64 msecs) const
       
  2731 {
       
  2732     return d->addMSecs(*this, msecs);
       
  2733 }
       
  2734 
       
  2735 /*!
       
  2736     Returns the number of days from this datetime to the \a other
       
  2737     datetime. If the \a other datetime is earlier than this datetime,
       
  2738     the value returned is negative.
       
  2739 
       
  2740     \sa addDays(), secsTo()
       
  2741 */
       
  2742 
       
  2743 int QDateTime::daysTo(const QDateTime &other) const
       
  2744 {
       
  2745     return d->date.daysTo(other.d->date);
       
  2746 }
       
  2747 
       
  2748 /*!
       
  2749     Returns the number of seconds from this datetime to the \a other
       
  2750     datetime. If the \a other datetime is earlier than this datetime,
       
  2751     the value returned is negative.
       
  2752 
       
  2753     Before performing the comparison, the two datetimes are converted
       
  2754     to Qt::UTC to ensure that the result is correct if one of the two
       
  2755     datetimes has daylight saving time (DST) and the other doesn't.
       
  2756 
       
  2757     Example:
       
  2758     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 11
       
  2759 
       
  2760     \sa addSecs(), daysTo(), QTime::secsTo()
       
  2761 */
       
  2762 
       
  2763 int QDateTime::secsTo(const QDateTime &other) const
       
  2764 {
       
  2765     QDate date1, date2;
       
  2766     QTime time1, time2;
       
  2767 
       
  2768     d->getUTC(date1, time1);
       
  2769     other.d->getUTC(date2, time2);
       
  2770 
       
  2771     return (date1.daysTo(date2) * SECS_PER_DAY) + time1.secsTo(time2);
       
  2772 }
       
  2773 
       
  2774 /*!
       
  2775     \fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec specification) const
       
  2776 
       
  2777     Returns a copy of this datetime configured to use the given time
       
  2778     \a specification.
       
  2779 
       
  2780     \sa timeSpec(), toUTC(), toLocalTime()
       
  2781 */
       
  2782 
       
  2783 QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
       
  2784 {
       
  2785     if ((d->spec == QDateTimePrivate::UTC) == (spec == Qt::UTC))
       
  2786         return *this;
       
  2787 
       
  2788     QDateTime ret;
       
  2789     if (spec == Qt::UTC) {
       
  2790         d->getUTC(ret.d->date, ret.d->time);
       
  2791         ret.d->spec = QDateTimePrivate::UTC;
       
  2792     } else {
       
  2793         ret.d->spec = d->getLocal(ret.d->date, ret.d->time);
       
  2794     }
       
  2795     return ret;
       
  2796 }
       
  2797 
       
  2798 /*!
       
  2799     Returns true if this datetime is equal to the \a other datetime;
       
  2800     otherwise returns false.
       
  2801 
       
  2802     \sa operator!=()
       
  2803 */
       
  2804 
       
  2805 bool QDateTime::operator==(const QDateTime &other) const
       
  2806 {
       
  2807     if (d->spec == other.d->spec && d->utcOffset == other.d->utcOffset)
       
  2808         return d->time == other.d->time && d->date == other.d->date;
       
  2809     else {
       
  2810         QDate date1, date2;
       
  2811         QTime time1, time2;
       
  2812 
       
  2813         d->getUTC(date1, time1);
       
  2814         other.d->getUTC(date2, time2);
       
  2815         return time1 == time2 && date1 == date2;
       
  2816     }
       
  2817 }
       
  2818 
       
  2819 /*!
       
  2820     \fn bool QDateTime::operator!=(const QDateTime &other) const
       
  2821 
       
  2822     Returns true if this datetime is different from the \a other
       
  2823     datetime; otherwise returns false.
       
  2824 
       
  2825     Two datetimes are different if either the date, the time, or the
       
  2826     time zone components are different.
       
  2827 
       
  2828     \sa operator==()
       
  2829 */
       
  2830 
       
  2831 /*!
       
  2832     Returns true if this datetime is earlier than the \a other
       
  2833     datetime; otherwise returns false.
       
  2834 */
       
  2835 
       
  2836 bool QDateTime::operator<(const QDateTime &other) const
       
  2837 {
       
  2838     if (d->spec == other.d->spec && d->spec != QDateTimePrivate::OffsetFromUTC) {
       
  2839         if (d->date != other.d->date)
       
  2840             return d->date < other.d->date;
       
  2841         return d->time < other.d->time;
       
  2842     } else {
       
  2843         QDate date1, date2;
       
  2844         QTime time1, time2;
       
  2845         d->getUTC(date1, time1);
       
  2846         other.d->getUTC(date2, time2);
       
  2847         if (date1 != date2)
       
  2848             return date1 < date2;
       
  2849         return time1 < time2;
       
  2850     }
       
  2851 }
       
  2852 
       
  2853 /*!
       
  2854     \fn bool QDateTime::operator<=(const QDateTime &other) const
       
  2855 
       
  2856     Returns true if this datetime is earlier than or equal to the
       
  2857     \a other datetime; otherwise returns false.
       
  2858 */
       
  2859 
       
  2860 /*!
       
  2861     \fn bool QDateTime::operator>(const QDateTime &other) const
       
  2862 
       
  2863     Returns true if this datetime is later than the \a other datetime;
       
  2864     otherwise returns false.
       
  2865 */
       
  2866 
       
  2867 /*!
       
  2868     \fn bool QDateTime::operator>=(const QDateTime &other) const
       
  2869 
       
  2870     Returns true if this datetime is later than or equal to the
       
  2871     \a other datetime; otherwise returns false.
       
  2872 */
       
  2873 
       
  2874 /*!
       
  2875     Returns the current datetime, as reported by the system clock, in
       
  2876     the local time zone.
       
  2877 
       
  2878     \sa QDate::currentDate(), QTime::currentTime(), toTimeSpec()
       
  2879 */
       
  2880 
       
  2881 QDateTime QDateTime::currentDateTime()
       
  2882 {
       
  2883 #if defined(Q_OS_WIN)
       
  2884     QDate d;
       
  2885     QTime t;
       
  2886     SYSTEMTIME st;
       
  2887     memset(&st, 0, sizeof(SYSTEMTIME));
       
  2888     GetLocalTime(&st);
       
  2889     d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
       
  2890     t.mds = MSECS_PER_HOUR * st.wHour + MSECS_PER_MIN * st.wMinute + 1000 * st.wSecond
       
  2891             + st.wMilliseconds;
       
  2892     return QDateTime(d, t);
       
  2893 #elif defined(Q_OS_SYMBIAN)
       
  2894     return QDateTime(QDate::currentDate(), QTime::currentTime());
       
  2895 #else
       
  2896 #if defined(Q_OS_UNIX)
       
  2897     // posix compliant system
       
  2898     // we have milliseconds
       
  2899     struct timeval tv;
       
  2900     gettimeofday(&tv, 0);
       
  2901     time_t ltime = tv.tv_sec;
       
  2902     tm *t = 0;
       
  2903 
       
  2904 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
       
  2905     // use the reentrant version of localtime() where available
       
  2906     tzset();
       
  2907     tm res;
       
  2908     t = localtime_r(&ltime, &res);
       
  2909 #else
       
  2910     t = localtime(&ltime);
       
  2911 #endif
       
  2912 
       
  2913     QDateTime dt;
       
  2914     dt.d->time.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec
       
  2915                      + tv.tv_usec / 1000;
       
  2916 #else
       
  2917     time_t ltime; // no millisecond resolution
       
  2918     ::time(&ltime);
       
  2919     tm *t = 0;
       
  2920     localtime(&ltime);
       
  2921     dt.d->time.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec;
       
  2922 #endif // Q_OS_UNIX
       
  2923 
       
  2924     dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
       
  2925     dt.d->spec = t->tm_isdst > 0  ? QDateTimePrivate::LocalDST :
       
  2926                  t->tm_isdst == 0 ? QDateTimePrivate::LocalStandard :
       
  2927                  QDateTimePrivate::LocalUnknown;
       
  2928     return dt;
       
  2929 #endif
       
  2930 }
       
  2931 
       
  2932 /*!
       
  2933   \since 4.2
       
  2934 
       
  2935   Returns a datetime whose date and time are the number of \a seconds
       
  2936   that have passed since 1970-01-01T00:00:00, Coordinated Universal
       
  2937   Time (Qt::UTC). On systems that do not support time zones, the time
       
  2938   will be set as if local time were Qt::UTC.
       
  2939 
       
  2940   \sa toTime_t(), setTime_t()
       
  2941 */
       
  2942 QDateTime QDateTime::fromTime_t(uint seconds)
       
  2943 {
       
  2944     QDateTime d;
       
  2945     d.setTime_t(seconds);
       
  2946     return d;
       
  2947 }
       
  2948 
       
  2949 /*!
       
  2950  \since 4.4
       
  2951  \internal
       
  2952 
       
  2953  Sets the offset from UTC to \a seconds, and also sets timeSpec() to
       
  2954  Qt::OffsetFromUTC.
       
  2955 
       
  2956  The maximum and minimum offset is 14 positive or negative hours.  If
       
  2957  \a seconds is larger or smaller than that, the result is undefined.
       
  2958 
       
  2959  0 as offset is identical to UTC. Therefore, if \a seconds is 0, the
       
  2960  timeSpec() will be set to Qt::UTC. Hence the UTC offset always
       
  2961  relates to UTC, and can never relate to local time.
       
  2962 
       
  2963  \sa isValid(), utcOffset()
       
  2964  */
       
  2965 void QDateTime::setUtcOffset(int seconds)
       
  2966 {
       
  2967     detach();
       
  2968 
       
  2969     /* The motivation to also setting d->spec is to ensure that the QDateTime
       
  2970      * instance stay in well-defined states all the time, instead of that
       
  2971      * we instruct the user to ensure it. */
       
  2972     if(seconds == 0)
       
  2973         d->spec = QDateTimePrivate::UTC;
       
  2974     else
       
  2975         d->spec = QDateTimePrivate::OffsetFromUTC;
       
  2976 
       
  2977     /* Even if seconds is 0 we assign it to utcOffset. */
       
  2978     d->utcOffset = seconds;
       
  2979 }
       
  2980 
       
  2981 /*!
       
  2982  \since 4.4
       
  2983  \internal
       
  2984 
       
  2985  Returns the UTC offset in seconds. If the timeSpec() isn't
       
  2986  Qt::OffsetFromUTC, 0 is returned. However, since 0 is a valid UTC
       
  2987  offset the return value of this function cannot be used to determine
       
  2988  whether a utcOffset() is used or is valid, timeSpec() must be
       
  2989  checked.
       
  2990 
       
  2991  Likewise, if this QDateTime() is invalid or if timeSpec() isn't
       
  2992  Qt::OffsetFromUTC, 0 is returned.
       
  2993 
       
  2994  The UTC offset only applies if the timeSpec() is Qt::OffsetFromUTC.
       
  2995 
       
  2996  \sa isValid(), setUtcOffset()
       
  2997  */
       
  2998 int QDateTime::utcOffset() const
       
  2999 {
       
  3000     if(isValid() && d->spec == QDateTimePrivate::OffsetFromUTC)
       
  3001         return d->utcOffset;
       
  3002     else
       
  3003         return 0;
       
  3004 }
       
  3005 
       
  3006 #ifndef QT_NO_DATESTRING
       
  3007 
       
  3008 static int fromShortMonthName(const QString &monthName)
       
  3009 {
       
  3010     // Assume that English monthnames are the default
       
  3011     for (int i = 0; i < 12; ++i) {
       
  3012         if (monthName == QLatin1String(qt_shortMonthNames[i]))
       
  3013             return i + 1;
       
  3014     }
       
  3015     // If English names can't be found, search the localized ones
       
  3016     for (int i = 1; i <= 12; ++i) {
       
  3017         if (monthName == QDate::shortMonthName(i))
       
  3018             return i;
       
  3019     }
       
  3020     return -1;
       
  3021 }
       
  3022 
       
  3023 /*!
       
  3024     \fn QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
       
  3025 
       
  3026     Returns the QDateTime represented by the \a string, using the
       
  3027     \a format given, or an invalid datetime if this is not possible.
       
  3028 
       
  3029     Note for Qt::TextDate: It is recommended that you use the
       
  3030     English short month names (e.g. "Jan"). Although localized month
       
  3031     names can also be used, they depend on the user's locale settings.
       
  3032 */
       
  3033 QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
       
  3034 {
       
  3035     if (s.isEmpty()) {
       
  3036         return QDateTime();
       
  3037     }
       
  3038 
       
  3039     switch (f) {
       
  3040     case Qt::ISODate: {
       
  3041         QString tmp = s;
       
  3042         Qt::TimeSpec ts = Qt::LocalTime;
       
  3043         const QDate date = QDate::fromString(tmp.left(10), Qt::ISODate);
       
  3044         if (tmp.size() == 10)
       
  3045             return QDateTime(date);
       
  3046 
       
  3047         // Recognize UTC specifications
       
  3048         if (tmp.endsWith(QLatin1Char('Z'))) {
       
  3049             ts = Qt::UTC;
       
  3050             tmp.chop(1);
       
  3051         }
       
  3052         return QDateTime(date, QTime::fromString(tmp.mid(11), Qt::ISODate), ts);
       
  3053     }
       
  3054     case Qt::SystemLocaleDate:
       
  3055     case Qt::SystemLocaleShortDate:
       
  3056     case Qt::SystemLocaleLongDate:
       
  3057         return fromString(s, QLocale::system().dateTimeFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat
       
  3058                                                                                             : QLocale::ShortFormat));
       
  3059     case Qt::LocaleDate:
       
  3060     case Qt::DefaultLocaleShortDate:
       
  3061     case Qt::DefaultLocaleLongDate:
       
  3062         return fromString(s, QLocale().dateTimeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
       
  3063                                                                                      : QLocale::ShortFormat));
       
  3064 #if !defined(QT_NO_TEXTDATE)
       
  3065     case Qt::TextDate: {
       
  3066         QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts);
       
  3067 
       
  3068         if ((parts.count() < 5) || (parts.count() > 6)) {
       
  3069             return QDateTime();
       
  3070         }
       
  3071 
       
  3072         // Accept "Sun Dec 1 13:02:00 1974" and "Sun 1. Dec 13:02:00 1974"
       
  3073         int month = -1, day = -1;
       
  3074         bool ok;
       
  3075 
       
  3076         month = fromShortMonthName(parts.at(1));
       
  3077         if (month != -1) {
       
  3078             day = parts.at(2).toInt(&ok);
       
  3079             if (!ok)
       
  3080                 day = -1;
       
  3081         }
       
  3082 
       
  3083         if (month == -1 || day == -1) {
       
  3084             // first variant failed, lets try the other
       
  3085             month = fromShortMonthName(parts.at(2));
       
  3086             if (month != -1) {
       
  3087                 QString dayStr = parts.at(1);
       
  3088                 if (dayStr.endsWith(QLatin1Char('.'))) {
       
  3089                     dayStr.chop(1);
       
  3090                     day = dayStr.toInt(&ok);
       
  3091                     if (!ok)
       
  3092                         day = -1;
       
  3093                 } else {
       
  3094                     day = -1;
       
  3095                 }
       
  3096             }
       
  3097         }
       
  3098 
       
  3099         if (month == -1 || day == -1) {
       
  3100             // both variants failed, give up
       
  3101             return QDateTime();
       
  3102         }
       
  3103 
       
  3104         int year;
       
  3105         QStringList timeParts = parts.at(3).split(QLatin1Char(':'));
       
  3106         if ((timeParts.count() == 3) || (timeParts.count() == 2)) {
       
  3107             year = parts.at(4).toInt(&ok);
       
  3108             if (!ok)
       
  3109                 return QDateTime();
       
  3110         } else {
       
  3111             timeParts = parts.at(4).split(QLatin1Char(':'));
       
  3112             if ((timeParts.count() != 3) && (timeParts.count() != 2))
       
  3113                 return QDateTime();
       
  3114             year = parts.at(3).toInt(&ok);
       
  3115             if (!ok)
       
  3116                 return QDateTime();
       
  3117         }
       
  3118 
       
  3119         int hour = timeParts.at(0).toInt(&ok);
       
  3120         if (!ok) {
       
  3121             return QDateTime();
       
  3122         }
       
  3123 
       
  3124         int minute = timeParts.at(1).toInt(&ok);
       
  3125         if (!ok) {
       
  3126             return QDateTime();
       
  3127         }
       
  3128 
       
  3129         int second = (timeParts.count() > 2) ? timeParts.at(2).toInt(&ok) : 0;
       
  3130         if (!ok) {
       
  3131             return QDateTime();
       
  3132         }
       
  3133 
       
  3134         QDate date(year, month, day);
       
  3135         QTime time(hour, minute, second);
       
  3136 
       
  3137         if (parts.count() == 5)
       
  3138             return QDateTime(date, time, Qt::LocalTime);
       
  3139 
       
  3140         QString tz = parts.at(5);
       
  3141         if (!tz.startsWith(QLatin1String("GMT"), Qt::CaseInsensitive))
       
  3142             return QDateTime();
       
  3143         int tzoffset = 0;
       
  3144         if (tz.length() > 3) {
       
  3145             QChar sign = tz.at(3);
       
  3146             if ((sign != QLatin1Char('+'))
       
  3147                 && (sign != QLatin1Char('-'))) {
       
  3148                 return QDateTime();
       
  3149             }
       
  3150             int tzhour = tz.mid(4, 2).toInt(&ok);
       
  3151             if (!ok)
       
  3152                 return QDateTime();
       
  3153             int tzminute = tz.mid(6).toInt(&ok);
       
  3154             if (!ok)
       
  3155                 return QDateTime();
       
  3156             tzoffset = (tzhour*60 + tzminute) * 60;
       
  3157             if (sign == QLatin1Char('-'))
       
  3158                 tzoffset = -tzoffset;
       
  3159         }
       
  3160         return QDateTime(date, time, Qt::UTC).addSecs(-tzoffset).toLocalTime();
       
  3161     }
       
  3162 #endif //QT_NO_TEXTDATE
       
  3163     }
       
  3164 
       
  3165     return QDateTime();
       
  3166 }
       
  3167 
       
  3168 /*!
       
  3169     \fn QDateTime::fromString(const QString &string, const QString &format)
       
  3170 
       
  3171     Returns the QDateTime represented by the \a string, using the \a
       
  3172     format given, or an invalid datetime if the string cannot be parsed.
       
  3173 
       
  3174     These expressions may be used for the date part of the format string:
       
  3175 
       
  3176     \table
       
  3177     \header \i Expression \i Output
       
  3178     \row \i d \i the day as number without a leading zero (1 to 31)
       
  3179     \row \i dd \i the day as number with a leading zero (01 to 31)
       
  3180     \row \i ddd
       
  3181             \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
       
  3182             Uses QDate::shortDayName().
       
  3183     \row \i dddd
       
  3184             \i the long localized day name (e.g. 'Monday' to 'Sunday').
       
  3185             Uses QDate::longDayName().
       
  3186     \row \i M \i the month as number without a leading zero (1-12)
       
  3187     \row \i MM \i the month as number with a leading zero (01-12)
       
  3188     \row \i MMM
       
  3189             \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
       
  3190             Uses QDate::shortMonthName().
       
  3191     \row \i MMMM
       
  3192             \i the long localized month name (e.g. 'January' to 'December').
       
  3193             Uses QDate::longMonthName().
       
  3194     \row \i yy \i the year as two digit number (00-99)
       
  3195     \row \i yyyy \i the year as four digit number
       
  3196     \endtable
       
  3197 
       
  3198     \note Unlike the other version of this function, day and month names must
       
  3199     be given in the user's local language. It is only possible to use the English
       
  3200     names if the user's language is English.
       
  3201 
       
  3202     These expressions may be used for the time part of the format string:
       
  3203 
       
  3204     \table
       
  3205     \header \i Expression \i Output
       
  3206     \row \i h
       
  3207             \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
       
  3208     \row \i hh
       
  3209             \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
       
  3210     \row \i H
       
  3211             \i the hour without a leading zero (0 to 23, even with AM/PM display)
       
  3212     \row \i HH
       
  3213             \i the hour with a leading zero (00 to 23, even with AM/PM display)
       
  3214     \row \i m \i the minute without a leading zero (0 to 59)
       
  3215     \row \i mm \i the minute with a leading zero (00 to 59)
       
  3216     \row \i s \i the second without a leading zero (0 to 59)
       
  3217     \row \i ss \i the second with a leading zero (00 to 59)
       
  3218     \row \i z \i the milliseconds without leading zeroes (0 to 999)
       
  3219     \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
       
  3220     \row \i AP or A
       
  3221          \i interpret as an AM/PM time. \e AP must be either "AM" or "PM".
       
  3222     \row \i ap or a
       
  3223          \i Interpret as an AM/PM time. \e ap must be either "am" or "pm".
       
  3224     \endtable
       
  3225 
       
  3226     All other input characters will be treated as text. Any sequence
       
  3227     of characters that are enclosed in singlequotes will also be
       
  3228     treated as text and not be used as an expression.
       
  3229 
       
  3230     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 12
       
  3231 
       
  3232     If the format is not satisfied an invalid QDateTime is returned.
       
  3233     The expressions that don't have leading zeroes (d, M, h, m, s, z) will be
       
  3234     greedy. This means that they will use two digits even if this will
       
  3235     put them outside the range and/or leave too few digits for other
       
  3236     sections.
       
  3237 
       
  3238     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 13
       
  3239 
       
  3240     This could have meant 1 January 00:30.00 but the M will grab
       
  3241     two digits.
       
  3242 
       
  3243     For any field that is not represented in the format the following
       
  3244     defaults are used:
       
  3245 
       
  3246     \table
       
  3247     \header \i Field  \i Default value
       
  3248     \row    \i Year   \i 1900
       
  3249     \row    \i Month  \i 1 (January)
       
  3250     \row    \i Day    \i 1
       
  3251     \row    \i Hour   \i 0
       
  3252     \row    \i Minute \i 0
       
  3253     \row    \i Second \i 0
       
  3254     \endtable
       
  3255 
       
  3256     For example:
       
  3257 
       
  3258     \snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 14
       
  3259 
       
  3260     \sa QDate::fromString() QTime::fromString() QDate::toString()
       
  3261     QDateTime::toString() QTime::toString()
       
  3262 */
       
  3263 
       
  3264 QDateTime QDateTime::fromString(const QString &string, const QString &format)
       
  3265 {
       
  3266 #ifndef QT_BOOTSTRAPPED
       
  3267     QTime time;
       
  3268     QDate date;
       
  3269 
       
  3270     QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString);
       
  3271     if (dt.parseFormat(format) && dt.fromString(string, &date, &time))
       
  3272         return QDateTime(date, time);
       
  3273 #else
       
  3274     Q_UNUSED(string);
       
  3275     Q_UNUSED(format);
       
  3276 #endif
       
  3277     return QDateTime(QDate(), QTime(-1, -1, -1));
       
  3278 }
       
  3279 
       
  3280 #endif // QT_NO_DATESTRING
       
  3281 /*!
       
  3282     \fn QDateTime QDateTime::toLocalTime() const
       
  3283 
       
  3284     Returns a datetime containing the date and time information in
       
  3285     this datetime, but specified using the Qt::LocalTime definition.
       
  3286 
       
  3287     \sa toTimeSpec()
       
  3288 */
       
  3289 
       
  3290 /*!
       
  3291     \fn QDateTime QDateTime::toUTC() const
       
  3292 
       
  3293     Returns a datetime containing the date and time information in
       
  3294     this datetime, but specified using the Qt::UTC definition.
       
  3295 
       
  3296     \sa toTimeSpec()
       
  3297 */
       
  3298 
       
  3299 /*! \internal
       
  3300  */
       
  3301 void QDateTime::detach()
       
  3302 {
       
  3303     d.detach();
       
  3304 }
       
  3305 
       
  3306 /*****************************************************************************
       
  3307   Date/time stream functions
       
  3308  *****************************************************************************/
       
  3309 
       
  3310 #ifndef QT_NO_DATASTREAM
       
  3311 /*!
       
  3312     \relates QDate
       
  3313 
       
  3314     Writes the \a date to stream \a out.
       
  3315 
       
  3316     \sa {Format of the QDataStream operators}
       
  3317 */
       
  3318 
       
  3319 QDataStream &operator<<(QDataStream &out, const QDate &date)
       
  3320 {
       
  3321     return out << (quint32)(date.jd);
       
  3322 }
       
  3323 
       
  3324 /*!
       
  3325     \relates QDate
       
  3326 
       
  3327     Reads a date from stream \a in into the \a date.
       
  3328 
       
  3329     \sa {Format of the QDataStream operators}
       
  3330 */
       
  3331 
       
  3332 QDataStream &operator>>(QDataStream &in, QDate &date)
       
  3333 {
       
  3334     quint32 jd;
       
  3335     in >> jd;
       
  3336     date.jd = jd;
       
  3337     return in;
       
  3338 }
       
  3339 
       
  3340 /*!
       
  3341     \relates QTime
       
  3342 
       
  3343     Writes \a time to stream \a out.
       
  3344 
       
  3345     \sa {Format of the QDataStream operators}
       
  3346 */
       
  3347 
       
  3348 QDataStream &operator<<(QDataStream &out, const QTime &time)
       
  3349 {
       
  3350     return out << quint32(time.mds);
       
  3351 }
       
  3352 
       
  3353 /*!
       
  3354     \relates QTime
       
  3355 
       
  3356     Reads a time from stream \a in into the given \a time.
       
  3357 
       
  3358     \sa {Format of the QDataStream operators}
       
  3359 */
       
  3360 
       
  3361 QDataStream &operator>>(QDataStream &in, QTime &time)
       
  3362 {
       
  3363     quint32 ds;
       
  3364     in >> ds;
       
  3365     time.mds = int(ds);
       
  3366     return in;
       
  3367 }
       
  3368 
       
  3369 /*!
       
  3370     \relates QDateTime
       
  3371 
       
  3372     Writes \a dateTime to the \a out stream.
       
  3373 
       
  3374     \sa {Format of the QDataStream operators}
       
  3375 */
       
  3376 QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime)
       
  3377 {
       
  3378     out << dateTime.d->date << dateTime.d->time;
       
  3379     if (out.version() >= 7)
       
  3380         out << (qint8)dateTime.d->spec;
       
  3381     return out;
       
  3382 }
       
  3383 
       
  3384 /*!
       
  3385     \relates QDateTime
       
  3386 
       
  3387     Reads a datetime from the stream \a in into \a dateTime.
       
  3388 
       
  3389     \sa {Format of the QDataStream operators}
       
  3390 */
       
  3391 
       
  3392 QDataStream &operator>>(QDataStream &in, QDateTime &dateTime)
       
  3393 {
       
  3394     dateTime.detach();
       
  3395 
       
  3396     qint8 ts = (qint8)QDateTimePrivate::LocalUnknown;
       
  3397     in >> dateTime.d->date >> dateTime.d->time;
       
  3398     if (in.version() >= 7)
       
  3399         in >> ts;
       
  3400     dateTime.d->spec = (QDateTimePrivate::Spec)ts;
       
  3401     return in;
       
  3402 }
       
  3403 #endif // QT_NO_DATASTREAM
       
  3404 
       
  3405 
       
  3406 /*!
       
  3407     \fn QString QDate::monthName(int month)
       
  3408 
       
  3409     Use shortMonthName() instead.
       
  3410 */
       
  3411 
       
  3412 /*!
       
  3413     \fn QString QDate::dayName(int weekday)
       
  3414 
       
  3415     Use shortDayName() instead.
       
  3416 */
       
  3417 
       
  3418 /*!
       
  3419     \fn bool QDate::leapYear(int year)
       
  3420 
       
  3421     Use isLeapYear() instead.
       
  3422 */
       
  3423 
       
  3424 /*!
       
  3425     \fn QDate QDate::currentDate(Qt::TimeSpec spec)
       
  3426 
       
  3427     If \a spec is Qt::LocalTime, use the currentDate() overload that
       
  3428     takes no parameters instead; otherwise, use
       
  3429     QDateTime::currentDateTime().
       
  3430 
       
  3431     \oldcode
       
  3432         QDate localDate = QDate::currentDate(Qt::LocalTime);
       
  3433         QDate utcDate = QDate::currentDate(Qt::UTC);
       
  3434     \newcode
       
  3435         QDate localDate = QDate::currentDate();
       
  3436         QDate utcDate = QDateTime::currentDateTime().toUTC().date();
       
  3437     \endcode
       
  3438 
       
  3439     \sa QDateTime::toUTC()
       
  3440 */
       
  3441 
       
  3442 /*!
       
  3443     \fn QTime QTime::currentTime(Qt::TimeSpec specification)
       
  3444 
       
  3445     Returns the current time for the given \a specification.
       
  3446 
       
  3447     To replace uses of this function where the \a specification is Qt::LocalTime,
       
  3448     use the currentDate() overload that takes no parameters instead; otherwise,
       
  3449     use QDateTime::currentDateTime() and convert the result to a UTC measurement.
       
  3450 
       
  3451     \oldcode
       
  3452         QTime localTime = QTime::currentTime(Qt::LocalTime);
       
  3453         QTime utcTime = QTime::currentTime(Qt::UTC);
       
  3454     \newcode
       
  3455         QTime localTime = QTime::currentTime();
       
  3456         QTime utcTime = QTimeTime::currentDateTime().toUTC().time();
       
  3457     \endcode
       
  3458 
       
  3459     \sa QDateTime::toUTC()
       
  3460 */
       
  3461 
       
  3462 /*!
       
  3463     \fn void QDateTime::setTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec)
       
  3464 
       
  3465     Use the single-argument overload of setTime_t() instead.
       
  3466 */
       
  3467 
       
  3468 /*!
       
  3469     \fn QDateTime QDateTime::currentDateTime(Qt::TimeSpec spec)
       
  3470 
       
  3471     Use the currentDateTime() overload that takes no parameters
       
  3472     instead.
       
  3473 */
       
  3474 
       
  3475 // checks if there is an unqoted 'AP' or 'ap' in the string
       
  3476 static bool hasUnquotedAP(const QString &f)
       
  3477 {
       
  3478     const QLatin1Char quote('\'');
       
  3479     bool inquote = false;
       
  3480     const int max = f.size();
       
  3481     for (int i=0; i<max; ++i) {
       
  3482         if (f.at(i) == quote) {
       
  3483             inquote = !inquote;
       
  3484         } else if (!inquote && f.at(i).toUpper() == QLatin1Char('A')) {
       
  3485             return true;
       
  3486         }
       
  3487     }
       
  3488     return false;
       
  3489 }
       
  3490 
       
  3491 #ifndef QT_NO_DATESTRING
       
  3492 /*****************************************************************************
       
  3493   Some static function used by QDate, QTime and QDateTime
       
  3494 *****************************************************************************/
       
  3495 
       
  3496 // Replaces tokens by their value. See QDateTime::toString() for a list of valid tokens
       
  3497 static QString getFmtString(const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = false)
       
  3498 {
       
  3499     if (f.isEmpty())
       
  3500         return QString();
       
  3501 
       
  3502     QString buf = f;
       
  3503     int removed = 0;
       
  3504 
       
  3505     if (dt) {
       
  3506         if (f.startsWith(QLatin1String("hh")) || f.startsWith(QLatin1String("HH"))) {
       
  3507             const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
       
  3508             if (hour12 && dt->hour() > 12)
       
  3509                 buf = QString::number(dt->hour() - 12).rightJustified(2, QLatin1Char('0'), true);
       
  3510             else if (hour12 && dt->hour() == 0)
       
  3511                 buf = QLatin1String("12");
       
  3512             else
       
  3513                 buf = QString::number(dt->hour()).rightJustified(2, QLatin1Char('0'), true);
       
  3514             removed = 2;
       
  3515         } else if (f.at(0) == QLatin1Char('h') || f.at(0) == QLatin1Char('H')) {
       
  3516             const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
       
  3517             if (hour12 && dt->hour() > 12)
       
  3518                 buf = QString::number(dt->hour() - 12);
       
  3519             else if (hour12 && dt->hour() == 0)
       
  3520                 buf = QLatin1String("12");
       
  3521             else
       
  3522                 buf = QString::number(dt->hour());
       
  3523             removed = 1;
       
  3524         } else if (f.startsWith(QLatin1String("mm"))) {
       
  3525             buf = QString::number(dt->minute()).rightJustified(2, QLatin1Char('0'), true);
       
  3526             removed = 2;
       
  3527         } else if (f.at(0) == (QLatin1Char('m'))) {
       
  3528             buf = QString::number(dt->minute());
       
  3529             removed = 1;
       
  3530         } else if (f.startsWith(QLatin1String("ss"))) {
       
  3531             buf = QString::number(dt->second()).rightJustified(2, QLatin1Char('0'), true);
       
  3532             removed = 2;
       
  3533         } else if (f.at(0) == QLatin1Char('s')) {
       
  3534             buf = QString::number(dt->second());
       
  3535         } else if (f.startsWith(QLatin1String("zzz"))) {
       
  3536             buf = QString::number(dt->msec()).rightJustified(3, QLatin1Char('0'), true);
       
  3537             removed = 3;
       
  3538         } else if (f.at(0) == QLatin1Char('z')) {
       
  3539             buf = QString::number(dt->msec());
       
  3540             removed = 1;
       
  3541         } else if (f.at(0).toUpper() == QLatin1Char('A')) {
       
  3542             const bool upper = f.at(0) == QLatin1Char('A');
       
  3543             buf = dt->hour() < 12 ? QLatin1String("am") : QLatin1String("pm");
       
  3544             if (upper)
       
  3545                 buf = buf.toUpper();
       
  3546             if (f.size() > 1 && f.at(1).toUpper() == QLatin1Char('P') &&
       
  3547                 f.at(0).isUpper() == f.at(1).isUpper()) {
       
  3548                 removed = 2;
       
  3549             } else {
       
  3550                 removed = 1;
       
  3551             }
       
  3552         }
       
  3553     }
       
  3554 
       
  3555     if (dd) {
       
  3556         if (f.startsWith(QLatin1String("dddd"))) {
       
  3557             buf = dd->longDayName(dd->dayOfWeek());
       
  3558             removed = 4;
       
  3559         } else if (f.startsWith(QLatin1String("ddd"))) {
       
  3560             buf = dd->shortDayName(dd->dayOfWeek());
       
  3561             removed = 3;
       
  3562         } else if (f.startsWith(QLatin1String("dd"))) {
       
  3563             buf = QString::number(dd->day()).rightJustified(2, QLatin1Char('0'), true);
       
  3564             removed = 2;
       
  3565         } else if (f.at(0) == QLatin1Char('d')) {
       
  3566             buf = QString::number(dd->day());
       
  3567             removed = 1;
       
  3568         } else if (f.startsWith(QLatin1String("MMMM"))) {
       
  3569             buf = dd->longMonthName(dd->month());
       
  3570             removed = 4;
       
  3571         } else if (f.startsWith(QLatin1String("MMM"))) {
       
  3572             buf = dd->shortMonthName(dd->month());
       
  3573             removed = 3;
       
  3574         } else if (f.startsWith(QLatin1String("MM"))) {
       
  3575             buf = QString::number(dd->month()).rightJustified(2, QLatin1Char('0'), true);
       
  3576             removed = 2;
       
  3577         } else if (f.at(0) == QLatin1Char('M')) {
       
  3578             buf = QString::number(dd->month());
       
  3579             removed = 1;
       
  3580         } else if (f.startsWith(QLatin1String("yyyy"))) {
       
  3581             const int year = dd->year();
       
  3582             buf = QString::number(qAbs(year)).rightJustified(4, QLatin1Char('0'));
       
  3583             if(year > 0)
       
  3584                 removed = 4;
       
  3585             else
       
  3586             {
       
  3587                 buf.prepend(QLatin1Char('-'));
       
  3588                 removed = 5;
       
  3589             }
       
  3590 
       
  3591         } else if (f.startsWith(QLatin1String("yy"))) {
       
  3592             buf = QString::number(dd->year()).right(2).rightJustified(2, QLatin1Char('0'));
       
  3593             removed = 2;
       
  3594         }
       
  3595     }
       
  3596     if (removed == 0 || removed >= f.size()) {
       
  3597         return buf;
       
  3598     }
       
  3599 
       
  3600     return buf + getFmtString(f.mid(removed), dt, dd, am_pm);
       
  3601 }
       
  3602 
       
  3603 // Parses the format string and uses getFmtString to get the values for the tokens. Ret
       
  3604 static QString fmtDateTime(const QString& f, const QTime* dt, const QDate* dd)
       
  3605 {
       
  3606     const QLatin1Char quote('\'');
       
  3607     if (f.isEmpty())
       
  3608         return QString();
       
  3609     if (dt && !dt->isValid())
       
  3610         return QString();
       
  3611     if (dd && !dd->isValid())
       
  3612         return QString();
       
  3613 
       
  3614     const bool ap = hasUnquotedAP(f);
       
  3615 
       
  3616     QString buf;
       
  3617     QString frm;
       
  3618     QChar status(QLatin1Char('0'));
       
  3619 
       
  3620     for (int i = 0; i < (int)f.length(); ++i) {
       
  3621         if (f.at(i) == quote) {
       
  3622             if (status == quote) {
       
  3623                 if (i > 0 && f.at(i - 1) == quote)
       
  3624                     buf += QLatin1Char('\'');
       
  3625                 status = QLatin1Char('0');
       
  3626             } else {
       
  3627                 if (!frm.isEmpty()) {
       
  3628                     buf += getFmtString(frm, dt, dd, ap);
       
  3629                     frm.clear();
       
  3630                 }
       
  3631                 status = quote;
       
  3632             }
       
  3633         } else if (status == quote) {
       
  3634             buf += f.at(i);
       
  3635         } else if (f.at(i) == status) {
       
  3636             if ((ap) && ((f.at(i) == QLatin1Char('P')) || (f.at(i) == QLatin1Char('p'))))
       
  3637                 status = QLatin1Char('0');
       
  3638             frm += f.at(i);
       
  3639         } else {
       
  3640             buf += getFmtString(frm, dt, dd, ap);
       
  3641             frm.clear();
       
  3642             if ((f.at(i) == QLatin1Char('h')) || (f.at(i) == QLatin1Char('m'))
       
  3643                 || (f.at(i) == QLatin1Char('H'))
       
  3644                 || (f.at(i) == QLatin1Char('s')) || (f.at(i) == QLatin1Char('z'))) {
       
  3645                 status = f.at(i);
       
  3646                 frm += f.at(i);
       
  3647             } else if ((f.at(i) == QLatin1Char('d')) || (f.at(i) == QLatin1Char('M')) || (f.at(i) == QLatin1Char('y'))) {
       
  3648                 status = f.at(i);
       
  3649                 frm += f.at(i);
       
  3650             } else if ((ap) && (f.at(i) == QLatin1Char('A'))) {
       
  3651                 status = QLatin1Char('P');
       
  3652                 frm += f.at(i);
       
  3653             } else  if((ap) && (f.at(i) == QLatin1Char('a'))) {
       
  3654                 status = QLatin1Char('p');
       
  3655                 frm += f.at(i);
       
  3656             } else {
       
  3657                 buf += f.at(i);
       
  3658                 status = QLatin1Char('0');
       
  3659             }
       
  3660         }
       
  3661     }
       
  3662 
       
  3663     buf += getFmtString(frm, dt, dd, ap);
       
  3664 
       
  3665     return buf;
       
  3666 }
       
  3667 #endif // QT_NO_DATESTRING
       
  3668 
       
  3669 #ifdef Q_OS_WIN
       
  3670 static const int LowerYear = 1980;
       
  3671 #else
       
  3672 static const int LowerYear = 1970;
       
  3673 #endif
       
  3674 static const int UpperYear = 2037;
       
  3675 
       
  3676 static QDate adjustDate(QDate date)
       
  3677 {
       
  3678     QDate lowerLimit(LowerYear, 1, 2);
       
  3679     QDate upperLimit(UpperYear, 12, 30);
       
  3680 
       
  3681     if (date > lowerLimit && date < upperLimit)
       
  3682         return date;
       
  3683 
       
  3684     int month = date.month();
       
  3685     int day = date.day();
       
  3686 
       
  3687     // neither 1970 nor 2037 are leap years, so make sure date isn't Feb 29
       
  3688     if (month == 2 && day == 29)
       
  3689         --day;
       
  3690 
       
  3691     if (date < lowerLimit)
       
  3692         date.setDate(LowerYear, month, day);
       
  3693     else
       
  3694         date.setDate(UpperYear, month, day);
       
  3695 
       
  3696     return date;
       
  3697 }
       
  3698 
       
  3699 static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time)
       
  3700 {
       
  3701     QDate fakeDate = adjustDate(date);
       
  3702 
       
  3703     time_t secsSince1Jan1970UTC = toTime_tHelper(fakeDate, time);
       
  3704     tm *brokenDown = 0;
       
  3705 
       
  3706 #if defined(Q_OS_WINCE)
       
  3707     tm res;
       
  3708     FILETIME utcTime = time_tToFt(secsSince1Jan1970UTC);
       
  3709     FILETIME resultTime;
       
  3710     FileTimeToLocalFileTime(&utcTime , &resultTime);
       
  3711     SYSTEMTIME sysTime;
       
  3712     FileTimeToSystemTime(&resultTime , &sysTime);
       
  3713 
       
  3714     res.tm_sec = sysTime.wSecond;
       
  3715     res.tm_min = sysTime.wMinute;
       
  3716     res.tm_hour = sysTime.wHour;
       
  3717     res.tm_mday = sysTime.wDay;
       
  3718     res.tm_mon = sysTime.wMonth - 1;
       
  3719     res.tm_year = sysTime.wYear - 1900;
       
  3720     brokenDown = &res;
       
  3721 #elif defined(Q_OS_SYMBIAN)
       
  3722     // months and days are zero index based
       
  3723     _LIT(KUnixEpoch, "19700000:000000.000000");
       
  3724     TTimeIntervalSeconds utcOffset = User::UTCOffset();
       
  3725     TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC);
       
  3726     TTime epochTTime;
       
  3727     TInt err = epochTTime.Set(KUnixEpoch);
       
  3728     if(err == KErrNone) {
       
  3729         TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC;
       
  3730         utcTTime = utcTTime + utcOffset;
       
  3731         TDateTime utcDateTime = utcTTime.DateTime();
       
  3732         tm res;
       
  3733         res.tm_sec = utcDateTime.Second();
       
  3734         res.tm_min = utcDateTime.Minute();
       
  3735         res.tm_hour = utcDateTime.Hour();
       
  3736         res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct
       
  3737         res.tm_mon = utcDateTime.Month();
       
  3738         res.tm_year = utcDateTime.Year() - 1900;
       
  3739         res.tm_isdst = 0;
       
  3740         brokenDown = &res;
       
  3741     }
       
  3742 #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
       
  3743     // use the reentrant version of localtime() where available
       
  3744     tzset();
       
  3745     tm res;
       
  3746     brokenDown = localtime_r(&secsSince1Jan1970UTC, &res);
       
  3747 #elif defined(_MSC_VER) && _MSC_VER >= 1400
       
  3748     tm res;
       
  3749     if (!_localtime64_s(&res, &secsSince1Jan1970UTC))
       
  3750         brokenDown = &res;
       
  3751 #else
       
  3752     brokenDown = localtime(&secsSince1Jan1970UTC);
       
  3753 #endif
       
  3754     if (!brokenDown) {
       
  3755         date = QDate(1970, 1, 1);
       
  3756         time = QTime();
       
  3757         return QDateTimePrivate::LocalUnknown;
       
  3758     } else {
       
  3759         int deltaDays = fakeDate.daysTo(date);
       
  3760         date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
       
  3761         time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());
       
  3762         date = date.addDays(deltaDays);
       
  3763         if (brokenDown->tm_isdst > 0)
       
  3764             return QDateTimePrivate::LocalDST;
       
  3765         else if (brokenDown->tm_isdst < 0)
       
  3766             return QDateTimePrivate::LocalUnknown;
       
  3767         else
       
  3768             return QDateTimePrivate::LocalStandard;
       
  3769     }
       
  3770 }
       
  3771 
       
  3772 static void localToUtc(QDate &date, QTime &time, int isdst)
       
  3773 {
       
  3774     if (!date.isValid())
       
  3775         return;
       
  3776 
       
  3777     QDate fakeDate = adjustDate(date);
       
  3778 
       
  3779     tm localTM;
       
  3780     localTM.tm_sec = time.second();
       
  3781     localTM.tm_min = time.minute();
       
  3782     localTM.tm_hour = time.hour();
       
  3783     localTM.tm_mday = fakeDate.day();
       
  3784     localTM.tm_mon = fakeDate.month() - 1;
       
  3785     localTM.tm_year = fakeDate.year() - 1900;
       
  3786     localTM.tm_isdst = (int)isdst;
       
  3787 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
       
  3788     time_t secsSince1Jan1970UTC = toTime_tHelper(fakeDate, time);
       
  3789 #else
       
  3790 #if defined(Q_OS_WIN)
       
  3791     _tzset();
       
  3792 #endif
       
  3793     time_t secsSince1Jan1970UTC = mktime(&localTM);
       
  3794 #endif
       
  3795     tm *brokenDown = 0;
       
  3796 #if defined(Q_OS_WINCE)
       
  3797     tm res;
       
  3798     FILETIME localTime = time_tToFt(secsSince1Jan1970UTC);
       
  3799     SYSTEMTIME sysTime;
       
  3800     FileTimeToSystemTime(&localTime, &sysTime);
       
  3801     FILETIME resultTime;
       
  3802     LocalFileTimeToFileTime(&localTime , &resultTime);
       
  3803     FileTimeToSystemTime(&resultTime , &sysTime);
       
  3804     res.tm_sec = sysTime.wSecond;
       
  3805     res.tm_min = sysTime.wMinute;
       
  3806     res.tm_hour = sysTime.wHour;
       
  3807     res.tm_mday = sysTime.wDay;
       
  3808     res.tm_mon = sysTime.wMonth - 1;
       
  3809     res.tm_year = sysTime.wYear - 1900;
       
  3810     res.tm_isdst = (int)isdst;
       
  3811     brokenDown = &res;
       
  3812 #elif defined(Q_OS_SYMBIAN)
       
  3813     // months and days are zero index based
       
  3814     _LIT(KUnixEpoch, "19700000:000000.000000");
       
  3815     TTimeIntervalSeconds utcOffset = TTimeIntervalSeconds(0 - User::UTCOffset().Int());
       
  3816     TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC);
       
  3817     TTime epochTTime;
       
  3818     TInt err = epochTTime.Set(KUnixEpoch);
       
  3819     if(err == KErrNone) {
       
  3820         TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC;
       
  3821         utcTTime = utcTTime + utcOffset;
       
  3822         TDateTime utcDateTime = utcTTime.DateTime();
       
  3823         tm res;
       
  3824         res.tm_sec = utcDateTime.Second();
       
  3825         res.tm_min = utcDateTime.Minute();
       
  3826         res.tm_hour = utcDateTime.Hour();
       
  3827         res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct
       
  3828         res.tm_mon = utcDateTime.Month();
       
  3829         res.tm_year = utcDateTime.Year() - 1900;
       
  3830         res.tm_isdst = (int)isdst;
       
  3831         brokenDown = &res;
       
  3832     }
       
  3833 #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
       
  3834     // use the reentrant version of gmtime() where available
       
  3835     tm res;
       
  3836     brokenDown = gmtime_r(&secsSince1Jan1970UTC, &res);
       
  3837 #elif defined(_MSC_VER) && _MSC_VER >= 1400
       
  3838     tm res;
       
  3839     if (!_gmtime64_s(&res, &secsSince1Jan1970UTC))
       
  3840         brokenDown = &res;
       
  3841 #else
       
  3842     brokenDown = gmtime(&secsSince1Jan1970UTC);
       
  3843 #endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
       
  3844     if (!brokenDown) {
       
  3845         date = QDate(1970, 1, 1);
       
  3846         time = QTime();
       
  3847     } else {
       
  3848         int deltaDays = fakeDate.daysTo(date);
       
  3849         date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
       
  3850         time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());
       
  3851         date = date.addDays(deltaDays);
       
  3852     }
       
  3853 }
       
  3854 
       
  3855 QDateTimePrivate::Spec QDateTimePrivate::getLocal(QDate &outDate, QTime &outTime) const
       
  3856 {
       
  3857     outDate = date;
       
  3858     outTime = time;
       
  3859     if (spec == QDateTimePrivate::UTC)
       
  3860         return utcToLocal(outDate, outTime);
       
  3861     return spec;
       
  3862 }
       
  3863 
       
  3864 void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const
       
  3865 {
       
  3866     outDate = date;
       
  3867     outTime = time;
       
  3868     const bool isOffset = spec == QDateTimePrivate::OffsetFromUTC;
       
  3869 
       
  3870     if (spec != QDateTimePrivate::UTC && !isOffset)
       
  3871         localToUtc(outDate, outTime, (int)spec);
       
  3872 
       
  3873     if (isOffset)
       
  3874         addMSecs(outDate, outTime, -(qint64(utcOffset) * 1000));
       
  3875 }
       
  3876 
       
  3877 #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
       
  3878 QDebug operator<<(QDebug dbg, const QDate &date)
       
  3879 {
       
  3880     dbg.nospace() << "QDate(" << date.toString() << ')';
       
  3881     return dbg.space();
       
  3882 }
       
  3883 
       
  3884 QDebug operator<<(QDebug dbg, const QTime &time)
       
  3885 {
       
  3886     dbg.nospace() << "QTime(" << time.toString() << ')';
       
  3887     return dbg.space();
       
  3888 }
       
  3889 
       
  3890 QDebug operator<<(QDebug dbg, const QDateTime &date)
       
  3891 {
       
  3892     dbg.nospace() << "QDateTime(" << date.toString() << ')';
       
  3893     return dbg.space();
       
  3894 }
       
  3895 #endif
       
  3896 
       
  3897 #ifndef QT_BOOTSTRAPPED
       
  3898 
       
  3899 /*!
       
  3900   \internal
       
  3901   Gets the digit from a datetime. E.g.
       
  3902 
       
  3903   QDateTime var(QDate(2004, 02, 02));
       
  3904   int digit = getDigit(var, Year);
       
  3905   // digit = 2004
       
  3906 */
       
  3907 
       
  3908 int QDateTimeParser::getDigit(const QDateTime &t, int index) const
       
  3909 {
       
  3910     if (index < 0 || index >= sectionNodes.size()) {
       
  3911 #ifndef QT_NO_DATESTRING
       
  3912         qWarning("QDateTimeParser::getDigit() Internal error (%s %d)",
       
  3913                  qPrintable(t.toString()), index);
       
  3914 #else
       
  3915         qWarning("QDateTimeParser::getDigit() Internal error (%d)", index);
       
  3916 #endif
       
  3917         return -1;
       
  3918     }
       
  3919     const SectionNode &node = sectionNodes.at(index);
       
  3920     switch (node.type) {
       
  3921     case Hour24Section: case Hour12Section: return t.time().hour();
       
  3922     case MinuteSection: return t.time().minute();
       
  3923     case SecondSection: return t.time().second();
       
  3924     case MSecSection: return t.time().msec();
       
  3925     case YearSection2Digits:
       
  3926     case YearSection: return t.date().year();
       
  3927     case MonthSection: return t.date().month();
       
  3928     case DaySection: return t.date().day();
       
  3929     case DayOfWeekSection: return t.date().day();
       
  3930     case AmPmSection: return t.time().hour() > 11 ? 1 : 0;
       
  3931 
       
  3932     default: break;
       
  3933     }
       
  3934 
       
  3935 #ifndef QT_NO_DATESTRING
       
  3936     qWarning("QDateTimeParser::getDigit() Internal error 2 (%s %d)",
       
  3937              qPrintable(t.toString()), index);
       
  3938 #else
       
  3939     qWarning("QDateTimeParser::getDigit() Internal error 2 (%d)", index);
       
  3940 #endif
       
  3941     return -1;
       
  3942 }
       
  3943 
       
  3944 /*!
       
  3945   \internal
       
  3946   Sets a digit in a datetime. E.g.
       
  3947 
       
  3948   QDateTime var(QDate(2004, 02, 02));
       
  3949   int digit = getDigit(var, Year);
       
  3950   // digit = 2004
       
  3951   setDigit(&var, Year, 2005);
       
  3952   digit = getDigit(var, Year);
       
  3953   // digit = 2005
       
  3954 */
       
  3955 
       
  3956 bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
       
  3957 {
       
  3958     if (index < 0 || index >= sectionNodes.size()) {
       
  3959 #ifndef QT_NO_DATESTRING
       
  3960         qWarning("QDateTimeParser::setDigit() Internal error (%s %d %d)",
       
  3961                  qPrintable(v.toString()), index, newVal);
       
  3962 #else
       
  3963         qWarning("QDateTimeParser::setDigit() Internal error (%d %d)", index, newVal);
       
  3964 #endif
       
  3965         return false;
       
  3966     }
       
  3967     const SectionNode &node = sectionNodes.at(index);
       
  3968 
       
  3969     int year, month, day, hour, minute, second, msec;
       
  3970     year = v.date().year();
       
  3971     month = v.date().month();
       
  3972     day = v.date().day();
       
  3973     hour = v.time().hour();
       
  3974     minute = v.time().minute();
       
  3975     second = v.time().second();
       
  3976     msec = v.time().msec();
       
  3977 
       
  3978     switch (node.type) {
       
  3979     case Hour24Section: case Hour12Section: hour = newVal; break;
       
  3980     case MinuteSection: minute = newVal; break;
       
  3981     case SecondSection: second = newVal; break;
       
  3982     case MSecSection: msec = newVal; break;
       
  3983     case YearSection2Digits:
       
  3984     case YearSection: year = newVal; break;
       
  3985     case MonthSection: month = newVal; break;
       
  3986     case DaySection:
       
  3987     case DayOfWeekSection:
       
  3988         if (newVal > 31) {
       
  3989             // have to keep legacy behavior. setting the
       
  3990             // date to 32 should return false. Setting it
       
  3991             // to 31 for february should return true
       
  3992             return false;
       
  3993         }
       
  3994         day = newVal;
       
  3995         break;
       
  3996     case AmPmSection: hour = (newVal == 0 ? hour % 12 : (hour % 12) + 12); break;
       
  3997     default:
       
  3998         qWarning("QDateTimeParser::setDigit() Internal error (%s)",
       
  3999                  qPrintable(sectionName(node.type)));
       
  4000         break;
       
  4001     }
       
  4002 
       
  4003     if (!(node.type & (DaySection|DayOfWeekSection))) {
       
  4004         if (day < cachedDay)
       
  4005             day = cachedDay;
       
  4006         const int max = QDate(year, month, 1).daysInMonth();
       
  4007         if (day > max) {
       
  4008             day = max;
       
  4009         }
       
  4010     }
       
  4011     if (QDate::isValid(year, month, day) && QTime::isValid(hour, minute, second, msec)) {
       
  4012         v = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);
       
  4013         return true;
       
  4014     }
       
  4015     return false;
       
  4016 }
       
  4017 
       
  4018 
       
  4019 
       
  4020 /*!
       
  4021   \
       
  4022 
       
  4023   Returns the absolute maximum for a section
       
  4024 */
       
  4025 
       
  4026 int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
       
  4027 {
       
  4028     const SectionNode &sn = sectionNode(s);
       
  4029     switch (sn.type) {
       
  4030     case Hour24Section:
       
  4031     case Hour12Section: return 23; // this is special-cased in
       
  4032                                    // parseSection. We want it to be
       
  4033                                    // 23 for the stepBy case.
       
  4034     case MinuteSection:
       
  4035     case SecondSection: return 59;
       
  4036     case MSecSection: return 999;
       
  4037     case YearSection2Digits:
       
  4038     case YearSection: return 9999; // sectionMaxSize will prevent
       
  4039                                    // people from typing in a larger
       
  4040                                    // number in count == 2 sections.
       
  4041                                    // stepBy() will work on real years anyway
       
  4042     case MonthSection: return 12;
       
  4043     case DaySection:
       
  4044     case DayOfWeekSection: return cur.isValid() ? cur.date().daysInMonth() : 31;
       
  4045     case AmPmSection: return 1;
       
  4046     default: break;
       
  4047     }
       
  4048     qWarning("QDateTimeParser::absoluteMax() Internal error (%s)",
       
  4049              qPrintable(sectionName(sn.type)));
       
  4050     return -1;
       
  4051 }
       
  4052 
       
  4053 /*!
       
  4054   \internal
       
  4055 
       
  4056   Returns the absolute minimum for a section
       
  4057 */
       
  4058 
       
  4059 int QDateTimeParser::absoluteMin(int s) const
       
  4060 {
       
  4061     const SectionNode &sn = sectionNode(s);
       
  4062     switch (sn.type) {
       
  4063     case Hour24Section:
       
  4064     case Hour12Section:
       
  4065     case MinuteSection:
       
  4066     case SecondSection:
       
  4067     case MSecSection:
       
  4068     case YearSection2Digits:
       
  4069     case YearSection: return 0;
       
  4070     case MonthSection:
       
  4071     case DaySection:
       
  4072     case DayOfWeekSection: return 1;
       
  4073     case AmPmSection: return 0;
       
  4074     default: break;
       
  4075     }
       
  4076     qWarning("QDateTimeParser::absoluteMin() Internal error (%s, %0x)",
       
  4077              qPrintable(sectionName(sn.type)), sn.type);
       
  4078     return -1;
       
  4079 }
       
  4080 
       
  4081 /*!
       
  4082   \internal
       
  4083 
       
  4084   Returns the sectionNode for the Section \a s.
       
  4085 */
       
  4086 
       
  4087 const QDateTimeParser::SectionNode &QDateTimeParser::sectionNode(int sectionIndex) const
       
  4088 {
       
  4089     if (sectionIndex < 0) {
       
  4090         switch (sectionIndex) {
       
  4091         case FirstSectionIndex:
       
  4092             return first;
       
  4093         case LastSectionIndex:
       
  4094             return last;
       
  4095         case NoSectionIndex:
       
  4096             return none;
       
  4097         }
       
  4098     } else if (sectionIndex < sectionNodes.size()) {
       
  4099         return sectionNodes.at(sectionIndex);
       
  4100     }
       
  4101 
       
  4102     qWarning("QDateTimeParser::sectionNode() Internal error (%d)",
       
  4103              sectionIndex);
       
  4104     return none;
       
  4105 }
       
  4106 
       
  4107 QDateTimeParser::Section QDateTimeParser::sectionType(int sectionIndex) const
       
  4108 {
       
  4109     return sectionNode(sectionIndex).type;
       
  4110 }
       
  4111 
       
  4112 
       
  4113 /*!
       
  4114   \internal
       
  4115 
       
  4116   Returns the starting position for section \a s.
       
  4117 */
       
  4118 
       
  4119 int QDateTimeParser::sectionPos(int sectionIndex) const
       
  4120 {
       
  4121     return sectionPos(sectionNode(sectionIndex));
       
  4122 }
       
  4123 
       
  4124 int QDateTimeParser::sectionPos(const SectionNode &sn) const
       
  4125 {
       
  4126     switch (sn.type) {
       
  4127     case FirstSection: return 0;
       
  4128     case LastSection: return displayText().size() - 1;
       
  4129     default: break;
       
  4130     }
       
  4131     if (sn.pos == -1) {
       
  4132         qWarning("QDateTimeParser::sectionPos Internal error (%s)", qPrintable(sectionName(sn.type)));
       
  4133         return -1;
       
  4134     }
       
  4135     return sn.pos;
       
  4136 }
       
  4137 
       
  4138 
       
  4139 /*!
       
  4140   \internal helper function for parseFormat. removes quotes that are
       
  4141   not escaped and removes the escaping on those that are escaped
       
  4142 
       
  4143 */
       
  4144 
       
  4145 static QString unquote(const QString &str)
       
  4146 {
       
  4147     const QChar quote(QLatin1Char('\''));
       
  4148     const QChar slash(QLatin1Char('\\'));
       
  4149     const QChar zero(QLatin1Char('0'));
       
  4150     QString ret;
       
  4151     QChar status(zero);
       
  4152     const int max = str.size();
       
  4153     for (int i=0; i<max; ++i) {
       
  4154         if (str.at(i) == quote) {
       
  4155             if (status != quote) {
       
  4156                 status = quote;
       
  4157             } else if (!ret.isEmpty() && str.at(i - 1) == slash) {
       
  4158                 ret[ret.size() - 1] = quote;
       
  4159             } else {
       
  4160                 status = zero;
       
  4161             }
       
  4162         } else {
       
  4163             ret += str.at(i);
       
  4164         }
       
  4165     }
       
  4166     return ret;
       
  4167 }
       
  4168 /*!
       
  4169   \internal
       
  4170 
       
  4171   Parses the format \a newFormat. If successful, returns true and
       
  4172   sets up the format. Else keeps the old format and returns false.
       
  4173 
       
  4174 */
       
  4175 
       
  4176 static inline int countRepeat(const QString &str, int index, int maxCount)
       
  4177 {
       
  4178     int count = 1;
       
  4179     const QChar ch(str.at(index));
       
  4180     const int max = qMin(index + maxCount, str.size());
       
  4181     while (index + count < max && str.at(index + count) == ch) {
       
  4182         ++count;
       
  4183     }
       
  4184     return count;
       
  4185 }
       
  4186 
       
  4187 static inline void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote)
       
  4188 {
       
  4189     QString str(string.mid(from, size));
       
  4190     if (lastQuote >= from)
       
  4191         str = unquote(str);
       
  4192     list->append(str);
       
  4193 }
       
  4194 
       
  4195 
       
  4196 bool QDateTimeParser::parseFormat(const QString &newFormat)
       
  4197 {
       
  4198     const QLatin1Char quote('\'');
       
  4199     const QLatin1Char slash('\\');
       
  4200     const QLatin1Char zero('0');
       
  4201     if (newFormat == displayFormat && !newFormat.isEmpty()) {
       
  4202         return true;
       
  4203     }
       
  4204 
       
  4205     QDTPDEBUGN("parseFormat: %s", newFormat.toLatin1().constData());
       
  4206 
       
  4207     QVector<SectionNode> newSectionNodes;
       
  4208     Sections newDisplay = 0;
       
  4209     QStringList newSeparators;
       
  4210     int i, index = 0;
       
  4211     int add = 0;
       
  4212     QChar status(zero);
       
  4213     const int max = newFormat.size();
       
  4214     int lastQuote = -1;
       
  4215     for (i = 0; i<max; ++i) {
       
  4216         if (newFormat.at(i) == quote) {
       
  4217             lastQuote = i;
       
  4218             ++add;
       
  4219             if (status != quote) {
       
  4220                 status = quote;
       
  4221             } else if (newFormat.at(i - 1) != slash) {
       
  4222                 status = zero;
       
  4223             }
       
  4224         } else if (status != quote) {
       
  4225             const char sect = newFormat.at(i).toLatin1();
       
  4226             switch (sect) {
       
  4227             case 'H':
       
  4228             case 'h':
       
  4229                 if (parserType != QVariant::Date) {
       
  4230                     const Section hour = (sect == 'h') ? Hour12Section : Hour24Section;
       
  4231                     const SectionNode sn = { hour, i - add, countRepeat(newFormat, i, 2) };
       
  4232                     newSectionNodes.append(sn);
       
  4233                     appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
       
  4234                     i += sn.count - 1;
       
  4235                     index = i + 1;
       
  4236                     newDisplay |= hour;
       
  4237                 }
       
  4238                 break;
       
  4239             case 'm':
       
  4240                 if (parserType != QVariant::Date) {
       
  4241                     const SectionNode sn = { MinuteSection, i - add, countRepeat(newFormat, i, 2) };
       
  4242                     newSectionNodes.append(sn);
       
  4243                     appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
       
  4244                     i += sn.count - 1;
       
  4245                     index = i + 1;
       
  4246                     newDisplay |= MinuteSection;
       
  4247                 }
       
  4248                 break;
       
  4249             case 's':
       
  4250                 if (parserType != QVariant::Date) {
       
  4251                     const SectionNode sn = { SecondSection, i - add, countRepeat(newFormat, i, 2) };
       
  4252                     newSectionNodes.append(sn);
       
  4253                     appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
       
  4254                     i += sn.count - 1;
       
  4255                     index = i + 1;
       
  4256                     newDisplay |= SecondSection;
       
  4257                 }
       
  4258                 break;
       
  4259 
       
  4260             case 'z':
       
  4261                 if (parserType != QVariant::Date) {
       
  4262                     const SectionNode sn = { MSecSection, i - add, countRepeat(newFormat, i, 3) < 3 ? 1 : 3 };
       
  4263                     newSectionNodes.append(sn);
       
  4264                     appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
       
  4265                     i += sn.count - 1;
       
  4266                     index = i + 1;
       
  4267                     newDisplay |= MSecSection;
       
  4268                 }
       
  4269                 break;
       
  4270             case 'A':
       
  4271             case 'a':
       
  4272                 if (parserType != QVariant::Date) {
       
  4273                     const bool cap = (sect == 'A');
       
  4274                     const SectionNode sn = { AmPmSection, i - add, (cap ? 1 : 0) };
       
  4275                     newSectionNodes.append(sn);
       
  4276                     appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
       
  4277                     newDisplay |= AmPmSection;
       
  4278                     if (i + 1 < newFormat.size()
       
  4279                         && newFormat.at(i+1) == (cap ? QLatin1Char('P') : QLatin1Char('p'))) {
       
  4280                         ++i;
       
  4281                     }
       
  4282                     index = i + 1;
       
  4283                 }
       
  4284                 break;
       
  4285             case 'y':
       
  4286                 if (parserType != QVariant::Time) {
       
  4287                     const int repeat = countRepeat(newFormat, i, 4);
       
  4288                     if (repeat >= 2) {
       
  4289                         const SectionNode sn = { repeat == 4 ? YearSection : YearSection2Digits,
       
  4290                                                  i - add, repeat == 4 ? 4 : 2 };
       
  4291                         newSectionNodes.append(sn);
       
  4292                         appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
       
  4293                         i += sn.count - 1;
       
  4294                         index = i + 1;
       
  4295                         newDisplay |= sn.type;
       
  4296                     }
       
  4297                 }
       
  4298                 break;
       
  4299             case 'M':
       
  4300                 if (parserType != QVariant::Time) {
       
  4301                     const SectionNode sn = { MonthSection, i - add, countRepeat(newFormat, i, 4) };
       
  4302                     newSectionNodes.append(sn);
       
  4303                     newSeparators.append(unquote(newFormat.mid(index, i - index)));
       
  4304                     i += sn.count - 1;
       
  4305                     index = i + 1;
       
  4306                     newDisplay |= MonthSection;
       
  4307                 }
       
  4308                 break;
       
  4309             case 'd':
       
  4310                 if (parserType != QVariant::Time) {
       
  4311                     const int repeat = countRepeat(newFormat, i, 4);
       
  4312                     const SectionNode sn = { repeat >= 3 ? DayOfWeekSection : DaySection, i - add, repeat };
       
  4313                     newSectionNodes.append(sn);
       
  4314                     appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
       
  4315                     i += sn.count - 1;
       
  4316                     index = i + 1;
       
  4317                     newDisplay |= sn.type;
       
  4318                 }
       
  4319                 break;
       
  4320 
       
  4321             default:
       
  4322                 break;
       
  4323             }
       
  4324         }
       
  4325     }
       
  4326     if (newSectionNodes.isEmpty() && context == DateTimeEdit) {
       
  4327         return false;
       
  4328     }
       
  4329 
       
  4330     if ((newDisplay & (AmPmSection|Hour12Section)) == Hour12Section) {
       
  4331         const int max = newSectionNodes.size();
       
  4332         for (int i=0; i<max; ++i) {
       
  4333             SectionNode &node = newSectionNodes[i];
       
  4334             if (node.type == Hour12Section)
       
  4335                 node.type = Hour24Section;
       
  4336         }
       
  4337     }
       
  4338 
       
  4339     if (index < newFormat.size()) {
       
  4340         appendSeparator(&newSeparators, newFormat, index, index - max, lastQuote);
       
  4341     } else {
       
  4342         newSeparators.append(QString());
       
  4343     }
       
  4344 
       
  4345     displayFormat = newFormat;
       
  4346     separators = newSeparators;
       
  4347     sectionNodes = newSectionNodes;
       
  4348     display = newDisplay;
       
  4349     last.pos = -1;
       
  4350 
       
  4351 //     for (int i=0; i<sectionNodes.size(); ++i) {
       
  4352 //         QDTPDEBUG << sectionName(sectionNodes.at(i).type) << sectionNodes.at(i).count;
       
  4353 //     }
       
  4354 
       
  4355     QDTPDEBUG << newFormat << displayFormat;
       
  4356     QDTPDEBUGN("separators:\n'%s'", separators.join(QLatin1String("\n")).toLatin1().constData());
       
  4357 
       
  4358     return true;
       
  4359 }
       
  4360 
       
  4361 /*!
       
  4362   \internal
       
  4363 
       
  4364   Returns the size of section \a s.
       
  4365 */
       
  4366 
       
  4367 int QDateTimeParser::sectionSize(int sectionIndex) const
       
  4368 {
       
  4369     if (sectionIndex < 0)
       
  4370         return 0;
       
  4371 
       
  4372     if (sectionIndex >= sectionNodes.size()) {
       
  4373         qWarning("QDateTimeParser::sectionSize Internal error (%d)", sectionIndex);
       
  4374         return -1;
       
  4375     }
       
  4376     if (sectionIndex == sectionNodes.size() - 1) {
       
  4377         return displayText().size() - sectionPos(sectionIndex) - separators.last().size();
       
  4378     } else {
       
  4379         return sectionPos(sectionIndex + 1) - sectionPos(sectionIndex)
       
  4380             - separators.at(sectionIndex + 1).size();
       
  4381     }
       
  4382 }
       
  4383 
       
  4384 
       
  4385 int QDateTimeParser::sectionMaxSize(Section s, int count) const
       
  4386 {
       
  4387 #ifndef QT_NO_TEXTDATE
       
  4388     int mcount = 12;
       
  4389 #endif
       
  4390 
       
  4391     switch (s) {
       
  4392     case FirstSection:
       
  4393     case NoSection:
       
  4394     case LastSection: return 0;
       
  4395 
       
  4396     case AmPmSection: {
       
  4397         const int lowerMax = qMin(getAmPmText(AmText, LowerCase).size(),
       
  4398                                   getAmPmText(PmText, LowerCase).size());
       
  4399         const int upperMax = qMin(getAmPmText(AmText, UpperCase).size(),
       
  4400                                   getAmPmText(PmText, UpperCase).size());
       
  4401         return qMin(4, qMin(lowerMax, upperMax));
       
  4402     }
       
  4403 
       
  4404     case Hour24Section:
       
  4405     case Hour12Section:
       
  4406     case MinuteSection:
       
  4407     case SecondSection:
       
  4408     case DaySection: return 2;
       
  4409     case DayOfWeekSection:
       
  4410 #ifdef QT_NO_TEXTDATE
       
  4411         return 2;
       
  4412 #else
       
  4413         mcount = 7;
       
  4414         // fall through
       
  4415 #endif
       
  4416     case MonthSection:
       
  4417         if (count <= 2)
       
  4418             return 2;
       
  4419 
       
  4420 #ifdef QT_NO_TEXTDATE
       
  4421         return 2;
       
  4422 #else
       
  4423         {
       
  4424             int ret = 0;
       
  4425             const QLocale l = locale();
       
  4426             for (int i=1; i<=mcount; ++i) {
       
  4427                 const QString str = (s == MonthSection
       
  4428                                      ? l.monthName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat)
       
  4429                                      : l.dayName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat));
       
  4430                 ret = qMax(str.size(), ret);
       
  4431             }
       
  4432             return ret;
       
  4433         }
       
  4434 #endif
       
  4435     case MSecSection: return 3;
       
  4436     case YearSection: return 4;
       
  4437     case YearSection2Digits: return 2;
       
  4438 
       
  4439     case CalendarPopupSection:
       
  4440     case Internal:
       
  4441     case TimeSectionMask:
       
  4442     case DateSectionMask:
       
  4443         qWarning("QDateTimeParser::sectionMaxSize: Invalid section %s",
       
  4444                  sectionName(s).toLatin1().constData());
       
  4445 
       
  4446     case NoSectionIndex:
       
  4447     case FirstSectionIndex:
       
  4448     case LastSectionIndex:
       
  4449     case CalendarPopupIndex:
       
  4450         // these cases can't happen
       
  4451         break;
       
  4452     }
       
  4453     return -1;
       
  4454 }
       
  4455 
       
  4456 
       
  4457 int QDateTimeParser::sectionMaxSize(int index) const
       
  4458 {
       
  4459     const SectionNode &sn = sectionNode(index);
       
  4460     return sectionMaxSize(sn.type, sn.count);
       
  4461 }
       
  4462 
       
  4463 /*!
       
  4464   \internal
       
  4465 
       
  4466   Returns the text of section \a s. This function operates on the
       
  4467   arg text rather than edit->text().
       
  4468 */
       
  4469 
       
  4470 
       
  4471 QString QDateTimeParser::sectionText(const QString &text, int sectionIndex, int index) const
       
  4472 {
       
  4473     const SectionNode &sn = sectionNode(sectionIndex);
       
  4474     switch (sn.type) {
       
  4475     case NoSectionIndex:
       
  4476     case FirstSectionIndex:
       
  4477     case LastSectionIndex:
       
  4478         return QString();
       
  4479     default: break;
       
  4480     }
       
  4481 
       
  4482     return text.mid(index, sectionSize(sectionIndex));
       
  4483 }
       
  4484 
       
  4485 QString QDateTimeParser::sectionText(int sectionIndex) const
       
  4486 {
       
  4487     const SectionNode &sn = sectionNode(sectionIndex);
       
  4488     switch (sn.type) {
       
  4489     case NoSectionIndex:
       
  4490     case FirstSectionIndex:
       
  4491     case LastSectionIndex:
       
  4492         return QString();
       
  4493     default: break;
       
  4494     }
       
  4495 
       
  4496     return displayText().mid(sn.pos, sectionSize(sectionIndex));
       
  4497 }
       
  4498 
       
  4499 
       
  4500 #ifndef QT_NO_TEXTDATE
       
  4501 /*!
       
  4502   \internal:skipToNextSection
       
  4503 
       
  4504   Parses the part of \a text that corresponds to \a s and returns
       
  4505   the value of that field. Sets *stateptr to the right state if
       
  4506   stateptr != 0.
       
  4507 */
       
  4508 
       
  4509 int QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex,
       
  4510                                   QString &text, int &cursorPosition, int index,
       
  4511                                   State &state, int *usedptr) const
       
  4512 {
       
  4513     state = Invalid;
       
  4514     int num = 0;
       
  4515     const SectionNode &sn = sectionNode(sectionIndex);
       
  4516     if ((sn.type & Internal) == Internal) {
       
  4517         qWarning("QDateTimeParser::parseSection Internal error (%s %d)",
       
  4518                  qPrintable(sectionName(sn.type)), sectionIndex);
       
  4519         return -1;
       
  4520     }
       
  4521 
       
  4522     const int sectionmaxsize = sectionMaxSize(sectionIndex);
       
  4523     QString sectiontext = text.mid(index, sectionmaxsize);
       
  4524     int sectiontextSize = sectiontext.size();
       
  4525 
       
  4526     QDTPDEBUG << "sectionValue for" << sectionName(sn.type)
       
  4527               << "with text" << text << "and st" << sectiontext
       
  4528               << text.mid(index, sectionmaxsize)
       
  4529               << index;
       
  4530 
       
  4531     int used = 0;
       
  4532     switch (sn.type) {
       
  4533     case AmPmSection: {
       
  4534         const int ampm = findAmPm(sectiontext, sectionIndex, &used);
       
  4535         switch (ampm) {
       
  4536         case AM: // sectiontext == AM
       
  4537         case PM: // sectiontext == PM
       
  4538             num = ampm;
       
  4539             state = Acceptable;
       
  4540             break;
       
  4541         case PossibleAM: // sectiontext => AM
       
  4542         case PossiblePM: // sectiontext => PM
       
  4543             num = ampm - 2;
       
  4544             state = Intermediate;
       
  4545             break;
       
  4546         case PossibleBoth: // sectiontext => AM|PM
       
  4547             num = 0;
       
  4548             state = Intermediate;
       
  4549             break;
       
  4550         case Neither:
       
  4551             state = Invalid;
       
  4552             QDTPDEBUG << "invalid because findAmPm(" << sectiontext << ") returned -1";
       
  4553             break;
       
  4554         default:
       
  4555             QDTPDEBUGN("This should never happen (findAmPm returned %d)", ampm);
       
  4556             break;
       
  4557         }
       
  4558         if (state != Invalid) {
       
  4559             QString str = text;
       
  4560             text.replace(index, used, sectiontext.left(used));
       
  4561         }
       
  4562         break; }
       
  4563     case MonthSection:
       
  4564     case DayOfWeekSection:
       
  4565         if (sn.count >= 3) {
       
  4566             if (sn.type == MonthSection) {
       
  4567                 int min = 1;
       
  4568                 const QDate minDate = getMinimum().date();
       
  4569                 if (currentValue.date().year() == minDate.year()) {
       
  4570                     min = minDate.month();
       
  4571                 }
       
  4572                 num = findMonth(sectiontext.toLower(), min, sectionIndex, &sectiontext, &used);
       
  4573             } else {
       
  4574                 num = findDay(sectiontext.toLower(), 1, sectionIndex, &sectiontext, &used);
       
  4575             }
       
  4576 
       
  4577             if (num != -1) {
       
  4578                 state = (used == sectiontext.size() ? Acceptable : Intermediate);
       
  4579                 QString str = text;
       
  4580                 text.replace(index, used, sectiontext.left(used));
       
  4581             } else {
       
  4582                 state = Intermediate;
       
  4583             }
       
  4584             break; }
       
  4585         // fall through
       
  4586     case DaySection:
       
  4587     case YearSection:
       
  4588     case YearSection2Digits:
       
  4589     case Hour12Section:
       
  4590     case Hour24Section:
       
  4591     case MinuteSection:
       
  4592     case SecondSection:
       
  4593     case MSecSection: {
       
  4594         if (sectiontextSize == 0) {
       
  4595             num = 0;
       
  4596             used = 0;
       
  4597             state = Intermediate;
       
  4598         } else {
       
  4599             const int absMax = absoluteMax(sectionIndex);
       
  4600             QLocale loc;
       
  4601             bool ok = true;
       
  4602             int last = -1;
       
  4603             used = -1;
       
  4604 
       
  4605             QString digitsStr(sectiontext);
       
  4606             for (int i = 0; i < sectiontextSize; ++i) {
       
  4607                 if (digitsStr.at(i).isSpace()) {
       
  4608                     sectiontextSize = i;
       
  4609                     break;
       
  4610                 }
       
  4611             }
       
  4612 
       
  4613             const int max = qMin(sectionmaxsize, sectiontextSize);
       
  4614             for (int digits = max; digits >= 1; --digits) {
       
  4615                 digitsStr.truncate(digits);
       
  4616                 int tmp = (int)loc.toUInt(digitsStr, &ok, 10);
       
  4617                 if (ok && sn.type == Hour12Section) {
       
  4618                     if (tmp > 12) {
       
  4619                         tmp = -1;
       
  4620                         ok = false;
       
  4621                     } else if (tmp == 12) {
       
  4622                         tmp = 0;
       
  4623                     }
       
  4624                 }
       
  4625                 if (ok && tmp <= absMax) {
       
  4626                     QDTPDEBUG << sectiontext.left(digits) << tmp << digits;
       
  4627                     last = tmp;
       
  4628                     used = digits;
       
  4629                     break;
       
  4630                 }
       
  4631             }
       
  4632 
       
  4633             if (last == -1) {
       
  4634                 QChar first(sectiontext.at(0));
       
  4635                 if (separators.at(sectionIndex + 1).startsWith(first)) {
       
  4636                     used = 0;
       
  4637                     state = Intermediate;
       
  4638                 } else {
       
  4639                     state = Invalid;
       
  4640                     QDTPDEBUG << "invalid because" << sectiontext << "can't become a uint" << last << ok;
       
  4641                 }
       
  4642             } else {
       
  4643                 num += last;
       
  4644                 const FieldInfo fi = fieldInfo(sectionIndex);
       
  4645                 const bool done = (used == sectionmaxsize);
       
  4646                 if (!done && fi & Fraction) { // typing 2 in a zzz field should be .200, not .002
       
  4647                     for (int i=used; i<sectionmaxsize; ++i) {
       
  4648                         num *= 10;
       
  4649                     }
       
  4650                 }
       
  4651                 const int absMin = absoluteMin(sectionIndex);
       
  4652                 if (num < absMin) {
       
  4653                     state = done ? Invalid : Intermediate;
       
  4654                     if (done)
       
  4655                         QDTPDEBUG << "invalid because" << num << "is less than absoluteMin" << absMin;
       
  4656                 } else if (num > absMax) {
       
  4657                     state = Intermediate;
       
  4658                 } else if (!done && (fi & (FixedWidth|Numeric)) == (FixedWidth|Numeric)) {
       
  4659                     if (skipToNextSection(sectionIndex, currentValue, digitsStr)) {
       
  4660                         state = Acceptable;
       
  4661                         const int missingZeroes = sectionmaxsize - digitsStr.size();
       
  4662                         text.insert(index, QString().fill(QLatin1Char('0'), missingZeroes));
       
  4663                         used = sectionmaxsize;
       
  4664                         cursorPosition += missingZeroes;
       
  4665                     } else {
       
  4666                         state = Intermediate;;
       
  4667                     }
       
  4668                 } else {
       
  4669                     state = Acceptable;
       
  4670                 }
       
  4671             }
       
  4672         }
       
  4673         break; }
       
  4674     default:
       
  4675         qWarning("QDateTimeParser::parseSection Internal error (%s %d)",
       
  4676                  qPrintable(sectionName(sn.type)), sectionIndex);
       
  4677         return -1;
       
  4678     }
       
  4679 
       
  4680     if (usedptr)
       
  4681         *usedptr = used;
       
  4682 
       
  4683     return (state != Invalid ? num : -1);
       
  4684 }
       
  4685 #endif // QT_NO_TEXTDATE
       
  4686 
       
  4687 #ifndef QT_NO_DATESTRING
       
  4688 /*!
       
  4689   \internal
       
  4690 */
       
  4691 
       
  4692 QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPosition,
       
  4693                                                   const QDateTime &currentValue, bool fixup) const
       
  4694 {
       
  4695     const QDateTime minimum = getMinimum();
       
  4696     const QDateTime maximum = getMaximum();
       
  4697 
       
  4698     State state = Acceptable;
       
  4699 
       
  4700     QDateTime newCurrentValue;
       
  4701     int pos = 0;
       
  4702     bool conflicts = false;
       
  4703     const int sectionNodesCount = sectionNodes.size();
       
  4704 
       
  4705     QDTPDEBUG << "parse" << input;
       
  4706     {
       
  4707         int year, month, day, hour12, hour, minute, second, msec, ampm, dayofweek, year2digits;
       
  4708         getDateFromJulianDay(currentValue.date().toJulianDay(), &year, &month, &day);
       
  4709         year2digits = year % 100;
       
  4710         hour = currentValue.time().hour();
       
  4711         hour12 = -1;
       
  4712         minute = currentValue.time().minute();
       
  4713         second = currentValue.time().second();
       
  4714         msec = currentValue.time().msec();
       
  4715         dayofweek = currentValue.date().dayOfWeek();
       
  4716 
       
  4717         ampm = -1;
       
  4718         Sections isSet = NoSection;
       
  4719         int num;
       
  4720         State tmpstate;
       
  4721 
       
  4722         for (int index=0; state != Invalid && index<sectionNodesCount; ++index) {
       
  4723             if (QStringRef(&input, pos, separators.at(index).size()) != separators.at(index)) {
       
  4724                 QDTPDEBUG << "invalid because" << input.mid(pos, separators.at(index).size())
       
  4725                           << "!=" << separators.at(index)
       
  4726                           << index << pos << currentSectionIndex;
       
  4727                 state = Invalid;
       
  4728                 goto end;
       
  4729             }
       
  4730             pos += separators.at(index).size();
       
  4731             sectionNodes[index].pos = pos;
       
  4732             int *current = 0;
       
  4733             const SectionNode sn = sectionNodes.at(index);
       
  4734             int used;
       
  4735 
       
  4736             num = parseSection(currentValue, index, input, cursorPosition, pos, tmpstate, &used);
       
  4737             QDTPDEBUG << "sectionValue" << sectionName(sectionType(index)) << input
       
  4738                       << "pos" << pos << "used" << used << stateName(tmpstate);
       
  4739             if (fixup && tmpstate == Intermediate && used < sn.count) {
       
  4740                 const FieldInfo fi = fieldInfo(index);
       
  4741                 if ((fi & (Numeric|FixedWidth)) == (Numeric|FixedWidth)) {
       
  4742                     const QString newText = QString::fromLatin1("%1").arg(num, sn.count, 10, QLatin1Char('0'));
       
  4743                     input.replace(pos, used, newText);
       
  4744                     used = sn.count;
       
  4745                 }
       
  4746             }
       
  4747             pos += qMax(0, used);
       
  4748 
       
  4749             state = qMin<State>(state, tmpstate);
       
  4750             if (state == Intermediate && context == FromString) {
       
  4751                 state = Invalid;
       
  4752                 break;
       
  4753             }
       
  4754 
       
  4755             QDTPDEBUG << index << sectionName(sectionType(index)) << "is set to"
       
  4756                       << pos << "state is" << stateName(state);
       
  4757 
       
  4758 
       
  4759             if (state != Invalid) {
       
  4760                 switch (sn.type) {
       
  4761                 case Hour24Section: current = &hour; break;
       
  4762                 case Hour12Section: current = &hour12; break;
       
  4763                 case MinuteSection: current = &minute; break;
       
  4764                 case SecondSection: current = &second; break;
       
  4765                 case MSecSection: current = &msec; break;
       
  4766                 case YearSection: current = &year; break;
       
  4767                 case YearSection2Digits: current = &year2digits; break;
       
  4768                 case MonthSection: current = &month; break;
       
  4769                 case DayOfWeekSection: current = &dayofweek; break;
       
  4770                 case DaySection: current = &day; num = qMax<int>(1, num); break;
       
  4771                 case AmPmSection: current = &ampm; break;
       
  4772                 default:
       
  4773                     qWarning("QDateTimeParser::parse Internal error (%s)",
       
  4774                              qPrintable(sectionName(sn.type)));
       
  4775                     break;
       
  4776                 }
       
  4777                 if (!current) {
       
  4778                     qWarning("QDateTimeParser::parse Internal error 2");
       
  4779                     return StateNode();
       
  4780                 }
       
  4781                 if (isSet & sn.type && *current != num) {
       
  4782                     QDTPDEBUG << "CONFLICT " << sectionName(sn.type) << *current << num;
       
  4783                     conflicts = true;
       
  4784                     if (index != currentSectionIndex || num == -1) {
       
  4785                         continue;
       
  4786                     }
       
  4787                 }
       
  4788                 if (num != -1)
       
  4789                     *current = num;
       
  4790                 isSet |= sn.type;
       
  4791             }
       
  4792         }
       
  4793 
       
  4794         if (state != Invalid && QStringRef(&input, pos, input.size() - pos) != separators.last()) {
       
  4795             QDTPDEBUG << "invalid because" << input.mid(pos)
       
  4796                       << "!=" << separators.last() << pos;
       
  4797             state = Invalid;
       
  4798         }
       
  4799 
       
  4800         if (state != Invalid) {
       
  4801             if (parserType != QVariant::Time) {
       
  4802                 if (year % 100 != year2digits) {
       
  4803                     switch (isSet & (YearSection2Digits|YearSection)) {
       
  4804                     case YearSection2Digits:
       
  4805                         year = (year / 100) * 100;
       
  4806                         year += year2digits;
       
  4807                         break;
       
  4808                     case ((uint)YearSection2Digits|(uint)YearSection): {
       
  4809                         conflicts = true;
       
  4810                         const SectionNode &sn = sectionNode(currentSectionIndex);
       
  4811                         if (sn.type == YearSection2Digits) {
       
  4812                             year = (year / 100) * 100;
       
  4813                             year += year2digits;
       
  4814                         }
       
  4815                         break; }
       
  4816                     default:
       
  4817                         break;
       
  4818                     }
       
  4819                 }
       
  4820 
       
  4821                 const QDate date(year, month, day);
       
  4822                 const int diff = dayofweek - date.dayOfWeek();
       
  4823                 if (diff != 0 && state == Acceptable && isSet & DayOfWeekSection) {
       
  4824                     conflicts = isSet & DaySection;
       
  4825                     const SectionNode &sn = sectionNode(currentSectionIndex);
       
  4826                     if (sn.type == DayOfWeekSection || currentSectionIndex == -1) {
       
  4827                         // dayofweek should be preferred
       
  4828                         day += diff;
       
  4829                         if (day <= 0) {
       
  4830                             day += 7;
       
  4831                         } else if (day > date.daysInMonth()) {
       
  4832                             day -= 7;
       
  4833                         }
       
  4834                         QDTPDEBUG << year << month << day << dayofweek
       
  4835                                   << diff << QDate(year, month, day).dayOfWeek();
       
  4836                     }
       
  4837                 }
       
  4838                 bool needfixday = false;
       
  4839                 if (sectionType(currentSectionIndex) & (DaySection|DayOfWeekSection)) {
       
  4840                     cachedDay = day;
       
  4841                 } else if (cachedDay > day) {
       
  4842                     day = cachedDay;
       
  4843                     needfixday = true;
       
  4844                 }
       
  4845 
       
  4846                 if (!QDate::isValid(year, month, day)) {
       
  4847                     if (day < 32) {
       
  4848                         cachedDay = day;
       
  4849                     }
       
  4850                     if (day > 28 && QDate::isValid(year, month, 1)) {
       
  4851                         needfixday = true;
       
  4852                     }
       
  4853                 }
       
  4854                 if (needfixday) {
       
  4855                     if (context == FromString) {
       
  4856                         state = Invalid;
       
  4857                         goto end;
       
  4858                     }
       
  4859                     if (state == Acceptable && fixday) {
       
  4860                         day = qMin<int>(day, QDate(year, month, 1).daysInMonth());
       
  4861 
       
  4862                         const QLocale loc = locale();
       
  4863                         for (int i=0; i<sectionNodesCount; ++i) {
       
  4864                             if (sectionType(i) & (DaySection|DayOfWeekSection)) {
       
  4865                                 input.replace(sectionPos(i), sectionSize(i), loc.toString(day));
       
  4866                             }
       
  4867                         }
       
  4868                     } else {
       
  4869                         state = qMin(Intermediate, state);
       
  4870                     }
       
  4871                 }
       
  4872             }
       
  4873 
       
  4874             if (parserType != QVariant::Date) {
       
  4875                 if (isSet & Hour12Section) {
       
  4876                     const bool hasHour = isSet & Hour24Section;
       
  4877                     if (ampm == -1) {
       
  4878                         if (hasHour) {
       
  4879                             ampm = (hour < 12 ? 0 : 1);
       
  4880                         } else {
       
  4881                             ampm = 0; // no way to tell if this is am or pm so I assume am
       
  4882                         }
       
  4883                     }
       
  4884                     hour12 = (ampm == 0 ? hour12 % 12 : (hour12 % 12) + 12);
       
  4885                     if (!hasHour) {
       
  4886                         hour = hour12;
       
  4887                     } else if (hour != hour12) {
       
  4888                         conflicts = true;
       
  4889                     }
       
  4890                 } else if (ampm != -1) {
       
  4891                     if (!(isSet & (Hour24Section))) {
       
  4892                         hour = (12 * ampm); // special case. Only ap section
       
  4893                     } else if ((ampm == 0) != (hour < 12)) {
       
  4894                         conflicts = true;
       
  4895                     }
       
  4896                 }
       
  4897 
       
  4898             }
       
  4899 
       
  4900             newCurrentValue = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);
       
  4901             QDTPDEBUG << year << month << day << hour << minute << second << msec;
       
  4902         }
       
  4903         QDTPDEBUGN("'%s' => '%s'(%s)", input.toLatin1().constData(),
       
  4904                    newCurrentValue.toString(QLatin1String("yyyy/MM/dd hh:mm:ss.zzz")).toLatin1().constData(),
       
  4905                    stateName(state).toLatin1().constData());
       
  4906     }
       
  4907 end:
       
  4908     if (newCurrentValue.isValid()) {
       
  4909         if (context != FromString && state != Invalid && newCurrentValue < minimum) {
       
  4910             const QLatin1Char space(' ');
       
  4911             if (newCurrentValue >= minimum)
       
  4912                 qWarning("QDateTimeParser::parse Internal error 3 (%s %s)",
       
  4913                          qPrintable(newCurrentValue.toString()), qPrintable(minimum.toString()));
       
  4914 
       
  4915             bool done = false;
       
  4916             state = Invalid;
       
  4917             for (int i=0; i<sectionNodesCount && !done; ++i) {
       
  4918                 const SectionNode &sn = sectionNodes.at(i);
       
  4919                 QString t = sectionText(input, i, sn.pos).toLower();
       
  4920                 if ((t.size() < sectionMaxSize(i) && (((int)fieldInfo(i) & (FixedWidth|Numeric)) != Numeric))
       
  4921                     || t.contains(space)) {
       
  4922                     switch (sn.type) {
       
  4923                     case AmPmSection:
       
  4924                         switch (findAmPm(t, i)) {
       
  4925                         case AM:
       
  4926                         case PM:
       
  4927                             state = Acceptable;
       
  4928                             done = true;
       
  4929                             break;
       
  4930                         case Neither:
       
  4931                             state = Invalid;
       
  4932                             done = true;
       
  4933                             break;
       
  4934                         case PossibleAM:
       
  4935                         case PossiblePM:
       
  4936                         case PossibleBoth: {
       
  4937                             const QDateTime copy(newCurrentValue.addSecs(12 * 60 * 60));
       
  4938                             if (copy >= minimum && copy <= maximum) {
       
  4939                                 state = Intermediate;
       
  4940                                 done = true;
       
  4941                             }
       
  4942                             break; }
       
  4943                         }
       
  4944                     case MonthSection:
       
  4945                         if (sn.count >= 3) {
       
  4946                             int tmp = newCurrentValue.date().month();
       
  4947                             // I know the first possible month makes the date too early
       
  4948                             while ((tmp = findMonth(t, tmp + 1, i)) != -1) {
       
  4949                                 const QDateTime copy(newCurrentValue.addMonths(tmp - newCurrentValue.date().month()));
       
  4950                                 if (copy >= minimum && copy <= maximum)
       
  4951                                     break; // break out of while
       
  4952                             }
       
  4953                             if (tmp == -1) {
       
  4954                                 break;
       
  4955                             }
       
  4956                             state = Intermediate;
       
  4957                             done = true;
       
  4958                             break;
       
  4959                         }
       
  4960                         // fallthrough
       
  4961                     default: {
       
  4962                         int toMin;
       
  4963                         int toMax;
       
  4964 
       
  4965                         if (sn.type & TimeSectionMask) {
       
  4966                             if (newCurrentValue.daysTo(minimum) != 0) {
       
  4967                                 break;
       
  4968                             }
       
  4969                             toMin = newCurrentValue.time().msecsTo(minimum.time());
       
  4970                             if (newCurrentValue.daysTo(maximum) > 0) {
       
  4971                                 toMax = -1; // can't get to max
       
  4972                             } else {
       
  4973                                 toMax = newCurrentValue.time().msecsTo(maximum.time());
       
  4974                             }
       
  4975                         } else {
       
  4976                             toMin = newCurrentValue.daysTo(minimum);
       
  4977                             toMax = newCurrentValue.daysTo(maximum);
       
  4978                         }
       
  4979                         const int maxChange = QDateTimeParser::maxChange(i);
       
  4980                         if (toMin > maxChange) {
       
  4981                             QDTPDEBUG << "invalid because toMin > maxChange" << toMin
       
  4982                                       << maxChange << t << newCurrentValue << minimum;
       
  4983                             state = Invalid;
       
  4984                             done = true;
       
  4985                             break;
       
  4986                         } else if (toMax > maxChange) {
       
  4987                             toMax = -1; // can't get to max
       
  4988                         }
       
  4989 
       
  4990                         const int min = getDigit(minimum, i);
       
  4991                         if (min == -1) {
       
  4992                             qWarning("QDateTimeParser::parse Internal error 4 (%s)",
       
  4993                                      qPrintable(sectionName(sn.type)));
       
  4994                             state = Invalid;
       
  4995                             done = true;
       
  4996                             break;
       
  4997                         }
       
  4998 
       
  4999                         int max = toMax != -1 ? getDigit(maximum, i) : absoluteMax(i, newCurrentValue);
       
  5000                         int pos = cursorPosition - sn.pos;
       
  5001                         if (pos < 0 || pos >= t.size())
       
  5002                             pos = -1;
       
  5003                         if (!potentialValue(t.simplified(), min, max, i, newCurrentValue, pos)) {
       
  5004                             QDTPDEBUG << "invalid because potentialValue(" << t.simplified() << min << max
       
  5005                                       << sectionName(sn.type) << "returned" << toMax << toMin << pos;
       
  5006                             state = Invalid;
       
  5007                             done = true;
       
  5008                             break;
       
  5009                         }
       
  5010                         state = Intermediate;
       
  5011                         done = true;
       
  5012                         break; }
       
  5013                     }
       
  5014                 }
       
  5015             }
       
  5016         } else {
       
  5017             if (context == FromString) {
       
  5018                 // optimization
       
  5019                 Q_ASSERT(getMaximum().date().toJulianDay() == 4642999);
       
  5020                 if (newCurrentValue.date().toJulianDay() > 4642999)
       
  5021                     state = Invalid;
       
  5022             } else {
       
  5023                 if (newCurrentValue > getMaximum())
       
  5024                     state = Invalid;
       
  5025             }
       
  5026 
       
  5027             QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << getMinimum() << getMaximum();
       
  5028         }
       
  5029     }
       
  5030     StateNode node;
       
  5031     node.input = input;
       
  5032     node.state = state;
       
  5033     node.conflicts = conflicts;
       
  5034     node.value = newCurrentValue.toTimeSpec(spec);
       
  5035     text = input;
       
  5036     return node;
       
  5037 }
       
  5038 #endif // QT_NO_DATESTRING
       
  5039 
       
  5040 #ifndef QT_NO_TEXTDATE
       
  5041 /*!
       
  5042   \internal finds the first possible monthname that \a str1 can
       
  5043   match. Starting from \a index; str should already by lowered
       
  5044 */
       
  5045 
       
  5046 int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionIndex,
       
  5047                                QString *usedMonth, int *used) const
       
  5048 {
       
  5049     int bestMatch = -1;
       
  5050     int bestCount = 0;
       
  5051     if (!str1.isEmpty()) {
       
  5052         const SectionNode &sn = sectionNode(sectionIndex);
       
  5053         if (sn.type != MonthSection) {
       
  5054             qWarning("QDateTimeParser::findMonth Internal error");
       
  5055             return -1;
       
  5056         }
       
  5057 
       
  5058         QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
       
  5059         QLocale l = locale();
       
  5060 
       
  5061         for (int month=startMonth; month<=12; ++month) {
       
  5062             QString str2 = l.monthName(month, type).toLower();
       
  5063 
       
  5064             if (str1.startsWith(str2)) {
       
  5065                 if (used) {
       
  5066                     QDTPDEBUG << "used is set to" << str2.size();
       
  5067                     *used = str2.size();
       
  5068                 }
       
  5069                 if (usedMonth)
       
  5070                     *usedMonth = l.monthName(month, type);
       
  5071 
       
  5072                 return month;
       
  5073             }
       
  5074             if (context == FromString)
       
  5075                 continue;
       
  5076 
       
  5077             const int limit = qMin(str1.size(), str2.size());
       
  5078 
       
  5079             QDTPDEBUG << "limit is" << limit << str1 << str2;
       
  5080             bool equal = true;
       
  5081             for (int i=0; i<limit; ++i) {
       
  5082                 if (str1.at(i) != str2.at(i)) {
       
  5083                     equal = false;
       
  5084                     if (i > bestCount) {
       
  5085                         bestCount = i;
       
  5086                         bestMatch = month;
       
  5087                     }
       
  5088                     break;
       
  5089                 }
       
  5090             }
       
  5091             if (equal) {
       
  5092                 if (used)
       
  5093                     *used = limit;
       
  5094                 if (usedMonth)
       
  5095                     *usedMonth = l.monthName(month, type);
       
  5096                 return month;
       
  5097             }
       
  5098         }
       
  5099         if (usedMonth && bestMatch != -1)
       
  5100             *usedMonth = l.monthName(bestMatch, type);
       
  5101     }
       
  5102     if (used) {
       
  5103         QDTPDEBUG << "used is set to" << bestCount;
       
  5104         *used = bestCount;
       
  5105     }
       
  5106     return bestMatch;
       
  5107 }
       
  5108 
       
  5109 int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex, QString *usedDay, int *used) const
       
  5110 {
       
  5111     int bestMatch = -1;
       
  5112     int bestCount = 0;
       
  5113     if (!str1.isEmpty()) {
       
  5114         const SectionNode &sn = sectionNode(sectionIndex);
       
  5115         if (!(sn.type & (DaySection|DayOfWeekSection))) {
       
  5116             qWarning("QDateTimeParser::findDay Internal error");
       
  5117             return -1;
       
  5118         }
       
  5119         const QLocale l = locale();
       
  5120         for (int day=startDay; day<=7; ++day) {
       
  5121             const QString str2 = l.dayName(day, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
       
  5122 
       
  5123             if (str1.startsWith(str2.toLower())) {
       
  5124                 if (used)
       
  5125                     *used = str2.size();
       
  5126                 if (usedDay) {
       
  5127                     *usedDay = str2;
       
  5128                 }
       
  5129                 return day;
       
  5130             }
       
  5131             if (context == FromString)
       
  5132                 continue;
       
  5133 
       
  5134             const int limit = qMin(str1.size(), str2.size());
       
  5135             bool found = true;
       
  5136             for (int i=0; i<limit; ++i) {
       
  5137                 if (str1.at(i) != str2.at(i) && !str1.at(i).isSpace()) {
       
  5138                     if (i > bestCount) {
       
  5139                         bestCount = i;
       
  5140                         bestMatch = day;
       
  5141                     }
       
  5142                     found = false;
       
  5143                     break;
       
  5144                 }
       
  5145 
       
  5146             }
       
  5147             if (found) {
       
  5148                 if (used)
       
  5149                     *used = limit;
       
  5150                 if (usedDay)
       
  5151                     *usedDay = str2;
       
  5152 
       
  5153                 return day;
       
  5154             }
       
  5155         }
       
  5156         if (usedDay && bestMatch != -1) {
       
  5157             *usedDay = l.dayName(bestMatch, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
       
  5158         }
       
  5159     }
       
  5160     if (used)
       
  5161         *used = bestCount;
       
  5162 
       
  5163     return bestMatch;
       
  5164 }
       
  5165 #endif // QT_NO_TEXTDATE
       
  5166 
       
  5167 /*!
       
  5168   \internal
       
  5169 
       
  5170   returns
       
  5171   0 if str == QDateTimeEdit::tr("AM")
       
  5172   1 if str == QDateTimeEdit::tr("PM")
       
  5173   2 if str can become QDateTimeEdit::tr("AM")
       
  5174   3 if str can become QDateTimeEdit::tr("PM")
       
  5175   4 if str can become QDateTimeEdit::tr("PM") and can become QDateTimeEdit::tr("AM")
       
  5176   -1 can't become anything sensible
       
  5177 
       
  5178 */
       
  5179 
       
  5180 int QDateTimeParser::findAmPm(QString &str, int index, int *used) const
       
  5181 {
       
  5182     const SectionNode &s = sectionNode(index);
       
  5183     if (s.type != AmPmSection) {
       
  5184         qWarning("QDateTimeParser::findAmPm Internal error");
       
  5185         return -1;
       
  5186     }
       
  5187     if (used)
       
  5188         *used = str.size();
       
  5189     if (str.trimmed().isEmpty()) {
       
  5190         return PossibleBoth;
       
  5191     }
       
  5192     const QLatin1Char space(' ');
       
  5193     int size = sectionMaxSize(index);
       
  5194 
       
  5195     enum {
       
  5196         amindex = 0,
       
  5197         pmindex = 1
       
  5198     };
       
  5199     QString ampm[2];
       
  5200     ampm[amindex] = getAmPmText(AmText, s.count == 1 ? UpperCase : LowerCase);
       
  5201     ampm[pmindex] = getAmPmText(PmText, s.count == 1 ? UpperCase : LowerCase);
       
  5202     for (int i=0; i<2; ++i)
       
  5203         ampm[i].truncate(size);
       
  5204 
       
  5205     QDTPDEBUG << "findAmPm" << str << ampm[0] << ampm[1];
       
  5206 
       
  5207     if (str.indexOf(ampm[amindex], 0, Qt::CaseInsensitive) == 0) {
       
  5208         str = ampm[amindex];
       
  5209         return AM;
       
  5210     } else if (str.indexOf(ampm[pmindex], 0, Qt::CaseInsensitive) == 0) {
       
  5211         str = ampm[pmindex];
       
  5212         return PM;
       
  5213     } else if (context == FromString || (str.count(space) == 0 && str.size() >= size)) {
       
  5214         return Neither;
       
  5215     }
       
  5216     size = qMin(size, str.size());
       
  5217 
       
  5218     bool broken[2] = {false, false};
       
  5219     for (int i=0; i<size; ++i) {
       
  5220         if (str.at(i) != space) {
       
  5221             for (int j=0; j<2; ++j) {
       
  5222                 if (!broken[j]) {
       
  5223                     int index = ampm[j].indexOf(str.at(i));
       
  5224                     QDTPDEBUG << "looking for" << str.at(i)
       
  5225                               << "in" << ampm[j] << "and got" << index;
       
  5226                     if (index == -1) {
       
  5227                         if (str.at(i).category() == QChar::Letter_Uppercase) {
       
  5228                             index = ampm[j].indexOf(str.at(i).toLower());
       
  5229                             QDTPDEBUG << "trying with" << str.at(i).toLower()
       
  5230                                       << "in" << ampm[j] << "and got" << index;
       
  5231                         } else if (str.at(i).category() == QChar::Letter_Lowercase) {
       
  5232                             index = ampm[j].indexOf(str.at(i).toUpper());
       
  5233                             QDTPDEBUG << "trying with" << str.at(i).toUpper()
       
  5234                                       << "in" << ampm[j] << "and got" << index;
       
  5235                         }
       
  5236                         if (index == -1) {
       
  5237                             broken[j] = true;
       
  5238                             if (broken[amindex] && broken[pmindex]) {
       
  5239                                 QDTPDEBUG << str << "didn't make it";
       
  5240                                 return Neither;
       
  5241                             }
       
  5242                             continue;
       
  5243                         } else {
       
  5244                             str[i] = ampm[j].at(index); // fix case
       
  5245                         }
       
  5246                     }
       
  5247                     ampm[j].remove(index, 1);
       
  5248                 }
       
  5249             }
       
  5250         }
       
  5251     }
       
  5252     if (!broken[pmindex] && !broken[amindex])
       
  5253         return PossibleBoth;
       
  5254     return (!broken[amindex] ? PossibleAM : PossiblePM);
       
  5255 }
       
  5256 
       
  5257 /*!
       
  5258   \internal
       
  5259   Max number of units that can be changed by this section.
       
  5260 */
       
  5261 
       
  5262 int QDateTimeParser::maxChange(int index) const
       
  5263 {
       
  5264     const SectionNode &sn = sectionNode(index);
       
  5265     switch (sn.type) {
       
  5266         // Time. unit is msec
       
  5267     case MSecSection: return 999;
       
  5268     case SecondSection: return 59 * 1000;
       
  5269     case MinuteSection: return 59 * 60 * 1000;
       
  5270     case Hour24Section: case Hour12Section: return 59 * 60 * 60 * 1000;
       
  5271 
       
  5272         // Date. unit is day
       
  5273     case DayOfWeekSection: return 7;
       
  5274     case DaySection: return 30;
       
  5275     case MonthSection: return 365 - 31;
       
  5276     case YearSection: return 9999 * 365;
       
  5277     case YearSection2Digits: return 100 * 365;
       
  5278     default:
       
  5279         qWarning("QDateTimeParser::maxChange() Internal error (%s)",
       
  5280                  qPrintable(sectionName(sectionType(index))));
       
  5281     }
       
  5282 
       
  5283     return -1;
       
  5284 }
       
  5285 
       
  5286 QDateTimeParser::FieldInfo QDateTimeParser::fieldInfo(int index) const
       
  5287 {
       
  5288     FieldInfo ret = 0;
       
  5289     const SectionNode &sn = sectionNode(index);
       
  5290     const Section s = sn.type;
       
  5291     switch (s) {
       
  5292     case MSecSection:
       
  5293         ret |= Fraction;
       
  5294         // fallthrough
       
  5295     case SecondSection:
       
  5296     case MinuteSection:
       
  5297     case Hour24Section:
       
  5298     case Hour12Section:
       
  5299     case YearSection:
       
  5300     case YearSection2Digits:
       
  5301         ret |= Numeric;
       
  5302         if (s != YearSection) {
       
  5303             ret |= AllowPartial;
       
  5304         }
       
  5305         if (sn.count != 1) {
       
  5306             ret |= FixedWidth;
       
  5307         }
       
  5308         break;
       
  5309     case MonthSection:
       
  5310     case DaySection:
       
  5311         switch (sn.count) {
       
  5312         case 2:
       
  5313             ret |= FixedWidth;
       
  5314             // fallthrough
       
  5315         case 1:
       
  5316             ret |= (Numeric|AllowPartial);
       
  5317             break;
       
  5318         }
       
  5319         break;
       
  5320     case DayOfWeekSection:
       
  5321         if (sn.count == 3)
       
  5322             ret |= FixedWidth;
       
  5323         break;
       
  5324     case AmPmSection:
       
  5325         ret |= FixedWidth;
       
  5326         break;
       
  5327     default:
       
  5328         qWarning("QDateTimeParser::fieldInfo Internal error 2 (%d %s %d)",
       
  5329                  index, qPrintable(sectionName(sn.type)), sn.count);
       
  5330         break;
       
  5331     }
       
  5332     return ret;
       
  5333 }
       
  5334 
       
  5335 /*!
       
  5336   \internal Get a number that str can become which is between min
       
  5337   and max or -1 if this is not possible.
       
  5338 */
       
  5339 
       
  5340 
       
  5341 QString QDateTimeParser::sectionFormat(int index) const
       
  5342 {
       
  5343     const SectionNode &sn = sectionNode(index);
       
  5344     return sectionFormat(sn.type, sn.count);
       
  5345 }
       
  5346 
       
  5347 QString QDateTimeParser::sectionFormat(Section s, int count) const
       
  5348 {
       
  5349     QChar fillChar;
       
  5350     switch (s) {
       
  5351     case AmPmSection: return count == 1 ? QLatin1String("AP") : QLatin1String("ap");
       
  5352     case MSecSection: fillChar = QLatin1Char('z'); break;
       
  5353     case SecondSection: fillChar = QLatin1Char('s'); break;
       
  5354     case MinuteSection: fillChar = QLatin1Char('m'); break;
       
  5355     case Hour24Section: fillChar = QLatin1Char('H'); break;
       
  5356     case Hour12Section: fillChar = QLatin1Char('h'); break;
       
  5357     case DayOfWeekSection:
       
  5358     case DaySection: fillChar = QLatin1Char('d'); break;
       
  5359     case MonthSection: fillChar = QLatin1Char('M'); break;
       
  5360     case YearSection2Digits:
       
  5361     case YearSection: fillChar = QLatin1Char('y'); break;
       
  5362     default:
       
  5363         qWarning("QDateTimeParser::sectionFormat Internal error (%s)",
       
  5364                  qPrintable(sectionName(s)));
       
  5365         return QString();
       
  5366     }
       
  5367     if (fillChar.isNull()) {
       
  5368         qWarning("QDateTimeParser::sectionFormat Internal error 2");
       
  5369         return QString();
       
  5370     }
       
  5371 
       
  5372     QString str;
       
  5373     str.fill(fillChar, count);
       
  5374     return str;
       
  5375 }
       
  5376 
       
  5377 
       
  5378 /*! \internal Returns true if str can be modified to represent a
       
  5379   number that is within min and max.
       
  5380 */
       
  5381 
       
  5382 bool QDateTimeParser::potentialValue(const QString &str, int min, int max, int index,
       
  5383                                      const QDateTime &currentValue, int insert) const
       
  5384 {
       
  5385     if (str.isEmpty()) {
       
  5386         return true;
       
  5387     }
       
  5388     const int size = sectionMaxSize(index);
       
  5389     int val = (int)locale().toUInt(str);
       
  5390     const SectionNode &sn = sectionNode(index);
       
  5391     if (sn.type == YearSection2Digits) {
       
  5392         val += currentValue.date().year() - (currentValue.date().year() % 100);
       
  5393     }
       
  5394     if (val >= min && val <= max && str.size() == size) {
       
  5395         return true;
       
  5396     } else if (val > max) {
       
  5397         return false;
       
  5398     } else if (str.size() == size && val < min) {
       
  5399         return false;
       
  5400     }
       
  5401 
       
  5402     const int len = size - str.size();
       
  5403     for (int i=0; i<len; ++i) {
       
  5404         for (int j=0; j<10; ++j) {
       
  5405             if (potentialValue(str + QLatin1Char('0' + j), min, max, index, currentValue, insert)) {
       
  5406                 return true;
       
  5407             } else if (insert >= 0) {
       
  5408                 QString tmp = str;
       
  5409                 tmp.insert(insert, QLatin1Char('0' + j));
       
  5410                 if (potentialValue(tmp, min, max, index, currentValue, insert))
       
  5411                     return true;
       
  5412             }
       
  5413         }
       
  5414     }
       
  5415 
       
  5416     return false;
       
  5417 }
       
  5418 
       
  5419 bool QDateTimeParser::skipToNextSection(int index, const QDateTime &current, const QString &text) const
       
  5420 {
       
  5421     Q_ASSERT(current >= getMinimum() && current <= getMaximum());
       
  5422 
       
  5423     const SectionNode &node = sectionNode(index);
       
  5424     Q_ASSERT(text.size() < sectionMaxSize(index));
       
  5425 
       
  5426     const QDateTime maximum = getMaximum();
       
  5427     const QDateTime minimum = getMinimum();
       
  5428     QDateTime tmp = current;
       
  5429     int min = absoluteMin(index);
       
  5430     setDigit(tmp, index, min);
       
  5431     if (tmp < minimum) {
       
  5432         min = getDigit(minimum, index);
       
  5433     }
       
  5434 
       
  5435     int max = absoluteMax(index, current);
       
  5436     setDigit(tmp, index, max);
       
  5437     if (tmp > maximum) {
       
  5438         max = getDigit(maximum, index);
       
  5439     }
       
  5440     int pos = cursorPosition() - node.pos;
       
  5441     if (pos < 0 || pos >= text.size())
       
  5442         pos = -1;
       
  5443 
       
  5444     const bool potential = potentialValue(text, min, max, index, current, pos);
       
  5445     return !potential;
       
  5446 
       
  5447     /* If the value potentially can become another valid entry we
       
  5448      * don't want to skip to the next. E.g. In a M field (month
       
  5449      * without leading 0 if you type 1 we don't want to autoskip but
       
  5450      * if you type 3 we do
       
  5451     */
       
  5452 }
       
  5453 
       
  5454 /*!
       
  5455   \internal
       
  5456   For debugging. Returns the name of the section \a s.
       
  5457 */
       
  5458 
       
  5459 QString QDateTimeParser::sectionName(int s) const
       
  5460 {
       
  5461     switch (s) {
       
  5462     case QDateTimeParser::AmPmSection: return QLatin1String("AmPmSection");
       
  5463     case QDateTimeParser::DaySection: return QLatin1String("DaySection");
       
  5464     case QDateTimeParser::DayOfWeekSection: return QLatin1String("DayOfWeekSection");
       
  5465     case QDateTimeParser::Hour24Section: return QLatin1String("Hour24Section");
       
  5466     case QDateTimeParser::Hour12Section: return QLatin1String("Hour12Section");
       
  5467     case QDateTimeParser::MSecSection: return QLatin1String("MSecSection");
       
  5468     case QDateTimeParser::MinuteSection: return QLatin1String("MinuteSection");
       
  5469     case QDateTimeParser::MonthSection: return QLatin1String("MonthSection");
       
  5470     case QDateTimeParser::SecondSection: return QLatin1String("SecondSection");
       
  5471     case QDateTimeParser::YearSection: return QLatin1String("YearSection");
       
  5472     case QDateTimeParser::YearSection2Digits: return QLatin1String("YearSection2Digits");
       
  5473     case QDateTimeParser::NoSection: return QLatin1String("NoSection");
       
  5474     case QDateTimeParser::FirstSection: return QLatin1String("FirstSection");
       
  5475     case QDateTimeParser::LastSection: return QLatin1String("LastSection");
       
  5476     default: return QLatin1String("Unknown section ") + QString::number(s);
       
  5477     }
       
  5478 }
       
  5479 
       
  5480 /*!
       
  5481   \internal
       
  5482   For debugging. Returns the name of the state \a s.
       
  5483 */
       
  5484 
       
  5485 QString QDateTimeParser::stateName(int s) const
       
  5486 {
       
  5487     switch (s) {
       
  5488     case Invalid: return QLatin1String("Invalid");
       
  5489     case Intermediate: return QLatin1String("Intermediate");
       
  5490     case Acceptable: return QLatin1String("Acceptable");
       
  5491     default: return QLatin1String("Unknown state ") + QString::number(s);
       
  5492     }
       
  5493 }
       
  5494 
       
  5495 #ifndef QT_NO_DATESTRING
       
  5496 bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) const
       
  5497 {
       
  5498     QDateTime val(QDate(1900, 1, 1), QDATETIMEEDIT_TIME_MIN);
       
  5499     QString text = t;
       
  5500     int copy = -1;
       
  5501     const StateNode tmp = parse(text, copy, val, false);
       
  5502     if (tmp.state != Acceptable || tmp.conflicts) {
       
  5503         return false;
       
  5504     }
       
  5505     if (time) {
       
  5506         const QTime t = tmp.value.time();
       
  5507         if (!t.isValid()) {
       
  5508             return false;
       
  5509         }
       
  5510         *time = t;
       
  5511     }
       
  5512 
       
  5513     if (date) {
       
  5514         const QDate d = tmp.value.date();
       
  5515         if (!d.isValid()) {
       
  5516             return false;
       
  5517         }
       
  5518         *date = d;
       
  5519     }
       
  5520     return true;
       
  5521 }
       
  5522 #endif // QT_NO_DATESTRING
       
  5523 
       
  5524 QDateTime QDateTimeParser::getMinimum() const
       
  5525 {
       
  5526     return QDateTime(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN, spec);
       
  5527 }
       
  5528 
       
  5529 QDateTime QDateTimeParser::getMaximum() const
       
  5530 {
       
  5531     return QDateTime(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX, spec);
       
  5532 }
       
  5533 
       
  5534 QString QDateTimeParser::getAmPmText(AmPm ap, Case cs) const
       
  5535 {
       
  5536     if (ap == AmText) {
       
  5537         return (cs == UpperCase ? QLatin1String("AM") : QLatin1String("am"));
       
  5538     } else {
       
  5539         return (cs == UpperCase ? QLatin1String("PM") : QLatin1String("pm"));
       
  5540     }
       
  5541 }
       
  5542 
       
  5543 /*
       
  5544   \internal
       
  5545 
       
  5546   I give arg2 preference because arg1 is always a QDateTime.
       
  5547 */
       
  5548 
       
  5549 bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::SectionNode &s2)
       
  5550 {
       
  5551     return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count);
       
  5552 }
       
  5553 
       
  5554 
       
  5555 #endif // QT_BOOTSTRAPPED
       
  5556 
       
  5557 QT_END_NAMESPACE