Qt 4.8
qdatetime.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
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 #include <tz.h>
79 #endif
80 
82 
83 enum {
84  FIRST_YEAR = -4713,
86  FIRST_DAY = 2, // ### Qt 5: make FIRST_DAY = 1, by support jd == 0 as valid
87  SECS_PER_DAY = 86400,
88  MSECS_PER_DAY = 86400000,
89  SECS_PER_HOUR = 3600,
90  MSECS_PER_HOUR = 3600000,
92  MSECS_PER_MIN = 60000,
93  JULIAN_DAY_FOR_EPOCH = 2440588 // result of julianDayFromGregorianDate(1970, 1, 1)
94 };
95 
96 static inline QDate fixedDate(int y, int m, int d)
97 {
98  QDate result(y, m, 1);
99  result.setDate(y, m, qMin(d, result.daysInMonth()));
100  return result;
101 }
102 
103 static inline uint julianDayFromGregorianDate(int year, int month, int day)
104 {
105  // Gregorian calendar starting from October 15, 1582
106  // Algorithm from Henry F. Fliegel and Thomas C. Van Flandern
107  return (1461 * (year + 4800 + (month - 14) / 12)) / 4
108  + (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12
109  - (3 * ((year + 4900 + (month - 14) / 12) / 100)) / 4
110  + day - 32075;
111 }
112 
113 static uint julianDayFromDate(int year, int month, int day)
114 {
115  if (year < 0)
116  ++year;
117 
118  if (year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15)))) {
119  return julianDayFromGregorianDate(year, month, day);
120  } else if (year < 1582 || (year == 1582 && (month < 10 || (month == 10 && day <= 4)))) {
121  // Julian calendar until October 4, 1582
122  // Algorithm from Frequently Asked Questions about Calendars by Claus Toendering
123  int a = (14 - month) / 12;
124  return (153 * (month + (12 * a) - 3) + 2) / 5
125  + (1461 * (year + 4800 - a)) / 4
126  + day - 32083;
127  } else {
128  // the day following October 4, 1582 is October 15, 1582
129  return 0;
130  }
131 }
132 
133 static void getDateFromJulianDay(uint julianDay, int *year, int *month, int *day)
134 {
135  int y, m, d;
136 
137  if (julianDay >= 2299161) {
138  // Gregorian calendar starting from October 15, 1582
139  // This algorithm is from Henry F. Fliegel and Thomas C. Van Flandern
140  qulonglong ell, n, i, j;
141  ell = qulonglong(julianDay) + 68569;
142  n = (4 * ell) / 146097;
143  ell = ell - (146097 * n + 3) / 4;
144  i = (4000 * (ell + 1)) / 1461001;
145  ell = ell - (1461 * i) / 4 + 31;
146  j = (80 * ell) / 2447;
147  d = ell - (2447 * j) / 80;
148  ell = j / 11;
149  m = j + 2 - (12 * ell);
150  y = 100 * (n - 49) + i + ell;
151  } else {
152  // Julian calendar until October 4, 1582
153  // Algorithm from Frequently Asked Questions about Calendars by Claus Toendering
154  julianDay += 32082;
155  int dd = (4 * julianDay + 3) / 1461;
156  int ee = julianDay - (1461 * dd) / 4;
157  int mm = ((5 * ee) + 2) / 153;
158  d = ee - (153 * mm + 2) / 5 + 1;
159  m = mm + 3 - 12 * (mm / 10);
160  y = dd - 4800 + (mm / 10);
161  if (y <= 0)
162  --y;
163  }
164  if (year)
165  *year = y;
166  if (month)
167  *month = m;
168  if (day)
169  *day = d;
170 }
171 
172 
173 static const char monthDays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
174 
175 #ifndef QT_NO_TEXTDATE
176 static const char * const qt_shortMonthNames[] = {
177  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
178  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
179 #endif
180 #ifndef QT_NO_DATESTRING
181 static QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* dd = 0);
182 #endif
183 
184 /*****************************************************************************
185  QDate member functions
186  *****************************************************************************/
187 
313 QDate::QDate(int y, int m, int d)
314 {
315  setDate(y, m, d);
316 }
317 
318 
340 bool QDate::isValid() const
341 {
342  return !isNull();
343 }
344 
345 
353 int QDate::year() const
354 {
355  int y;
356  getDateFromJulianDay(jd, &y, 0, 0);
357  return y;
358 }
359 
382 int QDate::month() const
383 {
384  int m;
385  getDateFromJulianDay(jd, 0, &m, 0);
386  return m;
387 }
388 
395 int QDate::day() const
396 {
397  int d;
398  getDateFromJulianDay(jd, 0, 0, &d);
399  return d;
400 }
401 
408 int QDate::dayOfWeek() const
409 {
410  return (jd % 7) + 1;
411 }
412 
420 int QDate::dayOfYear() const
421 {
422  return jd - julianDayFromDate(year(), 1, 1) + 1;
423 }
424 
432 {
433  int y, m, d;
434  getDateFromJulianDay(jd, &y, &m, &d);
435  if (m == 2 && isLeapYear(y))
436  return 29;
437  else
438  return monthDays[m];
439 }
440 
447 int QDate::daysInYear() const
448 {
449  int y, m, d;
450  getDateFromJulianDay(jd, &y, &m, &d);
451  return isLeapYear(y) ? 366 : 365;
452 }
453 
487 int QDate::weekNumber(int *yearNumber) const
488 {
489  if (!isValid())
490  return 0;
491 
492  int year = QDate::year();
493  int yday = dayOfYear() - 1;
494  int wday = dayOfWeek();
495  if (wday == 7)
496  wday = 0;
497  int w;
498 
499  for (;;) {
500  int len;
501  int bot;
502  int top;
503 
504  len = isLeapYear(year) ? 366 : 365;
505  /*
506  ** What yday (-3 ... 3) does
507  ** the ISO year begin on?
508  */
509  bot = ((yday + 11 - wday) % 7) - 3;
510  /*
511  ** What yday does the NEXT
512  ** ISO year begin on?
513  */
514  top = bot - (len % 7);
515  if (top < -3)
516  top += 7;
517  top += len;
518  if (yday >= top) {
519  ++year;
520  w = 1;
521  break;
522  }
523  if (yday >= bot) {
524  w = 1 + ((yday - bot) / 7);
525  break;
526  }
527  --year;
528  yday += isLeapYear(year) ? 366 : 365;
529  }
530  if (yearNumber != 0)
531  *yearNumber = year;
532  return w;
533 }
534 
535 #ifndef QT_NO_TEXTDATE
536 
569 {
570  if (month < 1 || month > 12) {
571  month = 1;
572  }
573  switch (type) {
574  case QDate::DateFormat:
578  default:
579  break;
580  }
581  return QString();
582 }
583 
592 {
593  return shortMonthName(month, QDate::DateFormat);
594 }
595 
629 {
630  if (month < 1 || month > 12) {
631  month = 1;
632  }
633  switch (type) {
634  case QDate::DateFormat:
638  default:
639  break;
640  }
641  return QString();
642 }
643 
652 {
653  if (month < 1 || month > 12) {
654  month = 1;
655  }
657 }
658 
687 {
688  if (weekday < 1 || weekday > 7) {
689  weekday = 1;
690  }
691  switch (type) {
692  case QDate::DateFormat:
693  return QLocale::system().dayName(weekday, QLocale::ShortFormat);
696  default:
697  break;
698  }
699  return QString();
700 }
701 
710 {
711  if (weekday < 1 || weekday > 7) {
712  weekday = 1;
713  }
714  return QLocale::system().dayName(weekday, QLocale::ShortFormat);
715 }
716 
745 {
746  if (weekday < 1 || weekday > 7) {
747  weekday = 1;
748  }
749  switch (type) {
750  case QDate::DateFormat:
751  return QLocale::system().dayName(weekday, QLocale::LongFormat);
754  default:
755  break;
756  }
757  return QLocale::system().dayName(weekday, QLocale::LongFormat);
758 }
759 
768 {
769  if (weekday < 1 || weekday > 7) {
770  weekday = 1;
771  }
772  return QLocale::system().dayName(weekday, QLocale::LongFormat);
773 }
774 #endif //QT_NO_TEXTDATE
775 
776 #ifndef QT_NO_DATESTRING
777 
824 {
825  if (!isValid())
826  return QString();
827  int y, m, d;
828  getDateFromJulianDay(jd, &y, &m, &d);
829  switch (f) {
835  case Qt::LocaleDate:
839  : QLocale::ShortFormat);
840  default:
841 #ifndef QT_NO_TEXTDATE
842  case Qt::TextDate:
843  {
844  return QString::fromLatin1("%0 %1 %2 %3")
846  .arg(shortMonthName(m))
847  .arg(d)
848  .arg(y);
849  }
850 #endif
851  case Qt::ISODate:
852  {
853  if (year() < 0 || year() > 9999)
854  return QString();
855  QString month(QString::number(m).rightJustified(2, QLatin1Char('0')));
856  QString day(QString::number(d).rightJustified(2, QLatin1Char('0')));
857  return QString::number(y) + QLatin1Char('-') + month + QLatin1Char('-') + day;
858  }
859  }
860 }
861 
916 {
917  if (year() > 9999)
918  return QString();
919  return fmtDateTime(format, 0, this);
920 }
921 #endif //QT_NO_DATESTRING
922 
937 bool QDate::setYMD(int y, int m, int d)
938 {
939  if (uint(y) <= 99)
940  y += 1900;
941  return setDate(y, m, d);
942 }
943 
959 bool QDate::setDate(int year, int month, int day)
960 {
961  if (!isValid(year, month, day)) {
962  jd = 0;
963  } else {
964  jd = julianDayFromDate(year, month, day);
965  }
966  return jd != 0;
967 }
968 
977 void QDate::getDate(int *year, int *month, int *day)
978 {
979  getDateFromJulianDay(jd, year, month, day);
980 }
981 
989 QDate QDate::addDays(int ndays) const
990 {
991  QDate d;
992  // this is basically "d.jd = jd + ndays" with checks for integer overflow
993  if (ndays >= 0)
994  d.jd = (jd + ndays >= jd) ? jd + ndays : 0;
995  else
996  d.jd = (jd + ndays < jd) ? jd + ndays : 0;
997  return d;
998 }
999 
1016 QDate QDate::addMonths(int nmonths) const
1017 {
1018  if (!isValid())
1019  return QDate();
1020  if (!nmonths)
1021  return *this;
1022 
1023  int old_y, y, m, d;
1024  getDateFromJulianDay(jd, &y, &m, &d);
1025  old_y = y;
1026 
1027  bool increasing = nmonths > 0;
1028 
1029  while (nmonths != 0) {
1030  if (nmonths < 0 && nmonths + 12 <= 0) {
1031  y--;
1032  nmonths+=12;
1033  } else if (nmonths < 0) {
1034  m+= nmonths;
1035  nmonths = 0;
1036  if (m <= 0) {
1037  --y;
1038  m += 12;
1039  }
1040  } else if (nmonths - 12 >= 0) {
1041  y++;
1042  nmonths -= 12;
1043  } else if (m == 12) {
1044  y++;
1045  m = 0;
1046  } else {
1047  m += nmonths;
1048  nmonths = 0;
1049  if (m > 12) {
1050  ++y;
1051  m -= 12;
1052  }
1053  }
1054  }
1055 
1056  // was there a sign change?
1057  if ((old_y > 0 && y <= 0) ||
1058  (old_y < 0 && y >= 0))
1059  // yes, adjust the date by +1 or -1 years
1060  y += increasing ? +1 : -1;
1061 
1062  // did we end up in the Gregorian/Julian conversion hole?
1063  if (y == 1582 && m == 10 && d > 4 && d < 15)
1064  d = increasing ? 15 : 4;
1065 
1066  return fixedDate(y, m, d);
1067 }
1068 
1081 QDate QDate::addYears(int nyears) const
1082 {
1083  if (!isValid())
1084  return QDate();
1085 
1086  int y, m, d;
1087  getDateFromJulianDay(jd, &y, &m, &d);
1088 
1089  int old_y = y;
1090  y += nyears;
1091 
1092  // was there a sign change?
1093  if ((old_y > 0 && y <= 0) ||
1094  (old_y < 0 && y >= 0))
1095  // yes, adjust the date by +1 or -1 years
1096  y += nyears > 0 ? +1 : -1;
1097 
1098  return fixedDate(y, m, d);
1099 }
1100 
1111 int QDate::daysTo(const QDate &d) const
1112 {
1113  return d.jd - jd;
1114 }
1115 
1116 
1188 #ifndef QT_NO_DATESTRING
1189 
1204 {
1205  if (s.isEmpty())
1206  return QDate();
1207 
1208  switch (f) {
1209  case Qt::ISODate:
1210  {
1211  int year(s.mid(0, 4).toInt());
1212  int month(s.mid(5, 2).toInt());
1213  int day(s.mid(8, 2).toInt());
1214  if (year && month && day)
1215  return QDate(year, month, day);
1216  }
1217  break;
1218  case Qt::SystemLocaleDate:
1223  case Qt::LocaleDate:
1226  return fromString(s, QLocale().dateFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
1227  : QLocale::ShortFormat));
1228  default:
1229 #ifndef QT_NO_TEXTDATE
1230  case Qt::TextDate: {
1232 
1233  if (parts.count() != 4) {
1234  return QDate();
1235  }
1236 
1237  QString monthName = parts.at(1);
1238  int month = -1;
1239  // Assume that English monthnames are the default
1240  for (int i = 0; i < 12; ++i) {
1241  if (monthName == QLatin1String(qt_shortMonthNames[i])) {
1242  month = i + 1;
1243  break;
1244  }
1245  }
1246  // If English names can't be found, search the localized ones
1247  if (month == -1) {
1248  for (int i = 1; i <= 12; ++i) {
1249  if (monthName == QDate::shortMonthName(i)) {
1250  month = i;
1251  break;
1252  }
1253  }
1254  }
1255  if (month < 1 || month > 12) {
1256  return QDate();
1257  }
1258 
1259  bool ok;
1260  int day = parts.at(2).toInt(&ok);
1261  if (!ok) {
1262  return QDate();
1263  }
1264 
1265  int year = parts.at(3).toInt(&ok);
1266  if (!ok) {
1267  return QDate();
1268  }
1269 
1270  return QDate(year, month, day);
1271  }
1272 #else
1273  break;
1274 #endif
1275  }
1276  return QDate();
1277 }
1278 
1348 {
1349  QDate date;
1350 #ifndef QT_BOOTSTRAPPED
1352  if (dt.parseFormat(format))
1353  dt.fromString(string, &date, 0);
1354 #else
1355  Q_UNUSED(string);
1356  Q_UNUSED(format);
1357 #endif
1358  return date;
1359 }
1360 #endif // QT_NO_DATESTRING
1361 
1377 bool QDate::isValid(int year, int month, int day)
1378 {
1379  if (year < FIRST_YEAR
1380  || (year == FIRST_YEAR &&
1381  (month < FIRST_MONTH
1382  || (month == FIRST_MONTH && day < FIRST_DAY)))
1383  || year == 0) // there is no year 0 in the Julian calendar
1384  return false;
1385 
1386  // passage from Julian to Gregorian calendar
1387  if (year == 1582 && month == 10 && day > 4 && day < 15)
1388  return 0;
1389 
1390  return (day > 0 && month > 0 && month <= 12) &&
1391  (day <= monthDays[month] || (day == 29 && month == 2 && isLeapYear(year)));
1392 }
1393 
1405 {
1406  if (y < 1582) {
1407  if ( y < 1) { // No year 0 in Julian calendar, so -1, -5, -9 etc are leap years
1408  ++y;
1409  }
1410  return y % 4 == 0;
1411  } else {
1412  return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
1413  }
1414 }
1415 
1426 uint QDate::gregorianToJulian(int y, int m, int d)
1427 {
1428  return julianDayFromDate(y, m, d);
1429 }
1430 
1441 void QDate::julianToGregorian(uint jd, int &y, int &m, int &d)
1442 {
1443  getDateFromJulianDay(jd, &y, &m, &d);
1444 }
1445 
1466 /*****************************************************************************
1467  QTime member functions
1468  *****************************************************************************/
1469 
1540 QTime::QTime(int h, int m, int s, int ms)
1541 {
1542  setHMS(h, m, s, ms);
1543 }
1544 
1545 
1566 bool QTime::isValid() const
1567 {
1568  return mds > NullTime && mds < MSECS_PER_DAY;
1569 }
1570 
1571 
1578 int QTime::hour() const
1579 {
1580  return ds() / MSECS_PER_HOUR;
1581 }
1582 
1589 int QTime::minute() const
1590 {
1591  return (ds() % MSECS_PER_HOUR) / MSECS_PER_MIN;
1592 }
1593 
1600 int QTime::second() const
1601 {
1602  return (ds() / 1000)%SECS_PER_MIN;
1603 }
1604 
1611 int QTime::msec() const
1612 {
1613  return ds() % 1000;
1614 }
1615 
1616 #ifndef QT_NO_DATESTRING
1617 
1654 {
1655  if (!isValid())
1656  return QString();
1657 
1658  switch (format) {
1659  case Qt::SystemLocaleDate:
1664  case Qt::LocaleDate:
1668  : QLocale::ShortFormat);
1669 
1670  default:
1671  case Qt::ISODate:
1672  case Qt::TextDate:
1673  return QString::fromLatin1("%1:%2:%3")
1674  .arg(hour(), 2, 10, QLatin1Char('0'))
1675  .arg(minute(), 2, 10, QLatin1Char('0'))
1676  .arg(second(), 2, 10, QLatin1Char('0'));
1677  }
1678 }
1679 
1729 {
1730  return fmtDateTime(format, this, 0);
1731 }
1732 #endif //QT_NO_DATESTRING
1733 
1744 bool QTime::setHMS(int h, int m, int s, int ms)
1745 {
1746 #if defined(Q_OS_WINCE)
1747  startTick = NullTime;
1748 #endif
1749  if (!isValid(h,m,s,ms)) {
1750  mds = NullTime; // make this invalid
1751  return false;
1752  }
1753  mds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;
1754  return true;
1755 }
1756 
1770 QTime QTime::addSecs(int s) const
1771 {
1772  return addMSecs(s * 1000);
1773 }
1774 
1788 int QTime::secsTo(const QTime &t) const
1789 {
1790  return (t.ds() - ds()) / 1000;
1791 }
1792 
1803 QTime QTime::addMSecs(int ms) const
1804 {
1805  QTime t;
1806  if (ms < 0) {
1807  // % not well-defined for -ve, but / is.
1808  int negdays = (MSECS_PER_DAY - ms) / MSECS_PER_DAY;
1809  t.mds = (ds() + ms + negdays * MSECS_PER_DAY) % MSECS_PER_DAY;
1810  } else {
1811  t.mds = (ds() + ms) % MSECS_PER_DAY;
1812  }
1813 #if defined(Q_OS_WINCE)
1814  if (startTick > NullTime)
1815  t.startTick = (startTick + ms) % MSECS_PER_DAY;
1816 #endif
1817  return t;
1818 }
1819 
1832 int QTime::msecsTo(const QTime &t) const
1833 {
1834 #if defined(Q_OS_WINCE)
1835  // GetLocalTime() for Windows CE has no milliseconds resolution
1836  if (t.startTick > NullTime && startTick > NullTime)
1837  return t.startTick - startTick;
1838  else
1839 #endif
1840  return t.ds() - ds();
1841 }
1842 
1843 
1912 #ifndef QT_NO_DATESTRING
1913 
1929 {
1930  if (s.isEmpty()) {
1931  QTime t;
1932  t.mds = NullTime;
1933  return t;
1934  }
1935 
1936  switch (f) {
1937  case Qt::SystemLocaleDate:
1942  case Qt::LocaleDate:
1945  return fromString(s, QLocale().timeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
1946  : QLocale::ShortFormat));
1947  default:
1948  {
1949  bool ok = true;
1950  const int hour(s.mid(0, 2).toInt(&ok));
1951  if (!ok)
1952  return QTime();
1953  const int minute(s.mid(3, 2).toInt(&ok));
1954  if (!ok)
1955  return QTime();
1956  const int second(s.mid(6, 2).toInt(&ok));
1957  if (!ok)
1958  return QTime();
1959  const QString msec_s(QLatin1String("0.") + s.mid(9, 4));
1960  const float msec(msec_s.toFloat(&ok));
1961  if (!ok)
1962  return QTime(hour, minute, second, 0);
1963  return QTime(hour, minute, second, qMin(qRound(msec * 1000.0), 999));
1964  }
1965  }
1966 }
1967 
2023 {
2024  QTime time;
2025 #ifndef QT_BOOTSTRAPPED
2027  if (dt.parseFormat(format))
2028  dt.fromString(string, 0, &time);
2029 #else
2030  Q_UNUSED(string);
2031  Q_UNUSED(format);
2032 #endif
2033  return time;
2034 }
2035 
2036 #endif // QT_NO_DATESTRING
2037 
2038 
2056 bool QTime::isValid(int h, int m, int s, int ms)
2057 {
2058  return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
2059 }
2060 
2061 
2071 {
2072  *this = currentTime();
2073 }
2074 
2096 {
2097  QTime t = currentTime();
2098  int n = msecsTo(t);
2099  if (n < 0) // passed midnight
2100  n += 86400*1000;
2101  *this = t;
2102  return n;
2103 }
2104 
2123 int QTime::elapsed() const
2124 {
2125  int n = msecsTo(currentTime());
2126  if (n < 0) // passed midnight
2127  n += 86400 * 1000;
2128  return n;
2129 }
2130 
2131 
2132 /*****************************************************************************
2133  QDateTime member functions
2134  *****************************************************************************/
2135 
2268  : d(new QDateTimePrivate)
2269 {
2270 }
2271 
2272 
2279  : d(new QDateTimePrivate)
2280 {
2281  d->date = date;
2282  d->time = QTime(0, 0, 0);
2283 }
2284 
2293  : d(new QDateTimePrivate)
2294 {
2295  d->date = date;
2296  d->time = date.isValid() && !time.isValid() ? QTime(0, 0, 0) : time;
2298 }
2299 
2305  : d(other.d)
2306 {
2307 }
2308 
2313 {
2314 }
2315 
2322 {
2323  d = other.d;
2324  return *this;
2325 }
2326 
2334 bool QDateTime::isNull() const
2335 {
2336  return d->date.isNull() && d->time.isNull();
2337 }
2338 
2347 {
2348  return d->date.isValid() && d->time.isValid();
2349 }
2350 
2358 {
2359  return d->date;
2360 }
2361 
2369 {
2370  return d->time;
2371 }
2372 
2380 {
2381  switch(d->spec)
2382  {
2383  case QDateTimePrivate::UTC:
2384  return Qt::UTC;
2386  return Qt::OffsetFromUTC;
2387  default:
2388  return Qt::LocalTime;
2389  }
2390 }
2391 
2400 {
2401  detach();
2402  d->date = date;
2406  if (date.isValid() && !d->time.isValid())
2407  d->time = QTime(0, 0, 0);
2408 }
2409 
2417 {
2418  detach();
2422  d->time = time;
2423 }
2424 
2432 {
2433  detach();
2434 
2435  switch(spec)
2436  {
2437  case Qt::UTC:
2439  break;
2440  case Qt::OffsetFromUTC:
2442  break;
2443  default:
2445  break;
2446  }
2447 }
2448 
2450 {
2451  qint64 days = jd - JULIAN_DAY_FOR_EPOCH;
2452  qint64 retval = (days * MSECS_PER_DAY) + msecs;
2453  return retval;
2454 }
2455 
2475 {
2476  QDate utcDate;
2477  QTime utcTime;
2478  d->getUTC(utcDate, utcTime);
2479 
2480  return toMSecsSinceEpoch_helper(utcDate.jd, utcTime.ds());
2481 }
2482 
2506 {
2507  qint64 retval = toMSecsSinceEpoch() / 1000;
2508  if (quint64(retval) >= Q_UINT64_C(0xFFFFFFFF))
2509  return uint(-1);
2510  return uint(retval);
2511 }
2512 
2531 {
2532  detach();
2533 
2534  QDateTimePrivate::Spec oldSpec = d->spec;
2535 
2536  int ddays = msecs / MSECS_PER_DAY;
2537  msecs %= MSECS_PER_DAY;
2538  if (msecs < 0) {
2539  // negative
2540  --ddays;
2541  msecs += MSECS_PER_DAY;
2542  }
2543 
2544  d->date = QDate(1970, 1, 1).addDays(ddays);
2545  d->time = QTime().addMSecs(msecs);
2547 
2548  if (oldSpec != QDateTimePrivate::UTC)
2549  d->spec = d->getLocal(d->date, d->time);
2550 }
2551 
2566 void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
2567 {
2568  detach();
2569 
2570  QDateTimePrivate::Spec oldSpec = d->spec;
2571 
2572  d->date = QDate(1970, 1, 1).addDays(secsSince1Jan1970UTC / SECS_PER_DAY);
2573  d->time = QTime().addSecs(secsSince1Jan1970UTC % SECS_PER_DAY);
2575 
2576  if (oldSpec != QDateTimePrivate::UTC)
2577  d->spec = d->getLocal(d->date, d->time);
2578 }
2579 
2580 #ifndef QT_NO_DATESTRING
2581 
2629 {
2630  QString buf;
2631  if (!isValid())
2632  return buf;
2633 
2634  if (f == Qt::ISODate) {
2635  buf = d->date.toString(Qt::ISODate);
2636  if (buf.isEmpty())
2637  return QString(); // failed to convert
2638  buf += QLatin1Char('T');
2639  buf += d->time.toString(Qt::ISODate);
2640  switch (d->spec) {
2641  case QDateTimePrivate::UTC:
2642  buf += QLatin1Char('Z');
2643  break;
2645  int sign = d->utcOffset >= 0 ? 1: -1;
2646  buf += QString::fromLatin1("%1%2:%3").
2647  arg(sign == 1 ? QLatin1Char('+') : QLatin1Char('-')).
2648  arg(d->utcOffset * sign / SECS_PER_HOUR, 2, 10, QLatin1Char('0')).
2649  arg((d->utcOffset / 60) % 60, 2, 10, QLatin1Char('0'));
2650  break;
2651  }
2652  default:
2653  break;
2654  }
2655  }
2656 #ifndef QT_NO_TEXTDATE
2657  else if (f == Qt::TextDate) {
2658 #ifndef Q_WS_WIN
2659  buf = d->date.shortDayName(d->date.dayOfWeek());
2660  buf += QLatin1Char(' ');
2661  buf += d->date.shortMonthName(d->date.month());
2662  buf += QLatin1Char(' ');
2663  buf += QString::number(d->date.day());
2664 #else
2665  wchar_t out[255];
2666  GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255);
2667  QString winstr = QString::fromWCharArray(out);
2668  switch (winstr.toInt()) {
2669  case 1:
2670  buf = d->date.shortDayName(d->date.dayOfWeek());
2671  buf += QLatin1Char(' ');
2672  buf += QString::number(d->date.day());
2673  buf += QLatin1String(". ");
2674  buf += d->date.shortMonthName(d->date.month());
2675  break;
2676  default:
2677  buf = d->date.shortDayName(d->date.dayOfWeek());
2678  buf += QLatin1Char(' ');
2679  buf += d->date.shortMonthName(d->date.month());
2680  buf += QLatin1Char(' ');
2681  buf += QString::number(d->date.day());
2682  }
2683 #endif
2684  buf += QLatin1Char(' ');
2685  buf += d->time.toString();
2686  buf += QLatin1Char(' ');
2687  buf += QString::number(d->date.year());
2688  }
2689 #endif
2690  else {
2691  buf = d->date.toString(f);
2692  if (buf.isEmpty())
2693  return QString(); // failed to convert
2694  buf += QLatin1Char(' ');
2695  buf += d->time.toString(f);
2696  }
2697 
2698  return buf;
2699 }
2700 
2770 {
2771  return fmtDateTime(format, &d->time, &d->date);
2772 }
2773 #endif //QT_NO_DATESTRING
2774 
2784 {
2785  return QDateTime(d->date.addDays(ndays), d->time, timeSpec());
2786 }
2787 
2797 {
2798  return QDateTime(d->date.addMonths(nmonths), d->time, timeSpec());
2799 }
2800 
2810 {
2811  return QDateTime(d->date.addYears(nyears), d->time, timeSpec());
2812 }
2813 
2815 {
2816  QDate utcDate;
2817  QTime utcTime;
2818  dt.d->getUTC(utcDate, utcTime);
2819 
2820  addMSecs(utcDate, utcTime, msecs);
2821 
2822  return QDateTime(utcDate, utcTime, Qt::UTC).toTimeSpec(dt.timeSpec());
2823 }
2824 
2832 void QDateTimePrivate::addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs)
2833 {
2834  uint dd = utcDate.jd;
2835  int tt = utcTime.ds();
2836  int sign = 1;
2837  if (msecs < 0) {
2838  msecs = -msecs;
2839  sign = -1;
2840  }
2841  if (msecs >= int(MSECS_PER_DAY)) {
2842  dd += sign * (msecs / MSECS_PER_DAY);
2843  msecs %= MSECS_PER_DAY;
2844  }
2845 
2846  tt += sign * msecs;
2847  if (tt < 0) {
2848  tt = MSECS_PER_DAY - tt - 1;
2849  dd -= tt / MSECS_PER_DAY;
2850  tt = tt % MSECS_PER_DAY;
2851  tt = MSECS_PER_DAY - tt - 1;
2852  } else if (tt >= int(MSECS_PER_DAY)) {
2853  dd += tt / MSECS_PER_DAY;
2854  tt = tt % MSECS_PER_DAY;
2855  }
2856 
2857  utcDate.jd = dd;
2858  utcTime.mds = tt;
2859 }
2860 
2870 {
2871  return d->addMSecs(*this, qint64(s) * 1000);
2872 }
2873 
2882 {
2883  return d->addMSecs(*this, msecs);
2884 }
2885 
2894 int QDateTime::daysTo(const QDateTime &other) const
2895 {
2896  return d->date.daysTo(other.d->date);
2897 }
2898 
2914 int QDateTime::secsTo(const QDateTime &other) const
2915 {
2916  QDate date1, date2;
2917  QTime time1, time2;
2918 
2919  d->getUTC(date1, time1);
2920  other.d->getUTC(date2, time2);
2921 
2922  return (date1.daysTo(date2) * SECS_PER_DAY) + time1.secsTo(time2);
2923 }
2924 
2943 {
2944  QDate selfDate;
2945  QDate otherDate;
2946  QTime selfTime;
2947  QTime otherTime;
2948 
2949  d->getUTC(selfDate, selfTime);
2950  other.d->getUTC(otherDate, otherTime);
2951 
2952  return (static_cast<qint64>(selfDate.daysTo(otherDate)) * static_cast<qint64>(MSECS_PER_DAY))
2953  + static_cast<qint64>(selfTime.msecsTo(otherTime));
2954 }
2955 
2956 
2970 {
2971  if ((d->spec == QDateTimePrivate::UTC) == (spec == Qt::UTC))
2972  return *this;
2973 
2974  QDateTime ret;
2975  if (spec == Qt::UTC) {
2976  d->getUTC(ret.d->date, ret.d->time);
2977  ret.d->spec = QDateTimePrivate::UTC;
2978  } else {
2979  ret.d->spec = d->getLocal(ret.d->date, ret.d->time);
2980  }
2981  return ret;
2982 }
2983 
2991 bool QDateTime::operator==(const QDateTime &other) const
2992 {
2993  if (d->spec == other.d->spec && d->utcOffset == other.d->utcOffset)
2994  return d->time == other.d->time && d->date == other.d->date;
2995  else {
2996  QDate date1, date2;
2997  QTime time1, time2;
2998 
2999  d->getUTC(date1, time1);
3000  other.d->getUTC(date2, time2);
3001  return time1 == time2 && date1 == date2;
3002  }
3003 }
3004 
3025 bool QDateTime::operator<(const QDateTime &other) const
3026 {
3027  if (d->spec == other.d->spec && d->spec != QDateTimePrivate::OffsetFromUTC) {
3028  if (d->date != other.d->date)
3029  return d->date < other.d->date;
3030  return d->time < other.d->time;
3031  } else {
3032  QDate date1, date2;
3033  QTime time1, time2;
3034  d->getUTC(date1, time1);
3035  other.d->getUTC(date2, time2);
3036  if (date1 != date2)
3037  return date1 < date2;
3038  return time1 < time2;
3039  }
3040 }
3041 
3109 static inline uint msecsFromDecomposed(int hour, int minute, int sec, int msec = 0)
3110 {
3111  return MSECS_PER_HOUR * hour + MSECS_PER_MIN * minute + 1000 * sec + msec;
3112 }
3113 
3114 #if defined(Q_OS_WIN)
3116 {
3117  QDate d;
3118  SYSTEMTIME st;
3119  memset(&st, 0, sizeof(SYSTEMTIME));
3120  GetLocalTime(&st);
3121  d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
3122  return d;
3123 }
3124 
3126 {
3127  QTime ct;
3128  SYSTEMTIME st;
3129  memset(&st, 0, sizeof(SYSTEMTIME));
3130  GetLocalTime(&st);
3131  ct.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
3132 #if defined(Q_OS_WINCE)
3133  ct.startTick = GetTickCount() % MSECS_PER_DAY;
3134 #endif
3135  return ct;
3136 }
3137 
3139 {
3140  QDate d;
3141  QTime t;
3142  SYSTEMTIME st;
3143  memset(&st, 0, sizeof(SYSTEMTIME));
3144  GetLocalTime(&st);
3145  d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
3146  t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
3147  return QDateTime(d, t);
3148 }
3149 
3151 {
3152  QDate d;
3153  QTime t;
3154  SYSTEMTIME st;
3155  memset(&st, 0, sizeof(SYSTEMTIME));
3156  GetSystemTime(&st);
3157  d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
3158  t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
3159  return QDateTime(d, t, Qt::UTC);
3160 }
3161 
3163 {
3164  QDate d;
3165  QTime t;
3166  SYSTEMTIME st;
3167  memset(&st, 0, sizeof(SYSTEMTIME));
3168  GetSystemTime(&st);
3169 
3170  return msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds) +
3171  qint64(julianDayFromGregorianDate(st.wYear, st.wMonth, st.wDay)
3172  - julianDayFromGregorianDate(1970, 1, 1)) * Q_INT64_C(86400000);
3173 }
3174 
3175 #elif defined(Q_OS_SYMBIAN)
3177 {
3178  QDate d;
3179  TTime localTime;
3180  localTime.HomeTime();
3181  TDateTime localDateTime = localTime.DateTime();
3182  // months and days are zero indexed
3183  d.jd = julianDayFromDate(localDateTime.Year(), localDateTime.Month() + 1, localDateTime.Day() + 1 );
3184  return d;
3185 }
3186 
3188 {
3189  QTime ct;
3190  TTime localTime;
3191  localTime.HomeTime();
3192  TDateTime localDateTime = localTime.DateTime();
3193  ct.mds = msecsFromDecomposed(localDateTime.Hour(), localDateTime.Minute(),
3194  localDateTime.Second(), localDateTime.MicroSecond() / 1000);
3195  return ct;
3196 }
3197 
3199 {
3200  QDate d;
3201  QTime ct;
3202  TTime localTime;
3203  localTime.HomeTime();
3204  TDateTime localDateTime = localTime.DateTime();
3205  // months and days are zero indexed
3206  d.jd = julianDayFromDate(localDateTime.Year(), localDateTime.Month() + 1, localDateTime.Day() + 1);
3207  ct.mds = msecsFromDecomposed(localDateTime.Hour(), localDateTime.Minute(),
3208  localDateTime.Second(), localDateTime.MicroSecond() / 1000);
3209  return QDateTime(d, ct);
3210 }
3211 
3213 {
3214  QDate d;
3215  QTime ct;
3216  TTime gmTime;
3217  gmTime.UniversalTime();
3218  TDateTime gmtDateTime = gmTime.DateTime();
3219  // months and days are zero indexed
3220  d.jd = julianDayFromDate(gmtDateTime.Year(), gmtDateTime.Month() + 1, gmtDateTime.Day() + 1);
3221  ct.mds = msecsFromDecomposed(gmtDateTime.Hour(), gmtDateTime.Minute(),
3222  gmtDateTime.Second(), gmtDateTime.MicroSecond() / 1000);
3223  return QDateTime(d, ct, Qt::UTC);
3224 }
3225 
3227 {
3228  QDate d;
3229  QTime ct;
3230  TTime gmTime;
3231  gmTime.UniversalTime();
3232  TDateTime gmtDateTime = gmTime.DateTime();
3233 
3234  // according to the documentation, the value is:
3235  // "a date and time as a number of microseconds since midnight, January 1st, 0 AD nominal Gregorian"
3236  qint64 value = gmTime.Int64();
3237 
3238  // whereas 1970-01-01T00:00:00 is (in the same representation):
3239  // ((1970 * 365) + (1970 / 4) - (1970 / 100) + (1970 / 400) - 13) * 86400 * 1000000
3240  static const qint64 unixEpoch = Q_INT64_C(0xdcddb30f2f8000);
3241 
3242  return (value - unixEpoch) / 1000;
3243 }
3244 
3245 #elif defined(Q_OS_UNIX)
3247 {
3248  QDate d;
3249  // posix compliant system
3250  time_t ltime;
3251  time(&ltime);
3252  struct tm *t = 0;
3253 
3254 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3255  // use the reentrant version of localtime() where available
3256  tzset();
3257  struct tm res;
3258  t = localtime_r(&ltime, &res);
3259 #else
3260  t = localtime(&ltime);
3261 #endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
3262 
3263  d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
3264  return d;
3265 }
3266 
3268 {
3269  QTime ct;
3270  // posix compliant system
3271  struct timeval tv;
3272  gettimeofday(&tv, 0);
3273  time_t ltime = tv.tv_sec;
3274  struct tm *t = 0;
3275 
3276 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3277  // use the reentrant version of localtime() where available
3278  tzset();
3279  struct tm res;
3280  t = localtime_r(&ltime, &res);
3281 #else
3282  t = localtime(&ltime);
3283 #endif
3284  Q_CHECK_PTR(t);
3285 
3286  ct.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
3287  return ct;
3288 }
3289 
3291 {
3292  // posix compliant system
3293  // we have milliseconds
3294  struct timeval tv;
3295  gettimeofday(&tv, 0);
3296  time_t ltime = tv.tv_sec;
3297  struct tm *t = 0;
3298 
3299 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3300  // use the reentrant version of localtime() where available
3301  tzset();
3302  struct tm res;
3303  t = localtime_r(&ltime, &res);
3304 #else
3305  t = localtime(&ltime);
3306 #endif
3307 
3308  QDateTime dt;
3309  dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
3310 
3311  dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
3312  dt.d->spec = t->tm_isdst > 0 ? QDateTimePrivate::LocalDST :
3313  t->tm_isdst == 0 ? QDateTimePrivate::LocalStandard :
3315  return dt;
3316 }
3317 
3319 {
3320  // posix compliant system
3321  // we have milliseconds
3322  struct timeval tv;
3323  gettimeofday(&tv, 0);
3324  time_t ltime = tv.tv_sec;
3325  struct tm *t = 0;
3326 
3327 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
3328  // use the reentrant version of localtime() where available
3329  struct tm res;
3330  t = gmtime_r(&ltime, &res);
3331 #else
3332  t = gmtime(&ltime);
3333 #endif
3334 
3335  QDateTime dt;
3336  dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);
3337 
3338  dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
3340  return dt;
3341 }
3342 
3344 {
3345  // posix compliant system
3346  // we have milliseconds
3347  struct timeval tv;
3348  gettimeofday(&tv, 0);
3349  return qint64(tv.tv_sec) * Q_INT64_C(1000) + tv.tv_usec / 1000;
3350 }
3351 
3352 #else
3353 #error "What system is this?"
3354 #endif
3355 
3370 {
3371  QDateTime d;
3372  d.setTime_t(seconds);
3373  return d;
3374 }
3375 
3394 {
3395  QDateTime d;
3396  d.setMSecsSinceEpoch(msecs);
3397  return d;
3398 }
3399 
3416 void QDateTime::setUtcOffset(int seconds)
3417 {
3418  detach();
3419 
3420  /* The motivation to also setting d->spec is to ensure that the QDateTime
3421  * instance stay in well-defined states all the time, instead of that
3422  * we instruct the user to ensure it. */
3423  if(seconds == 0)
3425  else
3427 
3428  /* Even if seconds is 0 we assign it to utcOffset. */
3429  d->utcOffset = seconds;
3430 }
3431 
3450 {
3452  return d->utcOffset;
3453  else
3454  return 0;
3455 }
3456 
3457 #ifndef QT_NO_DATESTRING
3458 
3459 static int fromShortMonthName(const QString &monthName)
3460 {
3461  // Assume that English monthnames are the default
3462  for (int i = 0; i < 12; ++i) {
3463  if (monthName == QLatin1String(qt_shortMonthNames[i]))
3464  return i + 1;
3465  }
3466  // If English names can't be found, search the localized ones
3467  for (int i = 1; i <= 12; ++i) {
3468  if (monthName == QDate::shortMonthName(i))
3469  return i;
3470  }
3471  return -1;
3472 }
3473 
3488 {
3489  if (s.isEmpty()) {
3490  return QDateTime();
3491  }
3492 
3493  switch (f) {
3494  case Qt::ISODate: {
3495  QString tmp = s;
3497  const QDate date = QDate::fromString(tmp.left(10), Qt::ISODate);
3498  if (tmp.size() == 10)
3499  return QDateTime(date);
3500 
3501  tmp = tmp.mid(11);
3502 
3503  // Recognize UTC specifications
3504  if (tmp.endsWith(QLatin1Char('Z'))) {
3505  ts = Qt::UTC;
3506  tmp.chop(1);
3507  }
3508 
3509  // Recognize timezone specifications
3510  QRegExp rx(QLatin1String("[+-]"));
3511  if (tmp.contains(rx)) {
3512  int idx = tmp.indexOf(rx);
3513  QString tmp2 = tmp.mid(idx);
3514  tmp = tmp.left(idx);
3515  bool ok = true;
3516  int ntzhour = 1;
3517  int ntzminute = 3;
3518  if ( tmp2.indexOf(QLatin1Char(':')) == 3 )
3519  ntzminute = 4;
3520  const int tzhour(tmp2.mid(ntzhour, 2).toInt(&ok));
3521  const int tzminute(tmp2.mid(ntzminute, 2).toInt(&ok));
3522  QTime tzt(tzhour, tzminute);
3523  int utcOffset = (tzt.hour() * 60 + tzt.minute()) * 60;
3524  if ( utcOffset != 0 ) {
3525  ts = Qt::OffsetFromUTC;
3526  QDateTime dt(date, QTime::fromString(tmp, Qt::ISODate), ts);
3527  dt.setUtcOffset( utcOffset * (tmp2.startsWith(QLatin1Char('-')) ? -1 : 1) );
3528  return dt;
3529  }
3530  }
3531  return QDateTime(date, QTime::fromString(tmp, Qt::ISODate), ts);
3532  }
3533  case Qt::SystemLocaleDate:
3538  case Qt::LocaleDate:
3541  return fromString(s, QLocale().dateTimeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat
3542  : QLocale::ShortFormat));
3543 #if !defined(QT_NO_TEXTDATE)
3544  case Qt::TextDate: {
3546 
3547  if ((parts.count() < 5) || (parts.count() > 6)) {
3548  return QDateTime();
3549  }
3550 
3551  // Accept "Sun Dec 1 13:02:00 1974" and "Sun 1. Dec 13:02:00 1974"
3552  int month = -1, day = -1;
3553  bool ok;
3554 
3555  month = fromShortMonthName(parts.at(1));
3556  if (month != -1) {
3557  day = parts.at(2).toInt(&ok);
3558  if (!ok)
3559  day = -1;
3560  }
3561 
3562  if (month == -1 || day == -1) {
3563  // first variant failed, lets try the other
3564  month = fromShortMonthName(parts.at(2));
3565  if (month != -1) {
3566  QString dayStr = parts.at(1);
3567  if (dayStr.endsWith(QLatin1Char('.'))) {
3568  dayStr.chop(1);
3569  day = dayStr.toInt(&ok);
3570  if (!ok)
3571  day = -1;
3572  } else {
3573  day = -1;
3574  }
3575  }
3576  }
3577 
3578  if (month == -1 || day == -1) {
3579  // both variants failed, give up
3580  return QDateTime();
3581  }
3582 
3583  int year;
3584  QStringList timeParts = parts.at(3).split(QLatin1Char(':'));
3585  if ((timeParts.count() == 3) || (timeParts.count() == 2)) {
3586  year = parts.at(4).toInt(&ok);
3587  if (!ok)
3588  return QDateTime();
3589  } else {
3590  timeParts = parts.at(4).split(QLatin1Char(':'));
3591  if ((timeParts.count() != 3) && (timeParts.count() != 2))
3592  return QDateTime();
3593  year = parts.at(3).toInt(&ok);
3594  if (!ok)
3595  return QDateTime();
3596  }
3597 
3598  int hour = timeParts.at(0).toInt(&ok);
3599  if (!ok) {
3600  return QDateTime();
3601  }
3602 
3603  int minute = timeParts.at(1).toInt(&ok);
3604  if (!ok) {
3605  return QDateTime();
3606  }
3607 
3608  int second = (timeParts.count() > 2) ? timeParts.at(2).toInt(&ok) : 0;
3609  if (!ok) {
3610  return QDateTime();
3611  }
3612 
3613  QDate date(year, month, day);
3614  QTime time(hour, minute, second);
3615 
3616  if (parts.count() == 5)
3617  return QDateTime(date, time, Qt::LocalTime);
3618 
3619  QString tz = parts.at(5);
3620  if (!tz.startsWith(QLatin1String("GMT"), Qt::CaseInsensitive))
3621  return QDateTime();
3622  QDateTime dt(date, time, Qt::UTC);
3623  if (tz.length() > 3) {
3624  int tzoffset = 0;
3625  QChar sign = tz.at(3);
3626  if ((sign != QLatin1Char('+'))
3627  && (sign != QLatin1Char('-'))) {
3628  return QDateTime();
3629  }
3630  int tzhour = tz.mid(4, 2).toInt(&ok);
3631  if (!ok)
3632  return QDateTime();
3633  int tzminute = tz.mid(6).toInt(&ok);
3634  if (!ok)
3635  return QDateTime();
3636  tzoffset = (tzhour*60 + tzminute) * 60;
3637  if (sign == QLatin1Char('-'))
3638  tzoffset = -tzoffset;
3639  dt.setUtcOffset(tzoffset);
3640  }
3641  return dt.toLocalTime();
3642  }
3643 #endif //QT_NO_TEXTDATE
3644  }
3645 
3646  return QDateTime();
3647 }
3648 
3749 {
3750 #ifndef QT_BOOTSTRAPPED
3751  QTime time;
3752  QDate date;
3753 
3755  if (dt.parseFormat(format) && dt.fromString(string, &date, &time))
3756  return QDateTime(date, time);
3757 #else
3758  Q_UNUSED(string);
3759  Q_UNUSED(format);
3760 #endif
3761  return QDateTime(QDate(), QTime(-1, -1, -1));
3762 }
3763 
3764 #endif // QT_NO_DATESTRING
3765 
3792 {
3793  d.detach();
3794 }
3795 
3796 /*****************************************************************************
3797  Date/time stream functions
3798  *****************************************************************************/
3799 
3800 #ifndef QT_NO_DATASTREAM
3801 
3813 {
3814  return out << (quint32)(date.jd);
3815 }
3816 
3829 {
3830  quint32 jd;
3831  in >> jd;
3832  date.jd = jd;
3833  return in;
3834 }
3835 
3848 {
3849  return out << quint32(time.mds);
3850 }
3851 
3864 {
3865  quint32 ds;
3866  in >> ds;
3867  time.mds = int(ds);
3868  return in;
3869 }
3870 
3882 {
3883  out << dateTime.d->date << dateTime.d->time;
3884  if (out.version() >= 7)
3885  out << (qint8)dateTime.d->spec;
3886  return out;
3887 }
3888 
3901 {
3902  dateTime.detach();
3903 
3905  in >> dateTime.d->date >> dateTime.d->time;
3906  if (in.version() >= 7)
3907  in >> ts;
3908  dateTime.d->spec = (QDateTimePrivate::Spec)ts;
3909  return in;
3910 }
3911 #endif // QT_NO_DATASTREAM
3912 
3913 
4004 // checks if there is an unqoted 'AP' or 'ap' in the string
4005 static bool hasUnquotedAP(const QString &f)
4006 {
4007  const QLatin1Char quote('\'');
4008  bool inquote = false;
4009  const int max = f.size();
4010  for (int i=0; i<max; ++i) {
4011  if (f.at(i) == quote) {
4012  inquote = !inquote;
4013  } else if (!inquote && f.at(i).toUpper() == QLatin1Char('A')) {
4014  return true;
4015  }
4016  }
4017  return false;
4018 }
4019 
4020 #ifndef QT_NO_DATESTRING
4021 /*****************************************************************************
4022  Some static function used by QDate, QTime and QDateTime
4023 *****************************************************************************/
4024 
4025 // Replaces tokens by their value. See QDateTime::toString() for a list of valid tokens
4026 static QString getFmtString(const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = false)
4027 {
4028  if (f.isEmpty())
4029  return QString();
4030 
4031  QString buf = f;
4032  int removed = 0;
4033 
4034  if (dt) {
4035  if (f.startsWith(QLatin1String("hh")) || f.startsWith(QLatin1String("HH"))) {
4036  const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
4037  if (hour12 && dt->hour() > 12)
4038  buf = QString::number(dt->hour() - 12).rightJustified(2, QLatin1Char('0'), true);
4039  else if (hour12 && dt->hour() == 0)
4040  buf = QLatin1String("12");
4041  else
4042  buf = QString::number(dt->hour()).rightJustified(2, QLatin1Char('0'), true);
4043  removed = 2;
4044  } else if (f.at(0) == QLatin1Char('h') || f.at(0) == QLatin1Char('H')) {
4045  const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
4046  if (hour12 && dt->hour() > 12)
4047  buf = QString::number(dt->hour() - 12);
4048  else if (hour12 && dt->hour() == 0)
4049  buf = QLatin1String("12");
4050  else
4051  buf = QString::number(dt->hour());
4052  removed = 1;
4053  } else if (f.startsWith(QLatin1String("mm"))) {
4054  buf = QString::number(dt->minute()).rightJustified(2, QLatin1Char('0'), true);
4055  removed = 2;
4056  } else if (f.at(0) == (QLatin1Char('m'))) {
4057  buf = QString::number(dt->minute());
4058  removed = 1;
4059  } else if (f.startsWith(QLatin1String("ss"))) {
4060  buf = QString::number(dt->second()).rightJustified(2, QLatin1Char('0'), true);
4061  removed = 2;
4062  } else if (f.at(0) == QLatin1Char('s')) {
4063  buf = QString::number(dt->second());
4064  } else if (f.startsWith(QLatin1String("zzz"))) {
4065  buf = QString::number(dt->msec()).rightJustified(3, QLatin1Char('0'), true);
4066  removed = 3;
4067  } else if (f.at(0) == QLatin1Char('z')) {
4068  buf = QString::number(dt->msec());
4069  removed = 1;
4070  } else if (f.at(0).toUpper() == QLatin1Char('A')) {
4071  const bool upper = f.at(0) == QLatin1Char('A');
4072  buf = dt->hour() < 12 ? QLatin1String("am") : QLatin1String("pm");
4073  if (upper)
4074  buf = buf.toUpper();
4075  if (f.size() > 1 && f.at(1).toUpper() == QLatin1Char('P') &&
4076  f.at(0).isUpper() == f.at(1).isUpper()) {
4077  removed = 2;
4078  } else {
4079  removed = 1;
4080  }
4081  }
4082  }
4083 
4084  if (dd) {
4085  if (f.startsWith(QLatin1String("dddd"))) {
4086  buf = dd->longDayName(dd->dayOfWeek());
4087  removed = 4;
4088  } else if (f.startsWith(QLatin1String("ddd"))) {
4089  buf = dd->shortDayName(dd->dayOfWeek());
4090  removed = 3;
4091  } else if (f.startsWith(QLatin1String("dd"))) {
4092  buf = QString::number(dd->day()).rightJustified(2, QLatin1Char('0'), true);
4093  removed = 2;
4094  } else if (f.at(0) == QLatin1Char('d')) {
4095  buf = QString::number(dd->day());
4096  removed = 1;
4097  } else if (f.startsWith(QLatin1String("MMMM"))) {
4098  buf = dd->longMonthName(dd->month());
4099  removed = 4;
4100  } else if (f.startsWith(QLatin1String("MMM"))) {
4101  buf = dd->shortMonthName(dd->month());
4102  removed = 3;
4103  } else if (f.startsWith(QLatin1String("MM"))) {
4104  buf = QString::number(dd->month()).rightJustified(2, QLatin1Char('0'), true);
4105  removed = 2;
4106  } else if (f.at(0) == QLatin1Char('M')) {
4107  buf = QString::number(dd->month());
4108  removed = 1;
4109  } else if (f.startsWith(QLatin1String("yyyy"))) {
4110  const int year = dd->year();
4111  buf = QString::number(qAbs(year)).rightJustified(4, QLatin1Char('0'));
4112  if(year > 0)
4113  removed = 4;
4114  else
4115  {
4116  buf.prepend(QLatin1Char('-'));
4117  removed = 5;
4118  }
4119 
4120  } else if (f.startsWith(QLatin1String("yy"))) {
4121  buf = QString::number(dd->year()).right(2).rightJustified(2, QLatin1Char('0'));
4122  removed = 2;
4123  }
4124  }
4125  if (removed == 0 || removed >= f.size()) {
4126  return buf;
4127  }
4128 
4129  return buf + getFmtString(f.mid(removed), dt, dd, am_pm);
4130 }
4131 
4132 // Parses the format string and uses getFmtString to get the values for the tokens. Ret
4133 static QString fmtDateTime(const QString& f, const QTime* dt, const QDate* dd)
4134 {
4135  const QLatin1Char quote('\'');
4136  if (f.isEmpty())
4137  return QString();
4138  if (dt && !dt->isValid())
4139  return QString();
4140  if (dd && !dd->isValid())
4141  return QString();
4142 
4143  const bool ap = hasUnquotedAP(f);
4144 
4145  QString buf;
4146  QString frm;
4147  QChar status(QLatin1Char('0'));
4148 
4149  for (int i = 0; i < (int)f.length(); ++i) {
4150  if (f.at(i) == quote) {
4151  if (status == quote) {
4152  if (i > 0 && f.at(i - 1) == quote)
4153  buf += QLatin1Char('\'');
4154  status = QLatin1Char('0');
4155  } else {
4156  if (!frm.isEmpty()) {
4157  buf += getFmtString(frm, dt, dd, ap);
4158  frm.clear();
4159  }
4160  status = quote;
4161  }
4162  } else if (status == quote) {
4163  buf += f.at(i);
4164  } else if (f.at(i) == status) {
4165  if ((ap) && ((f.at(i) == QLatin1Char('P')) || (f.at(i) == QLatin1Char('p'))))
4166  status = QLatin1Char('0');
4167  frm += f.at(i);
4168  } else {
4169  buf += getFmtString(frm, dt, dd, ap);
4170  frm.clear();
4171  if ((f.at(i) == QLatin1Char('h')) || (f.at(i) == QLatin1Char('m'))
4172  || (f.at(i) == QLatin1Char('H'))
4173  || (f.at(i) == QLatin1Char('s')) || (f.at(i) == QLatin1Char('z'))) {
4174  status = f.at(i);
4175  frm += f.at(i);
4176  } else if ((f.at(i) == QLatin1Char('d')) || (f.at(i) == QLatin1Char('M')) || (f.at(i) == QLatin1Char('y'))) {
4177  status = f.at(i);
4178  frm += f.at(i);
4179  } else if ((ap) && (f.at(i) == QLatin1Char('A'))) {
4180  status = QLatin1Char('P');
4181  frm += f.at(i);
4182  } else if((ap) && (f.at(i) == QLatin1Char('a'))) {
4183  status = QLatin1Char('p');
4184  frm += f.at(i);
4185  } else {
4186  buf += f.at(i);
4187  status = QLatin1Char('0');
4188  }
4189  }
4190  }
4191 
4192  buf += getFmtString(frm, dt, dd, ap);
4193 
4194  return buf;
4195 }
4196 #endif // QT_NO_DATESTRING
4197 
4198 #ifdef Q_OS_WIN
4199 static const int LowerYear = 1980;
4200 #else
4201 static const int LowerYear = 1970;
4202 #endif
4203 static const int UpperYear = 2037;
4204 
4206 {
4207  QDate lowerLimit(LowerYear, 1, 2);
4208  QDate upperLimit(UpperYear, 12, 30);
4209 
4210  if (date > lowerLimit && date < upperLimit)
4211  return date;
4212 
4213  int month = date.month();
4214  int day = date.day();
4215 
4216  // neither 1970 nor 2037 are leap years, so make sure date isn't Feb 29
4217  if (month == 2 && day == 29)
4218  --day;
4219 
4220  if (date < lowerLimit)
4221  date.setDate(LowerYear, month, day);
4222  else
4223  date.setDate(UpperYear, month, day);
4224 
4225  return date;
4226 }
4227 
4229 {
4230  QDate fakeDate = adjustDate(date);
4231 
4232  // won't overflow because of fakeDate
4233  time_t secsSince1Jan1970UTC = toMSecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime().msecsTo(time)) / 1000;
4234  tm *brokenDown = 0;
4235 
4236 #if defined(Q_OS_WINCE)
4237  tm res;
4238  FILETIME utcTime = time_tToFt(secsSince1Jan1970UTC);
4239  FILETIME resultTime;
4240  FileTimeToLocalFileTime(&utcTime , &resultTime);
4241  SYSTEMTIME sysTime;
4242  FileTimeToSystemTime(&resultTime , &sysTime);
4243 
4244  res.tm_sec = sysTime.wSecond;
4245  res.tm_min = sysTime.wMinute;
4246  res.tm_hour = sysTime.wHour;
4247  res.tm_mday = sysTime.wDay;
4248  res.tm_mon = sysTime.wMonth - 1;
4249  res.tm_year = sysTime.wYear - 1900;
4250  brokenDown = &res;
4251 #elif defined(Q_OS_SYMBIAN)
4252  // months and days are zero index based
4253  _LIT(KUnixEpoch, "19700000:000000.000000");
4254  TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC);
4255  TTime epochTTime;
4256  TInt err = epochTTime.Set(KUnixEpoch);
4257  tm res;
4258  if(err == KErrNone) {
4259  TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC;
4260  CTrapCleanup *cleanup = CTrapCleanup::New(); // needed to avoid crashes in apps that previously were able to use this function in static data initialization
4261  TRAP(err,
4262  RTz tz;
4263  User::LeaveIfError(tz.Connect());
4264  CleanupClosePushL(tz);
4265  CTzId *tzId = tz.GetTimeZoneIdL();
4266  CleanupStack::PushL(tzId);
4267  res.tm_isdst = tz.IsDaylightSavingOnL(*tzId,utcTTime);
4268  User::LeaveIfError(tz.ConvertToLocalTime(utcTTime));
4269  CleanupStack::PopAndDestroy(tzId);
4270  CleanupStack::PopAndDestroy(&tz));
4271  delete cleanup;
4272  if (KErrNone == err) {
4273  TDateTime localDateTime = utcTTime.DateTime();
4274  res.tm_sec = localDateTime.Second();
4275  res.tm_min = localDateTime.Minute();
4276  res.tm_hour = localDateTime.Hour();
4277  res.tm_mday = localDateTime.Day() + 1; // non-zero based index for tm struct
4278  res.tm_mon = localDateTime.Month();
4279  res.tm_year = localDateTime.Year() - 1900;
4280  // Symbian's timezone server doesn't know how to handle DST before year 1997
4281  if (res.tm_year < 97)
4282  res.tm_isdst = -1;
4283  brokenDown = &res;
4284  }
4285  }
4286 #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
4287  // use the reentrant version of localtime() where available
4288  tzset();
4289  tm res;
4290  brokenDown = localtime_r(&secsSince1Jan1970UTC, &res);
4291 #elif defined(_MSC_VER) && _MSC_VER >= 1400
4292  tm res;
4293  if (!_localtime64_s(&res, &secsSince1Jan1970UTC))
4294  brokenDown = &res;
4295 #else
4296  brokenDown = localtime(&secsSince1Jan1970UTC);
4297 #endif
4298  if (!brokenDown) {
4299  date = QDate(1970, 1, 1);
4300  time = QTime();
4302  } else {
4303  int deltaDays = fakeDate.daysTo(date);
4304  date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
4305  time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());
4306  date = date.addDays(deltaDays);
4307  if (brokenDown->tm_isdst > 0)
4309  else if (brokenDown->tm_isdst < 0)
4311  else
4313  }
4314 }
4315 
4316 static void localToUtc(QDate &date, QTime &time, int isdst)
4317 {
4318  if (!date.isValid())
4319  return;
4320 
4321  QDate fakeDate = adjustDate(date);
4322 
4323  tm localTM;
4324  localTM.tm_sec = time.second();
4325  localTM.tm_min = time.minute();
4326  localTM.tm_hour = time.hour();
4327  localTM.tm_mday = fakeDate.day();
4328  localTM.tm_mon = fakeDate.month() - 1;
4329  localTM.tm_year = fakeDate.year() - 1900;
4330  localTM.tm_isdst = (int)isdst;
4331 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
4332  time_t secsSince1Jan1970UTC = (toMSecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime().msecsTo(time)) / 1000);
4333 #else
4334 #if defined(Q_OS_WIN)
4335  _tzset();
4336 #endif
4337  time_t secsSince1Jan1970UTC = mktime(&localTM);
4338 #ifdef Q_OS_QNX
4339  //mktime sometimes fails on QNX. Following workaround converts the date and time then manually
4340  if (secsSince1Jan1970UTC == (time_t)-1) {
4341  QDateTime tempTime = QDateTime(date, time, Qt::UTC);;
4342  tempTime = tempTime.addMSecs(timezone * 1000);
4343  date = tempTime.date();
4344  time = tempTime.time();
4345  return;
4346  }
4347 #endif
4348 #endif
4349  tm *brokenDown = 0;
4350 #if defined(Q_OS_WINCE)
4351  tm res;
4352  FILETIME localTime = time_tToFt(secsSince1Jan1970UTC);
4353  SYSTEMTIME sysTime;
4354  FileTimeToSystemTime(&localTime, &sysTime);
4355  FILETIME resultTime;
4356  LocalFileTimeToFileTime(&localTime , &resultTime);
4357  FileTimeToSystemTime(&resultTime , &sysTime);
4358  res.tm_sec = sysTime.wSecond;
4359  res.tm_min = sysTime.wMinute;
4360  res.tm_hour = sysTime.wHour;
4361  res.tm_mday = sysTime.wDay;
4362  res.tm_mon = sysTime.wMonth - 1;
4363  res.tm_year = sysTime.wYear - 1900;
4364  res.tm_isdst = (int)isdst;
4365  brokenDown = &res;
4366 #elif defined(Q_OS_SYMBIAN)
4367  // months and days are zero index based
4368  _LIT(KUnixEpoch, "19700000:000000.000000");
4369  TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC);
4370  TTime epochTTime;
4371  TInt err = epochTTime.Set(KUnixEpoch);
4372  tm res;
4373  if(err == KErrNone) {
4374  TTime localTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC;
4375  RTz tz;
4376  if (KErrNone == tz.Connect()) {
4377  if (KErrNone == tz.ConvertToUniversalTime(localTTime)) {
4378  TDateTime utcDateTime = localTTime.DateTime();
4379  res.tm_sec = utcDateTime.Second();
4380  res.tm_min = utcDateTime.Minute();
4381  res.tm_hour = utcDateTime.Hour();
4382  res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct
4383  res.tm_mon = utcDateTime.Month();
4384  res.tm_year = utcDateTime.Year() - 1900;
4385  res.tm_isdst = (int)isdst;
4386  brokenDown = &res;
4387  }
4388  tz.Close();
4389  }
4390  }
4391 #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
4392  // use the reentrant version of gmtime() where available
4393  tm res;
4394  brokenDown = gmtime_r(&secsSince1Jan1970UTC, &res);
4395 #elif defined(_MSC_VER) && _MSC_VER >= 1400
4396  tm res;
4397  if (!_gmtime64_s(&res, &secsSince1Jan1970UTC))
4398  brokenDown = &res;
4399 #else
4400  brokenDown = gmtime(&secsSince1Jan1970UTC);
4401 #endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS
4402  if (!brokenDown) {
4403  date = QDate(1970, 1, 1);
4404  time = QTime();
4405  } else {
4406  int deltaDays = fakeDate.daysTo(date);
4407  date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
4408  time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());
4409  date = date.addDays(deltaDays);
4410  }
4411 }
4412 
4414 {
4415  outDate = date;
4416  outTime = time;
4417  if (spec == QDateTimePrivate::UTC)
4418  return utcToLocal(outDate, outTime);
4419  return spec;
4420 }
4421 
4422 void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const
4423 {
4424  outDate = date;
4425  outTime = time;
4426  const bool isOffset = spec == QDateTimePrivate::OffsetFromUTC;
4427 
4428  if (spec != QDateTimePrivate::UTC && !isOffset)
4429  localToUtc(outDate, outTime, (int)spec);
4430 
4431  if (isOffset)
4432  addMSecs(outDate, outTime, -(qint64(utcOffset) * 1000));
4433 }
4434 
4435 #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)
4437 {
4438  dbg.nospace() << "QDate(" << date.toString() << ')';
4439  return dbg.space();
4440 }
4441 
4443 {
4444  dbg.nospace() << "QTime(" << time.toString() << ')';
4445  return dbg.space();
4446 }
4447 
4449 {
4450  dbg.nospace() << "QDateTime(" << date.toString() << ')';
4451  return dbg.space();
4452 }
4453 #endif
4454 
4455 #ifndef QT_BOOTSTRAPPED
4456 
4470 {
4471  if (index < 0 || index >= sectionNodes.size()) {
4472 #ifndef QT_NO_DATESTRING
4473  qWarning("QDateTimeParser::getDigit() Internal error (%s %d)",
4474  qPrintable(t.toString()), index);
4475 #else
4476  qWarning("QDateTimeParser::getDigit() Internal error (%d)", index);
4477 #endif
4478  return -1;
4479  }
4480  const SectionNode &node = sectionNodes.at(index);
4481  switch (node.type) {
4482  case Hour24Section: case Hour12Section: return t.time().hour();
4483  case MinuteSection: return t.time().minute();
4484  case SecondSection: return t.time().second();
4485  case MSecSection: return t.time().msec();
4486  case YearSection2Digits:
4487  case YearSection: return t.date().year();
4488  case MonthSection: return t.date().month();
4489  case DaySection: return t.date().day();
4490  case DayOfWeekSection: return t.date().day();
4491  case AmPmSection: return t.time().hour() > 11 ? 1 : 0;
4492 
4493  default: break;
4494  }
4495 
4496 #ifndef QT_NO_DATESTRING
4497  qWarning("QDateTimeParser::getDigit() Internal error 2 (%s %d)",
4498  qPrintable(t.toString()), index);
4499 #else
4500  qWarning("QDateTimeParser::getDigit() Internal error 2 (%d)", index);
4501 #endif
4502  return -1;
4503 }
4504 
4520 bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
4521 {
4522  if (index < 0 || index >= sectionNodes.size()) {
4523 #ifndef QT_NO_DATESTRING
4524  qWarning("QDateTimeParser::setDigit() Internal error (%s %d %d)",
4525  qPrintable(v.toString()), index, newVal);
4526 #else
4527  qWarning("QDateTimeParser::setDigit() Internal error (%d %d)", index, newVal);
4528 #endif
4529  return false;
4530  }
4531  const SectionNode &node = sectionNodes.at(index);
4532 
4533  int year, month, day, hour, minute, second, msec;
4534  year = v.date().year();
4535  month = v.date().month();
4536  day = v.date().day();
4537  hour = v.time().hour();
4538  minute = v.time().minute();
4539  second = v.time().second();
4540  msec = v.time().msec();
4541 
4542  switch (node.type) {
4543  case Hour24Section: case Hour12Section: hour = newVal; break;
4544  case MinuteSection: minute = newVal; break;
4545  case SecondSection: second = newVal; break;
4546  case MSecSection: msec = newVal; break;
4547  case YearSection2Digits:
4548  case YearSection: year = newVal; break;
4549  case MonthSection: month = newVal; break;
4550  case DaySection:
4551  case DayOfWeekSection:
4552  if (newVal > 31) {
4553  // have to keep legacy behavior. setting the
4554  // date to 32 should return false. Setting it
4555  // to 31 for february should return true
4556  return false;
4557  }
4558  day = newVal;
4559  break;
4560  case AmPmSection: hour = (newVal == 0 ? hour % 12 : (hour % 12) + 12); break;
4561  default:
4562  qWarning("QDateTimeParser::setDigit() Internal error (%s)",
4563  qPrintable(sectionName(node.type)));
4564  break;
4565  }
4566 
4567  if (!(node.type & (DaySection|DayOfWeekSection))) {
4568  if (day < cachedDay)
4569  day = cachedDay;
4570  const int max = QDate(year, month, 1).daysInMonth();
4571  if (day > max) {
4572  day = max;
4573  }
4574  }
4575  if (QDate::isValid(year, month, day) && QTime::isValid(hour, minute, second, msec)) {
4576  v = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);
4577  return true;
4578  }
4579  return false;
4580 }
4581 
4582 
4583 
4590 int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
4591 {
4592  const SectionNode &sn = sectionNode(s);
4593  switch (sn.type) {
4594  case Hour24Section:
4595  case Hour12Section: return 23; // this is special-cased in
4596  // parseSection. We want it to be
4597  // 23 for the stepBy case.
4598  case MinuteSection:
4599  case SecondSection: return 59;
4600  case MSecSection: return 999;
4601  case YearSection2Digits:
4602  case YearSection: return 9999; // sectionMaxSize will prevent
4603  // people from typing in a larger
4604  // number in count == 2 sections.
4605  // stepBy() will work on real years anyway
4606  case MonthSection: return 12;
4607  case DaySection:
4608  case DayOfWeekSection: return cur.isValid() ? cur.date().daysInMonth() : 31;
4609  case AmPmSection: return 1;
4610  default: break;
4611  }
4612  qWarning("QDateTimeParser::absoluteMax() Internal error (%s)",
4613  qPrintable(sectionName(sn.type)));
4614  return -1;
4615 }
4616 
4624 {
4625  const SectionNode &sn = sectionNode(s);
4626  switch (sn.type) {
4627  case Hour24Section:
4628  case Hour12Section:
4629  case MinuteSection:
4630  case SecondSection:
4631  case MSecSection:
4632  case YearSection2Digits:
4633  case YearSection: return 0;
4634  case MonthSection:
4635  case DaySection:
4636  case DayOfWeekSection: return 1;
4637  case AmPmSection: return 0;
4638  default: break;
4639  }
4640  qWarning("QDateTimeParser::absoluteMin() Internal error (%s, %0x)",
4641  qPrintable(sectionName(sn.type)), sn.type);
4642  return -1;
4643 }
4644 
4655 {
4656  if (sectionIndex < 0) {
4657  switch (sectionIndex) {
4658  case FirstSectionIndex:
4659  return first;
4660  case LastSectionIndex:
4661  return last;
4662  case NoSectionIndex:
4663  return none;
4664  }
4665  } else if (sectionIndex < sectionNodes.size()) {
4666  return sectionNodes.at(sectionIndex);
4667  }
4668 
4669  qWarning("QDateTimeParser::sectionNode() Internal error (%d)",
4670  sectionIndex);
4671  return none;
4672 }
4673 
4675 {
4676  return sectionNode(sectionIndex).type;
4677 }
4678 
4679 
4689 int QDateTimeParser::sectionPos(int sectionIndex) const
4690 {
4691  return sectionPos(sectionNode(sectionIndex));
4692 }
4693 
4695 {
4696  switch (sn.type) {
4697  case FirstSection: return 0;
4698  case LastSection: return displayText().size() - 1;
4699  default: break;
4700  }
4701  if (sn.pos == -1) {
4702  qWarning("QDateTimeParser::sectionPos Internal error (%s)", qPrintable(sectionName(sn.type)));
4703  return -1;
4704  }
4705  return sn.pos;
4706 }
4707 
4708 
4715 static QString unquote(const QString &str)
4716 {
4717  const QChar quote(QLatin1Char('\''));
4718  const QChar slash(QLatin1Char('\\'));
4719  const QChar zero(QLatin1Char('0'));
4720  QString ret;
4721  QChar status(zero);
4722  const int max = str.size();
4723  for (int i=0; i<max; ++i) {
4724  if (str.at(i) == quote) {
4725  if (status != quote) {
4726  status = quote;
4727  } else if (!ret.isEmpty() && str.at(i - 1) == slash) {
4728  ret[ret.size() - 1] = quote;
4729  } else {
4730  status = zero;
4731  }
4732  } else {
4733  ret += str.at(i);
4734  }
4735  }
4736  return ret;
4737 }
4749 static inline int countRepeat(const QString &str, int index, int maxCount)
4750 {
4751  int count = 1;
4752  const QChar ch(str.at(index));
4753  const int max = qMin(index + maxCount, str.size());
4754  while (index + count < max && str.at(index + count) == ch) {
4755  ++count;
4756  }
4757  return count;
4758 }
4759 
4760 static inline void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote)
4761 {
4762  QString str(string.mid(from, size));
4763  if (lastQuote >= from)
4764  str = unquote(str);
4765  list->append(str);
4766 }
4767 
4768 
4770 {
4771  const QLatin1Char quote('\'');
4772  const QLatin1Char slash('\\');
4773  const QLatin1Char zero('0');
4774  if (newFormat == displayFormat && !newFormat.isEmpty()) {
4775  return true;
4776  }
4777 
4778  QDTPDEBUGN("parseFormat: %s", newFormat.toLatin1().constData());
4779 
4780  QVector<SectionNode> newSectionNodes;
4781  Sections newDisplay = 0;
4782  QStringList newSeparators;
4783  int i, index = 0;
4784  int add = 0;
4785  QChar status(zero);
4786  const int max = newFormat.size();
4787  int lastQuote = -1;
4788  for (i = 0; i<max; ++i) {
4789  if (newFormat.at(i) == quote) {
4790  lastQuote = i;
4791  ++add;
4792  if (status != quote) {
4793  status = quote;
4794  } else if (newFormat.at(i - 1) != slash) {
4795  status = zero;
4796  }
4797  } else if (status != quote) {
4798  const char sect = newFormat.at(i).toLatin1();
4799  switch (sect) {
4800  case 'H':
4801  case 'h':
4802  if (parserType != QVariant::Date) {
4803  const Section hour = (sect == 'h') ? Hour12Section : Hour24Section;
4804  const SectionNode sn = { hour, i - add, countRepeat(newFormat, i, 2) };
4805  newSectionNodes.append(sn);
4806  appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4807  i += sn.count - 1;
4808  index = i + 1;
4809  newDisplay |= hour;
4810  }
4811  break;
4812  case 'm':
4813  if (parserType != QVariant::Date) {
4814  const SectionNode sn = { MinuteSection, i - add, countRepeat(newFormat, i, 2) };
4815  newSectionNodes.append(sn);
4816  appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4817  i += sn.count - 1;
4818  index = i + 1;
4819  newDisplay |= MinuteSection;
4820  }
4821  break;
4822  case 's':
4823  if (parserType != QVariant::Date) {
4824  const SectionNode sn = { SecondSection, i - add, countRepeat(newFormat, i, 2) };
4825  newSectionNodes.append(sn);
4826  appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4827  i += sn.count - 1;
4828  index = i + 1;
4829  newDisplay |= SecondSection;
4830  }
4831  break;
4832 
4833  case 'z':
4834  if (parserType != QVariant::Date) {
4835  const SectionNode sn = { MSecSection, i - add, countRepeat(newFormat, i, 3) < 3 ? 1 : 3 };
4836  newSectionNodes.append(sn);
4837  appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4838  i += sn.count - 1;
4839  index = i + 1;
4840  newDisplay |= MSecSection;
4841  }
4842  break;
4843  case 'A':
4844  case 'a':
4845  if (parserType != QVariant::Date) {
4846  const bool cap = (sect == 'A');
4847  const SectionNode sn = { AmPmSection, i - add, (cap ? 1 : 0) };
4848  newSectionNodes.append(sn);
4849  appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4850  newDisplay |= AmPmSection;
4851  if (i + 1 < newFormat.size()
4852  && newFormat.at(i+1) == (cap ? QLatin1Char('P') : QLatin1Char('p'))) {
4853  ++i;
4854  }
4855  index = i + 1;
4856  }
4857  break;
4858  case 'y':
4859  if (parserType != QVariant::Time) {
4860  const int repeat = countRepeat(newFormat, i, 4);
4861  if (repeat >= 2) {
4862  const SectionNode sn = { repeat == 4 ? YearSection : YearSection2Digits,
4863  i - add, repeat == 4 ? 4 : 2 };
4864  newSectionNodes.append(sn);
4865  appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4866  i += sn.count - 1;
4867  index = i + 1;
4868  newDisplay |= sn.type;
4869  }
4870  }
4871  break;
4872  case 'M':
4873  if (parserType != QVariant::Time) {
4874  const SectionNode sn = { MonthSection, i - add, countRepeat(newFormat, i, 4) };
4875  newSectionNodes.append(sn);
4876  newSeparators.append(unquote(newFormat.mid(index, i - index)));
4877  i += sn.count - 1;
4878  index = i + 1;
4879  newDisplay |= MonthSection;
4880  }
4881  break;
4882  case 'd':
4883  if (parserType != QVariant::Time) {
4884  const int repeat = countRepeat(newFormat, i, 4);
4885  const SectionNode sn = { repeat >= 3 ? DayOfWeekSection : DaySection, i - add, repeat };
4886  newSectionNodes.append(sn);
4887  appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
4888  i += sn.count - 1;
4889  index = i + 1;
4890  newDisplay |= sn.type;
4891  }
4892  break;
4893 
4894  default:
4895  break;
4896  }
4897  }
4898  }
4899  if (newSectionNodes.isEmpty() && context == DateTimeEdit) {
4900  return false;
4901  }
4902 
4903  if ((newDisplay & (AmPmSection|Hour12Section)) == Hour12Section) {
4904  const int max = newSectionNodes.size();
4905  for (int i=0; i<max; ++i) {
4906  SectionNode &node = newSectionNodes[i];
4907  if (node.type == Hour12Section)
4908  node.type = Hour24Section;
4909  }
4910  }
4911 
4912  if (index < newFormat.size()) {
4913  appendSeparator(&newSeparators, newFormat, index, index - max, lastQuote);
4914  } else {
4915  newSeparators.append(QString());
4916  }
4917 
4918  displayFormat = newFormat;
4919  separators = newSeparators;
4920  sectionNodes = newSectionNodes;
4921  display = newDisplay;
4922  last.pos = -1;
4923 
4924 // for (int i=0; i<sectionNodes.size(); ++i) {
4925 // QDTPDEBUG << sectionName(sectionNodes.at(i).type) << sectionNodes.at(i).count;
4926 // }
4927 
4928  QDTPDEBUG << newFormat << displayFormat;
4929  QDTPDEBUGN("separators:\n'%s'", separators.join(QLatin1String("\n")).toLatin1().constData());
4930 
4931  return true;
4932 }
4933 
4943 int QDateTimeParser::sectionSize(int sectionIndex) const
4944 {
4945  if (sectionIndex < 0)
4946  return 0;
4947 
4948  if (sectionIndex >= sectionNodes.size()) {
4949  qWarning("QDateTimeParser::sectionSize Internal error (%d)", sectionIndex);
4950  return -1;
4951  }
4952  if (sectionIndex == sectionNodes.size() - 1) {
4953  return displayText().size() - sectionPos(sectionIndex) - separators.last().size();
4954  } else {
4955  return sectionPos(sectionIndex + 1) - sectionPos(sectionIndex)
4956  - separators.at(sectionIndex + 1).size();
4957  }
4958 }
4959 
4960 
4962 {
4963 #ifndef QT_NO_TEXTDATE
4964  int mcount = 12;
4965 #endif
4966 
4967  switch (s) {
4968  case FirstSection:
4969  case NoSection:
4970  case LastSection: return 0;
4971 
4972  case AmPmSection: {
4973  const int lowerMax = qMin(getAmPmText(AmText, LowerCase).size(),
4974  getAmPmText(PmText, LowerCase).size());
4975  const int upperMax = qMin(getAmPmText(AmText, UpperCase).size(),
4976  getAmPmText(PmText, UpperCase).size());
4977  return qMin(4, qMin(lowerMax, upperMax));
4978  }
4979 
4980  case Hour24Section:
4981  case Hour12Section:
4982  case MinuteSection:
4983  case SecondSection:
4984  case DaySection: return 2;
4985  case DayOfWeekSection:
4986 #ifdef QT_NO_TEXTDATE
4987  return 2;
4988 #else
4989  mcount = 7;
4990  // fall through
4991 #endif
4992  case MonthSection:
4993  if (count <= 2)
4994  return 2;
4995 
4996 #ifdef QT_NO_TEXTDATE
4997  return 2;
4998 #else
4999  {
5000  int ret = 0;
5001  const QLocale l = locale();
5002  for (int i=1; i<=mcount; ++i) {
5003  const QString str = (s == MonthSection
5004  ? l.monthName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat)
5005  : l.dayName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat));
5006  ret = qMax(str.size(), ret);
5007  }
5008  return ret;
5009  }
5010 #endif
5011  case MSecSection: return 3;
5012  case YearSection: return 4;
5013  case YearSection2Digits: return 2;
5014 
5015  case CalendarPopupSection:
5016  case Internal:
5017  case TimeSectionMask:
5018  case DateSectionMask:
5019  qWarning("QDateTimeParser::sectionMaxSize: Invalid section %s",
5020  sectionName(s).toLatin1().constData());
5021 
5022  case NoSectionIndex:
5023  case FirstSectionIndex:
5024  case LastSectionIndex:
5025  case CalendarPopupIndex:
5026  // these cases can't happen
5027  break;
5028  }
5029  return -1;
5030 }
5031 
5032 
5034 {
5035  const SectionNode &sn = sectionNode(index);
5036  return sectionMaxSize(sn.type, sn.count);
5037 }
5038 
5050 QString QDateTimeParser::sectionText(const QString &text, int sectionIndex, int index) const
5051 {
5052  const SectionNode &sn = sectionNode(sectionIndex);
5053  switch (sn.type) {
5054  case NoSectionIndex:
5055  case FirstSectionIndex:
5056  case LastSectionIndex:
5057  return QString();
5058  default: break;
5059  }
5060 
5061  return text.mid(index, sectionSize(sectionIndex));
5062 }
5063 
5064 QString QDateTimeParser::sectionText(int sectionIndex) const
5065 {
5066  const SectionNode &sn = sectionNode(sectionIndex);
5067  switch (sn.type) {
5068  case NoSectionIndex:
5069  case FirstSectionIndex:
5070  case LastSectionIndex:
5071  return QString();
5072  default: break;
5073  }
5074 
5075  return displayText().mid(sn.pos, sectionSize(sectionIndex));
5076 }
5077 
5078 
5079 #ifndef QT_NO_TEXTDATE
5080 
5088 int QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex,
5089  QString &text, int &cursorPosition, int index,
5090  State &state, int *usedptr) const
5091 {
5092  state = Invalid;
5093  int num = 0;
5094  const SectionNode &sn = sectionNode(sectionIndex);
5095  if ((sn.type & Internal) == Internal) {
5096  qWarning("QDateTimeParser::parseSection Internal error (%s %d)",
5097  qPrintable(sectionName(sn.type)), sectionIndex);
5098  return -1;
5099  }
5100 
5101  const int sectionmaxsize = sectionMaxSize(sectionIndex);
5102  QString sectiontext = text.mid(index, sectionmaxsize);
5103  int sectiontextSize = sectiontext.size();
5104 
5105  QDTPDEBUG << "sectionValue for" << sectionName(sn.type)
5106  << "with text" << text << "and st" << sectiontext
5107  << text.mid(index, sectionmaxsize)
5108  << index;
5109 
5110  int used = 0;
5111  switch (sn.type) {
5112  case AmPmSection: {
5113  const int ampm = findAmPm(sectiontext, sectionIndex, &used);
5114  switch (ampm) {
5115  case AM: // sectiontext == AM
5116  case PM: // sectiontext == PM
5117  num = ampm;
5118  state = Acceptable;
5119  break;
5120  case PossibleAM: // sectiontext => AM
5121  case PossiblePM: // sectiontext => PM
5122  num = ampm - 2;
5123  state = Intermediate;
5124  break;
5125  case PossibleBoth: // sectiontext => AM|PM
5126  num = 0;
5127  state = Intermediate;
5128  break;
5129  case Neither:
5130  state = Invalid;
5131  QDTPDEBUG << "invalid because findAmPm(" << sectiontext << ") returned -1";
5132  break;
5133  default:
5134  QDTPDEBUGN("This should never happen (findAmPm returned %d)", ampm);
5135  break;
5136  }
5137  if (state != Invalid) {
5138  QString str = text;
5139  text.replace(index, used, sectiontext.left(used));
5140  }
5141  break; }
5142  case MonthSection:
5143  case DayOfWeekSection:
5144  if (sn.count >= 3) {
5145  if (sn.type == MonthSection) {
5146  int min = 1;
5147  const QDate minDate = getMinimum().date();
5148  if (currentValue.date().year() == minDate.year()) {
5149  min = minDate.month();
5150  }
5151  num = findMonth(sectiontext.toLower(), min, sectionIndex, &sectiontext, &used);
5152  } else {
5153  num = findDay(sectiontext.toLower(), 1, sectionIndex, &sectiontext, &used);
5154  }
5155 
5156  if (num != -1) {
5157  state = (used == sectiontext.size() ? Acceptable : Intermediate);
5158  QString str = text;
5159  text.replace(index, used, sectiontext.left(used));
5160  } else {
5161  state = Intermediate;
5162  }
5163  break; }
5164  // fall through
5165  case DaySection:
5166  case YearSection:
5167  case YearSection2Digits:
5168  case Hour12Section:
5169  case Hour24Section:
5170  case MinuteSection:
5171  case SecondSection:
5172  case MSecSection: {
5173  if (sectiontextSize == 0) {
5174  num = 0;
5175  used = 0;
5176  state = Intermediate;
5177  } else {
5178  const int absMax = absoluteMax(sectionIndex);
5179  QLocale loc;
5180  bool ok = true;
5181  int last = -1;
5182  used = -1;
5183 
5184  QString digitsStr(sectiontext);
5185  for (int i = 0; i < sectiontextSize; ++i) {
5186  if (digitsStr.at(i).isSpace()) {
5187  sectiontextSize = i;
5188  break;
5189  }
5190  }
5191 
5192  const int max = qMin(sectionmaxsize, sectiontextSize);
5193  for (int digits = max; digits >= 1; --digits) {
5194  digitsStr.truncate(digits);
5195  int tmp = (int)loc.toUInt(digitsStr, &ok, 10);
5196  if (ok && sn.type == Hour12Section) {
5197  if (tmp > 12) {
5198  tmp = -1;
5199  ok = false;
5200  } else if (tmp == 12) {
5201  tmp = 0;
5202  }
5203  }
5204  if (ok && tmp <= absMax) {
5205  QDTPDEBUG << sectiontext.left(digits) << tmp << digits;
5206  last = tmp;
5207  used = digits;
5208  break;
5209  }
5210  }
5211 
5212  if (last == -1) {
5213  QChar first(sectiontext.at(0));
5214  if (separators.at(sectionIndex + 1).startsWith(first)) {
5215  used = 0;
5216  state = Intermediate;
5217  } else {
5218  state = Invalid;
5219  QDTPDEBUG << "invalid because" << sectiontext << "can't become a uint" << last << ok;
5220  }
5221  } else {
5222  num += last;
5223  const FieldInfo fi = fieldInfo(sectionIndex);
5224  const bool done = (used == sectionmaxsize);
5225  if (!done && fi & Fraction) { // typing 2 in a zzz field should be .200, not .002
5226  for (int i=used; i<sectionmaxsize; ++i) {
5227  num *= 10;
5228  }
5229  }
5230  const int absMin = absoluteMin(sectionIndex);
5231  if (num < absMin) {
5232  state = done ? Invalid : Intermediate;
5233  if (done)
5234  QDTPDEBUG << "invalid because" << num << "is less than absoluteMin" << absMin;
5235  } else if (num > absMax) {
5236  state = Intermediate;
5237  } else if (!done && (fi & (FixedWidth|Numeric)) == (FixedWidth|Numeric)) {
5238  if (skipToNextSection(sectionIndex, currentValue, digitsStr)) {
5239  state = Acceptable;
5240  const int missingZeroes = sectionmaxsize - digitsStr.size();
5241  text.insert(index, QString().fill(QLatin1Char('0'), missingZeroes));
5242  used = sectionmaxsize;
5243  cursorPosition += missingZeroes;
5244  } else {
5245  state = Intermediate;;
5246  }
5247  } else {
5248  state = Acceptable;
5249  }
5250  }
5251  }
5252  break; }
5253  default:
5254  qWarning("QDateTimeParser::parseSection Internal error (%s %d)",
5255  qPrintable(sectionName(sn.type)), sectionIndex);
5256  return -1;
5257  }
5258 
5259  if (usedptr)
5260  *usedptr = used;
5261 
5262  return (state != Invalid ? num : -1);
5263 }
5264 #endif // QT_NO_TEXTDATE
5265 
5266 #ifndef QT_NO_DATESTRING
5267 
5272  const QDateTime &currentValue, bool fixup) const
5273 {
5274  const QDateTime minimum = getMinimum();
5275  const QDateTime maximum = getMaximum();
5276 
5277  State state = Acceptable;
5278 
5279  QDateTime newCurrentValue;
5280  int pos = 0;
5281  bool conflicts = false;
5282  const int sectionNodesCount = sectionNodes.size();
5283 
5284  QDTPDEBUG << "parse" << input;
5285  {
5286  int year, month, day, hour12, hour, minute, second, msec, ampm, dayofweek, year2digits;
5287  getDateFromJulianDay(currentValue.date().toJulianDay(), &year, &month, &day);
5288  year2digits = year % 100;
5289  hour = currentValue.time().hour();
5290  hour12 = -1;
5291  minute = currentValue.time().minute();
5292  second = currentValue.time().second();
5293  msec = currentValue.time().msec();
5294  dayofweek = currentValue.date().dayOfWeek();
5295 
5296  ampm = -1;
5297  Sections isSet = NoSection;
5298  int num;
5299  State tmpstate;
5300 
5301  for (int index=0; state != Invalid && index<sectionNodesCount; ++index) {
5302  if (QStringRef(&input, pos, separators.at(index).size()) != separators.at(index)) {
5303  QDTPDEBUG << "invalid because" << input.mid(pos, separators.at(index).size())
5304  << "!=" << separators.at(index)
5305  << index << pos << currentSectionIndex;
5306  state = Invalid;
5307  goto end;
5308  }
5309  pos += separators.at(index).size();
5310  sectionNodes[index].pos = pos;
5311  int *current = 0;
5312  const SectionNode sn = sectionNodes.at(index);
5313  int used;
5314 
5315  num = parseSection(currentValue, index, input, cursorPosition, pos, tmpstate, &used);
5316  QDTPDEBUG << "sectionValue" << sectionName(sectionType(index)) << input
5317  << "pos" << pos << "used" << used << stateName(tmpstate);
5318  if (fixup && tmpstate == Intermediate && used < sn.count) {
5319  const FieldInfo fi = fieldInfo(index);
5320  if ((fi & (Numeric|FixedWidth)) == (Numeric|FixedWidth)) {
5321  const QString newText = QString::fromLatin1("%1").arg(num, sn.count, 10, QLatin1Char('0'));
5322  input.replace(pos, used, newText);
5323  used = sn.count;
5324  }
5325  }
5326  pos += qMax(0, used);
5327 
5328  state = qMin<State>(state, tmpstate);
5329  if (state == Intermediate && context == FromString) {
5330  state = Invalid;
5331  break;
5332  }
5333 
5334  QDTPDEBUG << index << sectionName(sectionType(index)) << "is set to"
5335  << pos << "state is" << stateName(state);
5336 
5337 
5338  if (state != Invalid) {
5339  switch (sn.type) {
5340  case Hour24Section: current = &hour; break;
5341  case Hour12Section: current = &hour12; break;
5342  case MinuteSection: current = &minute; break;
5343  case SecondSection: current = &second; break;
5344  case MSecSection: current = &msec; break;
5345  case YearSection: current = &year; break;
5346  case YearSection2Digits: current = &year2digits; break;
5347  case MonthSection: current = &month; break;
5348  case DayOfWeekSection: current = &dayofweek; break;
5349  case DaySection: current = &day; num = qMax<int>(1, num); break;
5350  case AmPmSection: current = &ampm; break;
5351  default:
5352  qWarning("QDateTimeParser::parse Internal error (%s)",
5353  qPrintable(sectionName(sn.type)));
5354  break;
5355  }
5356  if (!current) {
5357  qWarning("QDateTimeParser::parse Internal error 2");
5358  return StateNode();
5359  }
5360  if (isSet & sn.type && *current != num) {
5361  QDTPDEBUG << "CONFLICT " << sectionName(sn.type) << *current << num;
5362  conflicts = true;
5363  if (index != currentSectionIndex || num == -1) {
5364  continue;
5365  }
5366  }
5367  if (num != -1)
5368  *current = num;
5369  isSet |= sn.type;
5370  }
5371  }
5372 
5373  if (state != Invalid && QStringRef(&input, pos, input.size() - pos) != separators.last()) {
5374  QDTPDEBUG << "invalid because" << input.mid(pos)
5375  << "!=" << separators.last() << pos;
5376  state = Invalid;
5377  }
5378 
5379  if (state != Invalid) {
5380  if (parserType != QVariant::Time) {
5381  if (year % 100 != year2digits) {
5382  switch (isSet & (YearSection2Digits|YearSection)) {
5383  case YearSection2Digits:
5384  year = (year / 100) * 100;
5385  year += year2digits;
5386  break;
5387  case ((uint)YearSection2Digits|(uint)YearSection): {
5388  conflicts = true;
5389  const SectionNode &sn = sectionNode(currentSectionIndex);
5390  if (sn.type == YearSection2Digits) {
5391  year = (year / 100) * 100;
5392  year += year2digits;
5393  }
5394  break; }
5395  default:
5396  break;
5397  }
5398  }
5399 
5400  const QDate date(year, month, day);
5401  const int diff = dayofweek - date.dayOfWeek();
5402  if (diff != 0 && state == Acceptable && isSet & DayOfWeekSection) {
5403  conflicts = isSet & DaySection;
5404  const SectionNode &sn = sectionNode(currentSectionIndex);
5405  if (sn.type == DayOfWeekSection || currentSectionIndex == -1) {
5406  // dayofweek should be preferred
5407  day += diff;
5408  if (day <= 0) {
5409  day += 7;
5410  } else if (day > date.daysInMonth()) {
5411  day -= 7;
5412  }
5413  QDTPDEBUG << year << month << day << dayofweek
5414  << diff << QDate(year, month, day).dayOfWeek();
5415  }
5416  }
5417  bool needfixday = false;
5418  if (sectionType(currentSectionIndex) & (DaySection|DayOfWeekSection)) {
5419  cachedDay = day;
5420  } else if (cachedDay > day) {
5421  day = cachedDay;
5422  needfixday = true;
5423  }
5424 
5425  if (!QDate::isValid(year, month, day)) {
5426  if (day < 32) {
5427  cachedDay = day;
5428  }
5429  if (day > 28 && QDate::isValid(year, month, 1)) {
5430  needfixday = true;
5431  }
5432  }
5433  if (needfixday) {
5434  if (context == FromString) {
5435  state = Invalid;
5436  goto end;
5437  }
5438  if (state == Acceptable && fixday) {
5439  day = qMin<int>(day, QDate(year, month, 1).daysInMonth());
5440 
5441  const QLocale loc = locale();
5442  for (int i=0; i<sectionNodesCount; ++i) {
5443  if (sectionType(i) & (DaySection|DayOfWeekSection)) {
5444  input.replace(sectionPos(i), sectionSize(i), loc.toString(day));
5445  }
5446  }
5447  } else {
5448  state = qMin(Intermediate, state);
5449  }
5450  }
5451  }
5452 
5453  if (parserType != QVariant::Date) {
5454  if (isSet & Hour12Section) {
5455  const bool hasHour = isSet & Hour24Section;
5456  if (ampm == -1) {
5457  if (hasHour) {
5458  ampm = (hour < 12 ? 0 : 1);
5459  } else {
5460  ampm = 0; // no way to tell if this is am or pm so I assume am
5461  }
5462  }
5463  hour12 = (ampm == 0 ? hour12 % 12 : (hour12 % 12) + 12);
5464  if (!hasHour) {
5465  hour = hour12;
5466  } else if (hour != hour12) {
5467  conflicts = true;
5468  }
5469  } else if (ampm != -1) {
5470  if (!(isSet & (Hour24Section))) {
5471  hour = (12 * ampm); // special case. Only ap section
5472  } else if ((ampm == 0) != (hour < 12)) {
5473  conflicts = true;
5474  }
5475  }
5476 
5477  }
5478 
5479  newCurrentValue = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);
5480  QDTPDEBUG << year << month << day << hour << minute << second << msec;
5481  }
5482  QDTPDEBUGN("'%s' => '%s'(%s)", input.toLatin1().constData(),
5483  newCurrentValue.toString(QLatin1String("yyyy/MM/dd hh:mm:ss.zzz")).toLatin1().constData(),
5484  stateName(state).toLatin1().constData());
5485  }
5486 end:
5487  if (newCurrentValue.isValid()) {
5488  if (context != FromString && state != Invalid && newCurrentValue < minimum) {
5489  const QLatin1Char space(' ');
5490  if (newCurrentValue >= minimum)
5491  qWarning("QDateTimeParser::parse Internal error 3 (%s %s)",
5492  qPrintable(newCurrentValue.toString()), qPrintable(minimum.toString()));
5493 
5494  bool done = false;
5495  state = Invalid;
5496  for (int i=0; i<sectionNodesCount && !done; ++i) {
5497  const SectionNode &sn = sectionNodes.at(i);
5498  QString t = sectionText(input, i, sn.pos).toLower();
5499  if ((t.size() < sectionMaxSize(i) && (((int)fieldInfo(i) & (FixedWidth|Numeric)) != Numeric))
5500  || t.contains(space)) {
5501  switch (sn.type) {
5502  case AmPmSection:
5503  switch (findAmPm(t, i)) {
5504  case AM:
5505  case PM:
5506  state = Acceptable;
5507  done = true;
5508  break;
5509  case Neither:
5510  state = Invalid;
5511  done = true;
5512  break;
5513  case PossibleAM:
5514  case PossiblePM:
5515  case PossibleBoth: {
5516  const QDateTime copy(newCurrentValue.addSecs(12 * 60 * 60));
5517  if (copy >= minimum && copy <= maximum) {
5518  state = Intermediate;
5519  done = true;
5520  }
5521  break; }
5522  }
5523  case MonthSection:
5524  if (sn.count >= 3) {
5525  int tmp = newCurrentValue.date().month();
5526  // I know the first possible month makes the date too early
5527  while ((tmp = findMonth(t, tmp + 1, i)) != -1) {
5528  const QDateTime copy(newCurrentValue.addMonths(tmp - newCurrentValue.date().month()));
5529  if (copy >= minimum && copy <= maximum)
5530  break; // break out of while
5531  }
5532  if (tmp == -1) {
5533  break;
5534  }
5535  state = Intermediate;
5536  done = true;
5537  break;
5538  }
5539  // fallthrough
5540  default: {
5541  int toMin;
5542  int toMax;
5543 
5544  if (sn.type & TimeSectionMask) {
5545  if (newCurrentValue.daysTo(minimum) != 0) {
5546  break;
5547  }
5548  toMin = newCurrentValue.time().msecsTo(minimum.time());
5549  if (newCurrentValue.daysTo(maximum) > 0) {
5550  toMax = -1; // can't get to max
5551  } else {
5552  toMax = newCurrentValue.time().msecsTo(maximum.time());
5553  }
5554  } else {
5555  toMin = newCurrentValue.daysTo(minimum);
5556  toMax = newCurrentValue.daysTo(maximum);
5557  }
5558  const int maxChange = QDateTimeParser::maxChange(i);
5559  if (toMin > maxChange) {
5560  QDTPDEBUG << "invalid because toMin > maxChange" << toMin
5561  << maxChange << t << newCurrentValue << minimum;
5562  state = Invalid;
5563  done = true;
5564  break;
5565  } else if (toMax > maxChange) {
5566  toMax = -1; // can't get to max
5567  }
5568 
5569  const int min = getDigit(minimum, i);
5570  if (min == -1) {
5571  qWarning("QDateTimeParser::parse Internal error 4 (%s)",
5572  qPrintable(sectionName(sn.type)));
5573  state = Invalid;
5574  done = true;
5575  break;
5576  }
5577 
5578  int max = toMax != -1 ? getDigit(maximum, i) : absoluteMax(i, newCurrentValue);
5579  int pos = cursorPosition - sn.pos;
5580  if (pos < 0 || pos >= t.size())
5581  pos = -1;
5582  if (!potentialValue(t.simplified(), min, max, i, newCurrentValue, pos)) {
5583  QDTPDEBUG << "invalid because potentialValue(" << t.simplified() << min << max
5584  << sectionName(sn.type) << "returned" << toMax << toMin << pos;
5585  state = Invalid;
5586  done = true;
5587  break;
5588  }
5589  state = Intermediate;
5590  done = true;
5591  break; }
5592  }
5593  }
5594  }
5595  } else {
5596  if (context == FromString) {
5597  // optimization
5598  Q_ASSERT(getMaximum().date().toJulianDay() == 4642999);
5599  if (newCurrentValue.date().toJulianDay() > 4642999)
5600  state = Invalid;
5601  } else {
5602  if (newCurrentValue > getMaximum())
5603  state = Invalid;
5604  }
5605 
5606  QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << getMinimum() << getMaximum();
5607  }
5608  }
5609  StateNode node;
5610  node.input = input;
5611  node.state = state;
5612  node.conflicts = conflicts;
5613  node.value = newCurrentValue.toTimeSpec(spec);
5614  text = input;
5615  return node;
5616 }
5617 #endif // QT_NO_DATESTRING
5618 
5619 #ifndef QT_NO_TEXTDATE
5620 
5625 int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionIndex,
5626  QString *usedMonth, int *used) const
5627 {
5628  int bestMatch = -1;
5629  int bestCount = 0;
5630  if (!str1.isEmpty()) {
5631  const SectionNode &sn = sectionNode(sectionIndex);
5632  if (sn.type != MonthSection) {
5633  qWarning("QDateTimeParser::findMonth Internal error");
5634  return -1;
5635  }
5636 
5638  QLocale l = locale();
5639 
5640  for (int month=startMonth; month<=12; ++month) {
5641  QString str2 = l.monthName(month, type).toLower();
5642 
5643  if (str1.startsWith(str2)) {
5644  if (used) {
5645  QDTPDEBUG << "used is set to" << str2.size();
5646  *used = str2.size();
5647  }
5648  if (usedMonth)
5649  *usedMonth = l.monthName(month, type);
5650 
5651  return month;
5652  }
5653  if (context == FromString)
5654  continue;
5655 
5656  const int limit = qMin(str1.size(), str2.size());
5657 
5658  QDTPDEBUG << "limit is" << limit << str1 << str2;
5659  bool equal = true;
5660  for (int i=0; i<limit; ++i) {
5661  if (str1.at(i) != str2.at(i)) {
5662  equal = false;
5663  if (i > bestCount) {
5664  bestCount = i;
5665  bestMatch = month;
5666  }
5667  break;
5668  }
5669  }
5670  if (equal) {
5671  if (used)
5672  *used = limit;
5673  if (usedMonth)
5674  *usedMonth = l.monthName(month, type);
5675  return month;
5676  }
5677  }
5678  if (usedMonth && bestMatch != -1)
5679  *usedMonth = l.monthName(bestMatch, type);
5680  }
5681  if (used) {
5682  QDTPDEBUG << "used is set to" << bestCount;
5683  *used = bestCount;
5684  }
5685  return bestMatch;
5686 }
5687 
5688 int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex, QString *usedDay, int *used) const
5689 {
5690  int bestMatch = -1;
5691  int bestCount = 0;
5692  if (!str1.isEmpty()) {
5693  const SectionNode &sn = sectionNode(sectionIndex);
5694  if (!(sn.type & (DaySection|DayOfWeekSection))) {
5695  qWarning("QDateTimeParser::findDay Internal error");
5696  return -1;
5697  }
5698  const QLocale l = locale();
5699  for (int day=startDay; day<=7; ++day) {
5700  const QString str2 = l.dayName(day, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
5701 
5702  if (str1.startsWith(str2.toLower())) {
5703  if (used)
5704  *used = str2.size();
5705  if (usedDay) {
5706  *usedDay = str2;
5707  }
5708  return day;
5709  }
5710  if (context == FromString)
5711  continue;
5712 
5713  const int limit = qMin(str1.size(), str2.size());
5714  bool found = true;
5715  for (int i=0; i<limit; ++i) {
5716  if (str1.at(i) != str2.at(i) && !str1.at(i).isSpace()) {
5717  if (i > bestCount) {
5718  bestCount = i;
5719  bestMatch = day;
5720  }
5721  found = false;
5722  break;
5723  }
5724 
5725  }
5726  if (found) {
5727  if (used)
5728  *used = limit;
5729  if (usedDay)
5730  *usedDay = str2;
5731 
5732  return day;
5733  }
5734  }
5735  if (usedDay && bestMatch != -1) {
5736  *usedDay = l.dayName(bestMatch, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
5737  }
5738  }
5739  if (used)
5740  *used = bestCount;
5741 
5742  return bestMatch;
5743 }
5744 #endif // QT_NO_TEXTDATE
5745 
5759 int QDateTimeParser::findAmPm(QString &str, int index, int *used) const
5760 {
5761  const SectionNode &s = sectionNode(index);
5762  if (s.type != AmPmSection) {
5763  qWarning("QDateTimeParser::findAmPm Internal error");
5764  return -1;
5765  }
5766  if (used)
5767  *used = str.size();
5768  if (str.trimmed().isEmpty()) {
5769  return PossibleBoth;
5770  }
5771  const QLatin1Char space(' ');
5772  int size = sectionMaxSize(index);
5773 
5774  enum {
5775  amindex = 0,
5776  pmindex = 1
5777  };
5778  QString ampm[2];
5779  ampm[amindex] = getAmPmText(AmText, s.count == 1 ? UpperCase : LowerCase);
5780  ampm[pmindex] = getAmPmText(PmText, s.count == 1 ? UpperCase : LowerCase);
5781  for (int i=0; i<2; ++i)
5782  ampm[i].truncate(size);
5783 
5784  QDTPDEBUG << "findAmPm" << str << ampm[0] << ampm[1];
5785 
5786  if (str.indexOf(ampm[amindex], 0, Qt::CaseInsensitive) == 0) {
5787  str = ampm[amindex];
5788  return AM;
5789  } else if (str.indexOf(ampm[pmindex], 0, Qt::CaseInsensitive) == 0) {
5790  str = ampm[pmindex];
5791  return PM;
5792  } else if (context == FromString || (str.count(space) == 0 && str.size() >= size)) {
5793  return Neither;
5794  }
5795  size = qMin(size, str.size());
5796 
5797  bool broken[2] = {false, false};
5798  for (int i=0; i<size; ++i) {
5799  if (str.at(i) != space) {
5800  for (int j=0; j<2; ++j) {
5801  if (!broken[j]) {
5802  int index = ampm[j].indexOf(str.at(i));
5803  QDTPDEBUG << "looking for" << str.at(i)
5804  << "in" << ampm[j] << "and got" << index;
5805  if (index == -1) {
5806  if (str.at(i).category() == QChar::Letter_Uppercase) {
5807  index = ampm[j].indexOf(str.at(i).toLower());
5808  QDTPDEBUG << "trying with" << str.at(i).toLower()
5809  << "in" << ampm[j] << "and got" << index;
5810  } else if (str.at(i).category() == QChar::Letter_Lowercase) {
5811  index = ampm[j].indexOf(str.at(i).toUpper());
5812  QDTPDEBUG << "trying with" << str.at(i).toUpper()
5813  << "in" << ampm[j] << "and got" << index;
5814  }
5815  if (index == -1) {
5816  broken[j] = true;
5817  if (broken[amindex] && broken[pmindex]) {
5818  QDTPDEBUG << str << "didn't make it";
5819  return Neither;
5820  }
5821  continue;
5822  } else {
5823  str[i] = ampm[j].at(index); // fix case
5824  }
5825  }
5826  ampm[j].remove(index, 1);
5827  }
5828  }
5829  }
5830  }
5831  if (!broken[pmindex] && !broken[amindex])
5832  return PossibleBoth;
5833  return (!broken[amindex] ? PossibleAM : PossiblePM);
5834 }
5835 
5845 {
5846  const SectionNode &sn = sectionNode(index);
5847  switch (sn.type) {
5848  // Time. unit is msec
5849  case MSecSection: return 999;
5850  case SecondSection: return 59 * 1000;
5851  case MinuteSection: return 59 * 60 * 1000;
5852  case Hour24Section: case Hour12Section: return 59 * 60 * 60 * 1000;
5853 
5854  // Date. unit is day
5855  case DayOfWeekSection: return 7;
5856  case DaySection: return 30;
5857  case MonthSection: return 365 - 31;
5858  case YearSection: return 9999 * 365;
5859  case YearSection2Digits: return 100 * 365;
5860  default:
5861  qWarning("QDateTimeParser::maxChange() Internal error (%s)",
5862  qPrintable(sectionName(sectionType(index))));
5863  }
5864 
5865  return -1;
5866 }
5867 
5868 QDateTimeParser::FieldInfo QDateTimeParser::fieldInfo(int index) const
5869 {
5870  FieldInfo ret = 0;
5871  const SectionNode &sn = sectionNode(index);
5872  const Section s = sn.type;
5873  switch (s) {
5874  case MSecSection:
5875  ret |= Fraction;
5876  // fallthrough
5877  case SecondSection:
5878  case MinuteSection:
5879  case Hour24Section:
5880  case Hour12Section:
5881  case YearSection:
5882  case YearSection2Digits:
5883  ret |= Numeric;
5884  if (s != YearSection) {
5885  ret |= AllowPartial;
5886  }
5887  if (sn.count != 1) {
5888  ret |= FixedWidth;
5889  }
5890  break;
5891  case MonthSection:
5892  case DaySection:
5893  switch (sn.count) {
5894  case 2:
5895  ret |= FixedWidth;
5896  // fallthrough
5897  case 1:
5898  ret |= (Numeric|AllowPartial);
5899  break;
5900  }
5901  break;
5902  case DayOfWeekSection:
5903  if (sn.count == 3)
5904  ret |= FixedWidth;
5905  break;
5906  case AmPmSection:
5907  ret |= FixedWidth;
5908  break;
5909  default:
5910  qWarning("QDateTimeParser::fieldInfo Internal error 2 (%d %s %d)",
5911  index, qPrintable(sectionName(sn.type)), sn.count);
5912  break;
5913  }
5914  return ret;
5915 }
5916 
5924 {
5925  const SectionNode &sn = sectionNode(index);
5926  return sectionFormat(sn.type, sn.count);
5927 }
5928 
5930 {
5931  QChar fillChar;
5932  switch (s) {
5933  case AmPmSection: return count == 1 ? QLatin1String("AP") : QLatin1String("ap");
5934  case MSecSection: fillChar = QLatin1Char('z'); break;
5935  case SecondSection: fillChar = QLatin1Char('s'); break;
5936  case MinuteSection: fillChar = QLatin1Char('m'); break;
5937  case Hour24Section: fillChar = QLatin1Char('H'); break;
5938  case Hour12Section: fillChar = QLatin1Char('h'); break;
5939  case DayOfWeekSection:
5940  case DaySection: fillChar = QLatin1Char('d'); break;
5941  case MonthSection: fillChar = QLatin1Char('M'); break;
5942  case YearSection2Digits:
5943  case YearSection: fillChar = QLatin1Char('y'); break;
5944  default:
5945  qWarning("QDateTimeParser::sectionFormat Internal error (%s)",
5946  qPrintable(sectionName(s)));
5947  return QString();
5948  }
5949  if (fillChar.isNull()) {
5950  qWarning("QDateTimeParser::sectionFormat Internal error 2");
5951  return QString();
5952  }
5953 
5954  QString str;
5955  str.fill(fillChar, count);
5956  return str;
5957 }
5958 
5959 
5964 bool QDateTimeParser::potentialValue(const QString &str, int min, int max, int index,
5965  const QDateTime &currentValue, int insert) const
5966 {
5967  if (str.isEmpty()) {
5968  return true;
5969  }
5970  const int size = sectionMaxSize(index);
5971  int val = (int)locale().toUInt(str);
5972  const SectionNode &sn = sectionNode(index);
5973  if (sn.type == YearSection2Digits) {
5974  val += currentValue.date().year() - (currentValue.date().year() % 100);
5975  }
5976  if (val >= min && val <= max && str.size() == size) {
5977  return true;
5978  } else if (val > max) {
5979  return false;
5980  } else if (str.size() == size && val < min) {
5981  return false;
5982  }
5983 
5984  const int len = size - str.size();
5985  for (int i=0; i<len; ++i) {
5986  for (int j=0; j<10; ++j) {
5987  if (potentialValue(str + QLatin1Char('0' + j), min, max, index, currentValue, insert)) {
5988  return true;
5989  } else if (insert >= 0) {
5990  QString tmp = str;
5991  tmp.insert(insert, QLatin1Char('0' + j));
5992  if (potentialValue(tmp, min, max, index, currentValue, insert))
5993  return true;
5994  }
5995  }
5996  }
5997 
5998  return false;
5999 }
6000 
6001 bool QDateTimeParser::skipToNextSection(int index, const QDateTime &current, const QString &text) const
6002 {
6003  Q_ASSERT(current >= getMinimum() && current <= getMaximum());
6004 
6005  const SectionNode &node = sectionNode(index);
6006  Q_ASSERT(text.size() < sectionMaxSize(index));
6007 
6008  const QDateTime maximum = getMaximum();
6009  const QDateTime minimum = getMinimum();
6010  QDateTime tmp = current;
6011  int min = absoluteMin(index);
6012  setDigit(tmp, index, min);
6013  if (tmp < minimum) {
6014  min = getDigit(minimum, index);
6015  }
6016 
6017  int max = absoluteMax(index, current);
6018  setDigit(tmp, index, max);
6019  if (tmp > maximum) {
6020  max = getDigit(maximum, index);
6021  }
6022  int pos = cursorPosition() - node.pos;
6023  if (pos < 0 || pos >= text.size())
6024  pos = -1;
6025 
6026  const bool potential = potentialValue(text, min, max, index, current, pos);
6027  return !potential;
6028 
6029  /* If the value potentially can become another valid entry we
6030  * don't want to skip to the next. E.g. In a M field (month
6031  * without leading 0 if you type 1 we don't want to autoskip but
6032  * if you type 3 we do
6033  */
6034 }
6035 
6045 {
6046  switch (s) {
6047  case QDateTimeParser::AmPmSection: return QLatin1String("AmPmSection");
6048  case QDateTimeParser::DaySection: return QLatin1String("DaySection");
6049  case QDateTimeParser::DayOfWeekSection: return QLatin1String("DayOfWeekSection");
6050  case QDateTimeParser::Hour24Section: return QLatin1String("Hour24Section");
6051  case QDateTimeParser::Hour12Section: return QLatin1String("Hour12Section");
6052  case QDateTimeParser::MSecSection: return QLatin1String("MSecSection");
6053  case QDateTimeParser::MinuteSection: return QLatin1String("MinuteSection");
6054  case QDateTimeParser::MonthSection: return QLatin1String("MonthSection");
6055  case QDateTimeParser::SecondSection: return QLatin1String("SecondSection");
6056  case QDateTimeParser::YearSection: return QLatin1String("YearSection");
6057  case QDateTimeParser::YearSection2Digits: return QLatin1String("YearSection2Digits");
6058  case QDateTimeParser::NoSection: return QLatin1String("NoSection");
6059  case QDateTimeParser::FirstSection: return QLatin1String("FirstSection");
6060  case QDateTimeParser::LastSection: return QLatin1String("LastSection");
6061  default: return QLatin1String("Unknown section ") + QString::number(s);
6062  }
6063 }
6064 
6074 {
6075  switch (s) {
6076  case Invalid: return QLatin1String("Invalid");
6077  case Intermediate: return QLatin1String("Intermediate");
6078  case Acceptable: return QLatin1String("Acceptable");
6079  default: return QLatin1String("Unknown state ") + QString::number(s);
6080  }
6081 }
6082 
6083 #ifndef QT_NO_DATESTRING
6085 {
6086  QDateTime val(QDate(1900, 1, 1), QDATETIMEEDIT_TIME_MIN);
6087  QString text = t;
6088  int copy = -1;
6089  const StateNode tmp = parse(text, copy, val, false);
6090  if (tmp.state != Acceptable || tmp.conflicts) {
6091  return false;
6092  }
6093  if (time) {
6094  const QTime t = tmp.value.time();
6095  if (!t.isValid()) {
6096  return false;
6097  }
6098  *time = t;
6099  }
6100 
6101  if (date) {
6102  const QDate d = tmp.value.date();
6103  if (!d.isValid()) {
6104  return false;
6105  }
6106  *date = d;
6107  }
6108  return true;
6109 }
6110 #endif // QT_NO_DATESTRING
6111 
6113 {
6115 }
6116 
6118 {
6120 }
6121 
6123 {
6124  if (ap == AmText) {
6125  return (cs == UpperCase ? QLatin1String("AM") : QLatin1String("am"));
6126  } else {
6127  return (cs == UpperCase ? QLatin1String("PM") : QLatin1String("pm"));
6128  }
6129 }
6130 
6131 /*
6132  \internal
6133 
6134  I give arg2 preference because arg1 is always a QDateTime.
6135 */
6136 
6138 {
6139  return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count);
6140 }
6141 
6142 #ifdef Q_OS_SYMBIAN
6143 const static TTime UnixEpochOffset(I64LIT(0xdcddb30f2f8000));
6144 const static TInt64 MinimumMillisecondTime(KMinTInt64 / 1000);
6145 const static TInt64 MaximumMillisecondTime(KMaxTInt64 / 1000);
6146 QDateTime qt_symbian_TTime_To_QDateTime(const TTime& time)
6147 {
6148  TTimeIntervalMicroSeconds absolute = time.MicroSecondsFrom(UnixEpochOffset);
6149 
6150  return QDateTime::fromMSecsSinceEpoch(absolute.Int64() / 1000);
6151 }
6152 
6153 TTime qt_symbian_QDateTime_To_TTime(const QDateTime& datetime)
6154 {
6155  qint64 absolute = datetime.toMSecsSinceEpoch();
6156  if(absolute > MaximumMillisecondTime)
6157  return TTime(KMaxTInt64);
6158  if(absolute < MinimumMillisecondTime)
6159  return TTime(KMinTInt64);
6160  return TTime(absolute * 1000);
6161 }
6162 
6163 time_t qt_symbian_TTime_To_time_t(const TTime& time)
6164 {
6165  TTimeIntervalSeconds interval;
6166  TInt err = time.SecondsFrom(UnixEpochOffset, interval);
6167  if (err || interval.Int() < 0)
6168  return (time_t) 0;
6169  return (time_t) interval.Int();
6170 }
6171 
6172 TTime qt_symbian_time_t_To_TTime(time_t time)
6173 {
6174  return UnixEpochOffset + TTimeIntervalSeconds(time);
6175 }
6176 #endif //Q_OS_SYMBIAN
6177 
6178 #endif // QT_BOOTSTRAPPED
6179 
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
static QString fromWCharArray(const wchar_t *, int size=-1)
Returns a copy of the string, where the encoding of string depends on the size of wchar...
Definition: qstring.cpp:1019
QDateTime addSecs(int secs) const
Returns a QDateTime object containing a datetime s seconds later than the datetime of this object (or...
Definition: qdatetime.cpp:2869
QBool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.h:904
int dayOfWeek() const
Returns the weekday (1 = Monday to 7 = Sunday) for this date.
Definition: qdatetime.cpp:408
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:62
double d
Definition: qnumeric_p.h:62
int daysTo(const QDateTime &) const
Returns the number of days from this datetime to the other datetime.
Definition: qdatetime.cpp:2894
#define QDATETIMEEDIT_DATE_MAX
Definition: qdatetime_p.h:71
static void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote)
Definition: qdatetime.cpp:4760
int tm_min
int absoluteMin(int index) const
Definition: qdatetime.cpp:4623
qint64 toMSecsSinceEpoch() const
Returns the datetime as the number of milliseconds that have passed since 1970-01-01T00:00:00.
Definition: qdatetime.cpp:2474
int type
Definition: qmetatype.cpp:239
bool isNull() const
Returns true if both the date and the time are null; otherwise returns false.
Definition: qdatetime.cpp:2334
int daysTo(const QDate &) const
Returns the number of days from this date to d (which is negative if d is earlier than this date)...
Definition: qdatetime.cpp:1111
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
int findAmPm(QString &str1, int index, int *used=0) const
Definition: qdatetime.cpp:5759
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
StateNode parse(QString &input, int &cursorPosition, const QDateTime &currentValue, bool fixup) const
Definition: qdatetime.cpp:5271
bool isNull() const
Returns true if the date is null; otherwise returns false.
Definition: qdatetime.h:66
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
#define add(aName)
The QRegExp class provides pattern matching using regular expressions.
Definition: qregexp.h:61
bool isValid() const
Returns true if this date is valid; otherwise returns false.
Definition: qdatetime.cpp:340
int toInt(bool *ok=0, int base=10) const
Returns the string converted to an int using base base, which is 10 by default and must be between 2 ...
Definition: qstring.cpp:6090
bool isNull() const
Returns true if the character is the Unicode character 0x0000 (&#39;\0&#39;); otherwise returns false...
Definition: qchar.h:262
static QString fmtDateTime(const QString &f, const QTime *dt=0, const QDate *dd=0)
Definition: qdatetime.cpp:4133
void start()
Sets this time to the current time.
Definition: qdatetime.cpp:2070
bool isNull() const
Returns true if the time is null (i.
Definition: qdatetime.h:158
QDebug & nospace()
Clears the stream&#39;s internal flag that records whether the last character was a space and returns a r...
Definition: qdebug.h:92
int msecsTo(const QTime &) const
Returns the number of milliseconds from this time to t.
Definition: qdatetime.cpp:1832
qint64 toMSecsSinceEpoch_helper(qint64 jd, int msecs)
Definition: qdatetime.cpp:2449
QString monthName(int, FormatType format=LongFormat) const
Returns the localized name of month, in the format specified by type.
Definition: qlocale.cpp:2007
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
uint toUInt(const QString &s, bool *ok=0, int base=0) const
Returns the unsigned int represented by the localized string s, using base base.
Definition: qlocale.cpp:1161
void chop(int n)
Removes n characters from the end of the string.
Definition: qstring.cpp:4623
int tm_mday
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QString & prepend(QChar c)
Definition: qstring.h:261
QString toUpper() const Q_REQUIRED_RESULT
Returns an uppercase copy of the string.
Definition: qstring.cpp:5483
int month() const
Returns the number corresponding to the month of this date, using the following convention: ...
Definition: qdatetime.cpp:382
int absoluteMax(int index, const QDateTime &value=QDateTime()) const
\
Definition: qdatetime.cpp:4590
bool parseFormat(const QString &format)
Definition: qdatetime.cpp:4769
FormatType
Definition: qlocale.h:659
uint toTime_t() const
Returns the datetime as the number of seconds that have passed since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC).
Definition: qdatetime.cpp:2505
virtual QString getAmPmText(AmPm ap, Case cs) const
Definition: qdatetime.cpp:6122
QDateTime()
Constructs a null datetime (i.e.
Definition: qdatetime.cpp:2267
int weekNumber(int *yearNum=0) const
Returns the week number (1 to 53), and stores the year in {yearNumber} unless yearNumber is null (the...
Definition: qdatetime.cpp:487
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
int day() const
Returns the day of the month (1 to 31) of this date.
Definition: qdatetime.cpp:395
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
bool isValid() const
Returns true if both the date and the time are valid; otherwise returns false.
Definition: qdatetime.cpp:2346
The QDate class provides date functions.
Definition: qdatetime.h:55
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
static void getDateFromJulianDay(uint julianDay, int *year, int *month, int *day)
Definition: qdatetime.cpp:133
int msec() const
Returns the millisecond part (0 to 999) of the time.
Definition: qdatetime.cpp:1611
int tm_year
static uint msecsFromDecomposed(int hour, int minute, int sec, int msec=0)
Definition: qdatetime.cpp:3109
void getDate(int *year, int *month, int *day)
Definition: qdatetime.cpp:977
long ASN1_INTEGER_get ASN1_INTEGER * a
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
int secsTo(const QTime &) const
Returns the number of seconds from this time to t.
Definition: qdatetime.cpp:1788
static void localToUtc(QDate &date, QTime &time, int isdst)
Definition: qdatetime.cpp:4316
virtual QDateTime getMaximum() const
Definition: qdatetime.cpp:6117
static QString shortDayName(int weekday)
Returns the short version of the name of the weekday.
Definition: qdatetime.cpp:709
int daysInYear() const
Returns the number of days in the year (365 or 366) for this date.
Definition: qdatetime.cpp:447
QDate()
Constructs a null date.
Definition: qdatetime.h:63
int sectionMaxSize(int index) const
Definition: qdatetime.cpp:5033
The QString class provides a Unicode character string.
Definition: qstring.h:83
int maxChange(int s) const
Max number of units that can be changed by this section.
Definition: qdatetime.cpp:5844
#define QDATETIMEEDIT_TIME_MIN
Definition: qdatetime_p.h:67
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
QDate addYears(int years) const
Returns a QDate object containing a date nyears later than the date of this object (or earlier if nye...
Definition: qdatetime.cpp:1081
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
QDate addMonths(int months) const
Returns a QDate object containing a date nmonths later than the date of this object (or earlier if nm...
Definition: qdatetime.cpp:1016
bool operator<(const QDateTime &other) const
Returns true if this datetime is earlier than the other datetime; otherwise returns false...
Definition: qdatetime.cpp:3025
static const char monthDays[]
Definition: qdatetime.cpp:173
int utcOffset() const
Definition: qdatetime.cpp:3449
static uint julianDayFromDate(int year, int month, int day)
Definition: qdatetime.cpp:113
MonthNameType
This enum describes the types of the string representation used for the month name.
Definition: qdatetime.h:58
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QTime addSecs(int secs) const
Returns a QTime object containing a time s seconds later than the time of this object (or earlier if ...
Definition: qdatetime.cpp:1770
QString toString(qlonglong i) const
Returns a localized string representation of i.
Definition: qlocale.cpp:1295
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
QString toString(Qt::DateFormat f=Qt::TextDate) const
Returns the datetime as a string in the format given.
Definition: qdatetime.cpp:2628
static bool isLeapYear(int year)
Returns true if the specified year is a leap year; otherwise returns false.
Definition: qdatetime.cpp:1404
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
bool isSpace() const
Returns true if the character is a separator character (Separator_* categories); otherwise returns fa...
Definition: qchar.cpp:609
Category category() const
Returns the character&#39;s category.
Definition: qchar.cpp:853
int restart()
Sets this time to the current time and returns the number of milliseconds that have elapsed since the...
Definition: qdatetime.cpp:2095
static QLocale system()
Returns a QLocale object initialized to the system locale.
Definition: qlocale.cpp:1917
bool operator==(const QDateTime &other) const
Returns true if this datetime is equal to the other datetime; otherwise returns false.
Definition: qdatetime.cpp:2991
static QString longMonthName(int month)
Returns the long version of the name of the month.
Definition: qdatetime.cpp:651
static QString getFmtString(const QString &f, const QTime *dt=0, const QDate *dd=0, bool am_pm=false)
Definition: qdatetime.cpp:4026
static int sign(int x)
QDateTime & operator=(const QDateTime &other)
Makes a copy of the other datetime and returns a reference to the copy.
Definition: qdatetime.cpp:2321
TimeSpec
Definition: qnamespace.h:1404
QString sectionFormat(int index) const
Definition: qdatetime.cpp:5923
static uint gregorianToJulian(int y, int m, int d)
This function has a confusing name and shouldn&#39;t be part of the API anyway, since we have toJulian() ...
Definition: qdatetime.cpp:1426
QDateTime addYears(int years) const
Returns a QDateTime object containing a datetime nyears years later than the datetime of this object ...
Definition: qdatetime.cpp:2809
signed char qint8
Definition: qglobal.h:933
QString rightJustified(int width, QChar fill=QLatin1Char(' '), bool trunc=false) const Q_REQUIRED_RESULT
Returns a string of size() width that contains the fill character followed by the string...
Definition: qstring.cpp:5357
static QDateTime fromString(const QString &s, Qt::DateFormat f=Qt::TextDate)
Returns the QDateTime represented by the string, using the format given, or an invalid datetime if th...
Definition: qdatetime.cpp:3487
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
int ds() const
Definition: qdatetime.h:199
#define QDTPDEBUGN
Definition: qdatetime.cpp:69
The QTime class provides clock time functions.
Definition: qdatetime.h:148
int dayOfYear() const
Returns the day of the year (1 to 365 or 366 on leap years) for this date.
Definition: qdatetime.cpp:420
bool skipToNextSection(int section, const QDateTime &current, const QString &sectionText) const
Definition: qdatetime.cpp:6001
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
static QDate fixedDate(int y, int m, int d)
Definition: qdatetime.cpp:96
static int countRepeat(const QString &str, int index, int maxCount)
Parses the format newFormat.
Definition: qdatetime.cpp:4749
void setTime_t(uint secsSince1Jan1970UTC)
Sets the date and time given the number of seconds that have passed since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC).
Definition: qdatetime.cpp:2566
static uint julianDayFromGregorianDate(int year, int month, int day)
Definition: qdatetime.cpp:103
QString sectionName(int s) const
For debugging.
Definition: qdatetime.cpp:6044
void setDate(const QDate &date)
Sets the date part of this datetime to date.
Definition: qdatetime.cpp:2399
void truncate(int pos)
Truncates the string at the given position index.
Definition: qstring.cpp:4603
unsigned long time_t
int startTick
Definition: qdatetime.h:202
unsigned __int64 quint64
Definition: qglobal.h:943
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
qint64 msecsTo(const QDateTime &) const
Returns the number of milliseconds from this datetime to the other datetime.
Definition: qdatetime.cpp:2942
QString trimmed() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end.
Definition: qstring.cpp:4506
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
int tm_mon
static QDate currentDate()
Returns the current date, as reported by the system clock.
Definition: qdatetime.cpp:3115
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
int sectionSize(int index) const
Returns the size of section s.
Definition: qdatetime.cpp:4943
static const char *const qt_shortMonthNames[]
Definition: qdatetime.cpp:176
void setTime(const QTime &time)
Sets the time part of this datetime to time.
Definition: qdatetime.cpp:2416
QDateTime toLocalTime() const
Returns a datetime containing the date and time information in this datetime, but specified using the...
Definition: qdatetime.h:250
QTime()
Constructs a null time object.
Definition: qdatetime.h:151
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
virtual QDateTime getMinimum() const
Definition: qdatetime.cpp:6112
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
int secsTo(const QDateTime &) const
Returns the number of seconds from this datetime to the other datetime.
Definition: qdatetime.cpp:2914
static QDateTime currentDateTimeUtc()
Returns the current datetime, as reported by the system clock, in UTC.
Definition: qdatetime.cpp:3150
const SectionNode & sectionNode(int index) const
Returns the sectionNode for the Section s.
Definition: qdatetime.cpp:4654
int findDay(const QString &str1, int intDaystart, int sectionIndex, QString *dayName=0, int *used=0) const
Definition: qdatetime.cpp:5688
Q_CORE_EXPORT void qWarning(const char *,...)
int second() const
Returns the second part (0 to 59) of the time.
Definition: qdatetime.cpp:1600
unsigned int uint
Definition: qglobal.h:996
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
static Bigint * diff(Bigint *a, Bigint *b)
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
QString stateName(int s) const
For debugging.
Definition: qdatetime.cpp:6073
static qint64 currentMSecsSinceEpoch()
Returns the number of milliseconds since 1970-01-01T00:00:00 Universal Coordinated Time...
Definition: qdatetime.cpp:3162
void getUTC(QDate &outDate, QTime &outTime) const
Definition: qdatetime.cpp:4422
QDateTime addMonths(int months) const
Returns a QDateTime object containing a datetime nmonths months later than the datetime of this objec...
Definition: qdatetime.cpp:2796
QChar toUpper() const
Returns the uppercase equivalent if the character is lowercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1287
void setTimeSpec(Qt::TimeSpec spec)
Sets the time specification used in this datetime to spec.
Definition: qdatetime.cpp:2431
QDate addDays(int days) const
Returns a QDate object containing a date ndays later than the date of this object (or earlier if nday...
Definition: qdatetime.cpp:989
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
__int64 qint64
Definition: qglobal.h:942
int getDigit(const QDateTime &dt, int index) const
Gets the digit from a datetime.
Definition: qdatetime.cpp:4469
QDateTime addMSecs(qint64 msecs) const
Returns a QDateTime object containing a datetime msecs miliseconds later than the datetime of this ob...
Definition: qdatetime.cpp:2881
int minute() const
Returns the minute part (0 to 59) of the time.
Definition: qdatetime.cpp:1589
The State element defines configurations of objects and properties.
#define QDATETIMEEDIT_TIME_MAX
Definition: qdatetime_p.h:68
int parseSection(const QDateTime &currentValue, int sectionIndex, QString &txt, int &cursorPosition, int index, QDateTimeParser::State &state, int *used=0) const
Definition: qdatetime.cpp:5088
int count() const
Definition: qstring.h:103
The QStringRef class provides a thin wrapper around QString substrings.
Definition: qstring.h:1099
bool setDate(int year, int month, int day)
Sets the date&#39;s year, month, and day.
Definition: qdatetime.cpp:959
#define Q_INT64_C(c)
Definition: qglobal.h:940
static const int UpperYear
Definition: qdatetime.cpp:4203
static QTime fromString(const QString &s, Qt::DateFormat f=Qt::TextDate)
Returns the time represented in the string as a QTime using the format given, or an invalid time if t...
Definition: qdatetime.cpp:1928
bool isUpper() const
Returns true if the character is an uppercase letter, i.
Definition: qchar.h:273
int version() const
Returns the version number of the data serialization format.
Definition: qdatastream.h:212
void detach()
Definition: qdatetime.cpp:3791
static QDateTime fromMSecsSinceEpoch(qint64 msecs)
Returns a datetime whose date and time are the number of milliseconds, msecs, that have passed since ...
Definition: qdatetime.cpp:3393
static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time)
Definition: qdatetime.cpp:4228
#define QDATETIMEEDIT_DATE_MIN
Definition: qdatetime_p.h:69
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QDate date() const
Returns the date part of the datetime.
Definition: qdatetime.cpp:2357
QString toString(Qt::DateFormat f=Qt::TextDate) const
Returns the time as a string.
Definition: qdatetime.cpp:1653
int toJulianDay() const
Converts the date to a Julian day.
Definition: qdatetime.h:134
int findMonth(const QString &str1, int monthstart, int sectionIndex, QString *monthName=0, int *used=0) const
Definition: qdatetime.cpp:5625
static QString unquote(const QString &str)
Definition: qdatetime.cpp:4715
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
int daysInMonth() const
Returns the number of days in the month (28 to 31) for this date.
Definition: qdatetime.cpp:431
int elapsed() const
Returns the number of milliseconds that have elapsed since the last time start() or restart() was cal...
Definition: qdatetime.cpp:2123
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
static QDateTime addMSecs(const QDateTime &dt, qint64 msecs)
Definition: qdatetime.cpp:2814
QDateTime addDays(int days) const
Returns a QDateTime object containing a datetime ndays days later than the datetime of this object (o...
Definition: qdatetime.cpp:2783
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
static bool hasUnquotedAP(const QString &f)
Definition: qdatetime.cpp:4005
The QDateTime class provides date and time functions.
Definition: qdatetime.h:216
int utcOffset
The offset in seconds.
Definition: qdatetime_p.h:102
int mds
Definition: qdatetime.h:200
~QDateTime()
Destroys the datetime.
Definition: qdatetime.cpp:2312
QString simplified() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end, and that has each sequence o...
Definition: qstring.cpp:4415
void clear()
Clears the contents of the string and makes it empty.
Definition: qstring.h:723
static QTime currentTime()
Returns the current time as reported by the system clock.
Definition: qdatetime.cpp:3125
static QDate adjustDate(QDate date)
Definition: qdatetime.cpp:4205
Section sectionType(int index) const
Definition: qdatetime.cpp:4674
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
bool setDigit(QDateTime &t, int index, int newval) const
Sets a digit in a datetime.
Definition: qdatetime.cpp:4520
friend Q_CORE_EXPORT QDataStream & operator>>(QDataStream &, QDateTime &)
Reads a datetime from the stream in into dateTime.
Definition: qdatetime.cpp:3900
#define st(var, type, card)
static int fromShortMonthName(const QString &monthName)
Definition: qdatetime.cpp:3459
QString toLower() const Q_REQUIRED_RESULT
Returns a lowercase copy of the string.
Definition: qstring.cpp:5389
static QDate fromString(const QString &s, Qt::DateFormat f=Qt::TextDate)
Returns the QDate represented by the string, using the format given, or an invalid date if the string...
Definition: qdatetime.cpp:1203
Qt::TimeSpec timeSpec() const
Returns the time specification of the datetime.
Definition: qdatetime.cpp:2379
static QDateTime fromTime_t(uint secsSince1Jan1970UTC)
Returns a datetime whose date and time are the number of seconds that have passed since 1970-01-01T00...
Definition: qdatetime.cpp:3369
unsigned int quint32
Definition: qglobal.h:938
Spec getLocal(QDate &outDate, QTime &outTime) const
Definition: qdatetime.cpp:4413
QString standaloneMonthName(int, FormatType format=LongFormat) const
Returns the localized name of month that is used as a standalone text, in the format specified by typ...
Definition: qlocale.cpp:2056
QString & fill(QChar c, int size=-1)
Sets every character in the string to character ch.
Definition: qstring.cpp:4641
#define QDTPDEBUG
Definition: qdatetime.cpp:68
void detach()
If the shared data object&#39;s reference count is greater than 1, this function creates a deep copy of t...
Definition: qshareddata.h:148
static void cleanup()
Definition: qpicture.cpp:1508
static const int zero
static QDateTime currentDateTime()
Returns the current datetime, as reported by the system clock, in the local time zone.
Definition: qdatetime.cpp:3138
bool setYMD(int y, int m, int d)
Sets the date&#39;s year y, month m, and day d.
Definition: qdatetime.cpp:937
QFactoryLoader * l
bool potentialValue(const QString &str, int min, int max, int index, const QDateTime &currentValue, int insert) const
Definition: qdatetime.cpp:5964
char toLatin1() const
Returns the Latin-1 character equivalent to the QChar, or 0.
Definition: qchar.h:376
static void julianToGregorian(uint jd, int &y, int &m, int &d)
This function has a confusing name and shouldn&#39;t be part of the API anyway, since we have toJulian() ...
Definition: qdatetime.cpp:1441
quint16 index
friend Q_CORE_EXPORT QDataStream & operator<<(QDataStream &, const QDateTime &)
Writes dateTime to the out stream.
Definition: qdatetime.cpp:3881
QTime addMSecs(int ms) const
Returns a QTime object containing a time ms milliseconds later than the time of this object (or earli...
Definition: qdatetime.cpp:1803
static QString shortMonthName(int month)
Returns the short version of the name of the month.
Definition: qdatetime.cpp:591
int tm_sec
int year() const
Returns the year of this date.
Definition: qdatetime.cpp:353
QExplicitlySharedDataPointer< QDateTimePrivate > d
Definition: qdatetime.h:294
static const int LowerYear
Definition: qdatetime.cpp:4199
QString dayName(int, FormatType format=LongFormat) const
Returns the localized name of the day (where 1 represents Monday, 2 represents Tuesday and so on)...
Definition: qlocale.cpp:2106
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
QTime time() const
Returns the time part of the datetime.
Definition: qdatetime.cpp:2368
QDateTime toTimeSpec(Qt::TimeSpec spec) const
Returns a copy of this datetime configured to use the given time specification.
Definition: qdatetime.cpp:2969
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71
quint64 qulonglong
Definition: qglobal.h:952
QString sectionText(int sectionIndex) const
Definition: qdatetime.cpp:5064
int tm_hour
static QString longDayName(int weekday)
Returns the long version of the name of the weekday.
Definition: qdatetime.cpp:767
uint jd
Definition: qdatetime.h:137
#define Q_UINT64_C(c)
Definition: qglobal.h:941
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition: qstring.cpp:3796
bool fromString(const QString &text, QDate *date, QTime *time) const
Definition: qdatetime.cpp:6084
FieldInfo fieldInfo(int index) const
Definition: qdatetime.cpp:5868
static const KeyPair *const end
QDebug & space()
Writes a space character to the debug stream and returns a reference to the stream.
Definition: qdebug.h:91
#define qPrintable(string)
Definition: qglobal.h:1750
int sectionPos(int index) const
Returns the starting position for section s.
Definition: qdatetime.cpp:4689
QString & insert(int i, QChar c)
Definition: qstring.cpp:1671
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
QString toString(Qt::DateFormat f=Qt::TextDate) const
Returns the date as a string.
Definition: qdatetime.cpp:823
QChar toLower() const
Returns the lowercase equivalent if the character is uppercase or titlecase; otherwise returns the ch...
Definition: qchar.cpp:1239
int tm_isdst
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
void setMSecsSinceEpoch(qint64 msecs)
Sets the date and time given the number of milliseconds,msecs, that have passed since 1970-01-01T00:0...
Definition: qdatetime.cpp:2530
bool setHMS(int h, int m, int s, int ms=0)
Sets the time to hour h, minute m, seconds s and milliseconds ms.
Definition: qdatetime.cpp:1744
const QChar at(int i) const
Returns the character at the given index position in the string reference.
Definition: qstring.h:1174
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
#define time_tToFt(a)
#define text
Definition: qobjectdefs.h:80
static bool equal(const QChar *a, int l, const char *b)
Definition: qurl.cpp:3270
bool isValid() const
Returns true if the time is valid; otherwise returns false.
Definition: qdatetime.cpp:1566
int hour() const
Returns the hour part (0 to 23) of the time.
Definition: qdatetime.cpp:1578
void setUtcOffset(int seconds)
Definition: qdatetime.cpp:3416
QString standaloneDayName(int, FormatType format=LongFormat) const
Returns the localized name of the day (where 1 represents Monday, 2 represents Tuesday and so on) tha...
Definition: qlocale.cpp:2158
DateFormat
Definition: qnamespace.h:1392