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