~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/corelib/tools/qdatetime.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the core module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qplatformdefs.h"
 
30
#include "private/qdatetime_p.h"
 
31
 
 
32
#include "qdatastream.h"
 
33
#include "qdatetime.h"
 
34
#include "qregexp.h"
 
35
#ifndef QT_NO_DEBUG_STREAM
 
36
#include "qdebug.h"
 
37
#endif
 
38
#if defined(Q_OS_WIN32)
 
39
#include <windows.h>
 
40
#include <time.h>
 
41
#endif
 
42
#ifndef Q_WS_WIN
 
43
#include <locale.h>
 
44
#endif
 
45
 
 
46
#if defined(Q_WS_MAC)
 
47
#include <private/qcore_mac_p.h>
 
48
extern QString qt_mac_from_pascal_string(const Str255); // qglobal.cpp
 
49
#endif
 
50
 
 
51
enum {
 
52
    FIRST_DAY = 2361222,        // Julian day for 1752-09-14
 
53
    FIRST_YEAR = 1752,
 
54
    SECS_PER_DAY = 86400,
 
55
    MSECS_PER_DAY = 86400000,
 
56
    SECS_PER_HOUR = 3600,
 
57
    MSECS_PER_HOUR = 3600000,
 
58
    SECS_PER_MIN = 60,
 
59
    MSECS_PER_MIN = 60000
 
60
};
 
61
 
 
62
static const short monthDays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
 
63
 
 
64
static const char * const qt_shortMonthNames[] = {
 
65
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
 
66
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
 
67
static const char * const qt_longMonthNames[] = {
 
68
    "January", "February", "Mars", "April", "May", "June",
 
69
    "July", "August", "September", "October", "November", "December" };
 
70
static const char * const qt_shortDayNames[] = {
 
71
    "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
 
72
static const char * const qt_longDayNames[] = {
 
73
    "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
 
74
 
 
75
static QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* dd = 0);
 
76
 
 
77
/*****************************************************************************
 
78
  QDate member functions
 
79
 *****************************************************************************/
 
80
 
 
81
/*!
 
82
    \class QDate
 
83
    \reentrant
 
84
    \brief The QDate class provides date functions.
 
85
 
 
86
    \ingroup time
 
87
    \mainclass
 
88
 
 
89
    A QDate object contains a calendar date, i.e. year, month, and day
 
90
    numbers, in the modern Western (Gregorian) calendar. It can read
 
91
    the current date from the system clock. It provides functions for
 
92
    comparing dates, and for manipulating dates. For example, it is
 
93
    possible to add and subtract days, months, and years to dates.
 
94
 
 
95
    A QDate object is typically created either by giving the year,
 
96
    month, and day numbers explicitly, or by using the static function
 
97
    currentDate() that creates a QDate object containing the system
 
98
    clock's date. An explicit date can also be set using setYMD(). The
 
99
    fromString() function returns a QDate given a string and a date
 
100
    format which is used to interpret the date within the string.
 
101
 
 
102
    The year(), month(), and day() functions provide access to the
 
103
    year, month, and day numbers. Also, dayOfWeek() and dayOfYear()
 
104
    functions are provided. The same information is provided in
 
105
    textual format by the toString(), shortDayName(), longDayName(),
 
106
    shortMonthName(), and longMonthName() functions.
 
107
 
 
108
    QDate provides a full set of operators to compare two QDate
 
109
    objects where smaller means earlier, and larger means later.
 
110
 
 
111
    You can increment (or decrement) a date by a given number of days
 
112
    using addDays(). Similarly you can use addMonths() and addYears().
 
113
    The daysTo() function returns the number of days between two
 
114
    dates.
 
115
 
 
116
    The daysInMonth() and daysInYear() functions return how many days
 
117
    there are in this date's month and year, respectively. The
 
118
    isLeapYear() function indicates whether this date is in a leap year.
 
119
 
 
120
    Note that QDate should not be used for date calculations for dates
 
121
    prior to the introduction of the Gregorian calendar. This calendar
 
122
    was adopted by England from the 14 September 1752 (hence this is
 
123
    the earliest valid QDate), and subsequently by most other Western
 
124
    countries, by 1923.
 
125
 
 
126
    The latest valid year within this scheme is the year 8000.
 
127
 
 
128
    \sa QTime QDateTime QDateEdit QDateTimeEdit
 
129
*/
 
130
 
 
131
/*!
 
132
    \fn QDate::QDate()
 
133
 
 
134
    Constructs a null date. Null dates are invalid.
 
135
 
 
136
    \sa isNull(), isValid()
 
137
*/
 
138
 
 
139
 
 
140
/*!
 
141
    Constructs a date with year \a y, month \a m and day \a d.
 
142
 
 
143
    \a y must be in the range 1752 to 8000, \a m must be in the range
 
144
    1 to 12, and \a d must be in the range 1 to 31.
 
145
 
 
146
    \warning If \a y is in the range 0 to 99, it is interpreted as
 
147
     a year in the range 1900 to 1999.
 
148
 
 
149
    \sa isValid()
 
150
*/
 
151
 
 
152
QDate::QDate(int y, int m, int d)
 
153
{
 
154
    jd = 0;
 
155
    setYMD(y, m, d);
 
156
}
 
157
 
 
158
 
 
159
/*!
 
160
    \fn bool QDate::isNull() const
 
161
 
 
162
    Returns true if the date is null; otherwise returns false. A null
 
163
    date is invalid.
 
164
 
 
165
    \sa isValid()
 
166
*/
 
167
 
 
168
 
 
169
/*!
 
170
    Returns true if this date is valid; otherwise returns false.
 
171
 
 
172
    \sa isNull()
 
173
*/
 
174
 
 
175
bool QDate::isValid() const
 
176
{
 
177
    return jd >= FIRST_DAY;
 
178
}
 
179
 
 
180
 
 
181
/*!
 
182
    Returns the year (1752 to 8000) of this date.
 
183
 
 
184
    \sa month(), day()
 
185
*/
 
186
 
 
187
int QDate::year() const
 
188
{
 
189
    int y, m, d;
 
190
    julianToGregorian(jd, y, m, d);
 
191
    return y;
 
192
}
 
193
 
 
194
/*!
 
195
    Returns the number corresponding to the month of this date, using
 
196
    the following convention:
 
197
 
 
198
    \list
 
199
    \i 1 = "January"
 
200
    \i 2 = "February"
 
201
    \i 3 = "March"
 
202
    \i 4 = "April"
 
203
    \i 5 = "May"
 
204
    \i 6 = "June"
 
205
    \i 7 = "July"
 
206
    \i 8 = "August"
 
207
    \i 9 = "September"
 
208
    \i 10 = "October"
 
209
    \i 11 = "November"
 
210
    \i 12 = "December"
 
211
    \endlist
 
212
 
 
213
    \sa year(), day()
 
214
*/
 
215
 
 
216
int QDate::month() const
 
217
{
 
218
    int y, m, d;
 
219
    julianToGregorian(jd, y, m, d);
 
220
    return m;
 
221
}
 
222
 
 
223
/*!
 
224
    Returns the day of the month (1 to 31) of this date.
 
225
 
 
226
    \sa year(), month(), dayOfWeek()
 
227
*/
 
228
 
 
229
int QDate::day() const
 
230
{
 
231
    int y, m, d;
 
232
    julianToGregorian(jd, y, m, d);
 
233
    return d;
 
234
}
 
235
 
 
236
/*!
 
237
    Returns the weekday for this date.
 
238
 
 
239
    \sa day(), dayOfYear(), Qt::DayOfWeek
 
240
*/
 
241
 
 
242
int QDate::dayOfWeek() const
 
243
{
 
244
    return (jd % 7) + 1;
 
245
}
 
246
 
 
247
/*!
 
248
    Returns the day of the year (1 to 365) for this date.
 
249
 
 
250
    \sa day(), dayOfWeek()
 
251
*/
 
252
 
 
253
int QDate::dayOfYear() const
 
254
{
 
255
    return jd - gregorianToJulian(year(), 1, 1) + 1;
 
256
}
 
257
 
 
258
/*!
 
259
    Returns the number of days in the month (28 to 31) for this date.
 
260
 
 
261
    \sa day(), daysInYear()
 
262
*/
 
263
 
 
264
int QDate::daysInMonth() const
 
265
{
 
266
    int y, m, d;
 
267
    julianToGregorian(jd, y, m, d);
 
268
    if (m == 2 && isLeapYear(y))
 
269
        return 29;
 
270
    else
 
271
        return monthDays[m];
 
272
}
 
273
 
 
274
/*!
 
275
    Returns the number of days in the year (365 or 366) for this date.
 
276
 
 
277
    \sa day(), daysInMonth()
 
278
*/
 
279
 
 
280
int QDate::daysInYear() const
 
281
{
 
282
    int y, m, d;
 
283
    julianToGregorian(jd, y, m, d);
 
284
    return isLeapYear(y) ? 366 : 365;
 
285
}
 
286
 
 
287
/*!
 
288
    Returns the week number (1 to 53), and stores the year in
 
289
    *\a{yearNumber} unless \a yearNumber is null (the default).
 
290
 
 
291
    Returns 0 if the date is invalid.
 
292
 
 
293
    In accordance with ISO 8601, weeks start on Qt::Monday and the first
 
294
    Qt::Thursday of a year is always in week 1 of that year. Most years
 
295
    have 52 weeks, but some have 53.
 
296
 
 
297
    *\a{yearNumber} is not always the same as year(). For example, 1
 
298
    January 2000 has week number 52 in the year 1999, and 31 December
 
299
    2002 has week number 1 in the year 2003.
 
300
 
 
301
    \legalese
 
302
    \code
 
303
 
 
304
    Copyright (c) 1989 The Regents of the University of California.
 
305
    All rights reserved.
 
306
 
 
307
    Redistribution and use in source and binary forms are permitted
 
308
    provided that the above copyright notice and this paragraph are
 
309
    duplicated in all such forms and that any documentation,
 
310
    advertising materials, and other materials related to such
 
311
    distribution and use acknowledge that the software was developed
 
312
    by the University of California, Berkeley.  The name of the
 
313
    University may not be used to endorse or promote products derived
 
314
    from this software without specific prior written permission.
 
315
    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 
316
    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 
317
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
318
    \endcode
 
319
 
 
320
    \sa isValid()
 
321
*/
 
322
 
 
323
int QDate::weekNumber(int *yearNumber) const
 
324
{
 
325
    if (!isValid())
 
326
        return 0;
 
327
 
 
328
    int year = QDate::year();
 
329
    int yday = dayOfYear() - 1;
 
330
    int wday = dayOfWeek();
 
331
    if (wday == 7)
 
332
        wday = 0;
 
333
    int w;
 
334
 
 
335
    for (;;) {
 
336
        int len;
 
337
        int bot;
 
338
        int top;
 
339
 
 
340
        len = isLeapYear(year) ? 366 : 365;
 
341
        /*
 
342
        ** What yday (-3 ... 3) does
 
343
        ** the ISO year begin on?
 
344
        */
 
345
        bot = ((yday + 11 - wday) % 7) - 3;
 
346
        /*
 
347
        ** What yday does the NEXT
 
348
        ** ISO year begin on?
 
349
        */
 
350
        top = bot - (len % 7);
 
351
        if (top < -3)
 
352
            top += 7;
 
353
        top += len;
 
354
        if (yday >= top) {
 
355
            ++year;
 
356
            w = 1;
 
357
            break;
 
358
        }
 
359
        if (yday >= bot) {
 
360
            w = 1 + ((yday - bot) / 7);
 
361
            break;
 
362
        }
 
363
        --year;
 
364
        yday += isLeapYear(year) ? 366 : 365;
 
365
    }
 
366
    if (yearNumber != 0)
 
367
        *yearNumber = year;
 
368
    return w;
 
369
}
 
370
 
 
371
#ifndef QT_NO_TEXTDATE
 
372
/*!
 
373
    Returns the name of the \a month using the following
 
374
    convention:
 
375
 
 
376
    \list
 
377
    \i 1 = "Jan"
 
378
    \i 2 = "Feb"
 
379
    \i 3 = "Mar"
 
380
    \i 4 = "Apr"
 
381
    \i 5 = "May"
 
382
    \i 6 = "Jun"
 
383
    \i 7 = "Jul"
 
384
    \i 8 = "Aug"
 
385
    \i 9 = "Sep"
 
386
    \i 10 = "Oct"
 
387
    \i 11 = "Nov"
 
388
    \i 12 = "Dec"
 
389
    \endlist
 
390
 
 
391
    The month names will be localized according to the system's locale
 
392
    settings.
 
393
 
 
394
    \sa toString(), longMonthName(), shortDayName(), longDayName()
 
395
*/
 
396
 
 
397
QString QDate::shortMonthName(int month)
 
398
{
 
399
    if (month < 1 || month > 12) {
 
400
        qWarning("QDate::shortMonthName: Parameter out ouf range");
 
401
        month = 1;
 
402
    }
 
403
#ifndef Q_WS_WIN
 
404
    char buffer[255];
 
405
    tm tt;
 
406
    memset(&tt, 0, sizeof(tm));
 
407
    tt.tm_mon = month - 1;
 
408
    const QByteArray lctime(setlocale(LC_TIME, ""));
 
409
    if (strftime(buffer, sizeof(buffer), "%b", &tt)) {
 
410
        setlocale(LC_TIME, lctime.data());
 
411
        return QString::fromLocal8Bit(buffer);
 
412
    }
 
413
    setlocale(LC_TIME, lctime.data());
 
414
#else
 
415
    SYSTEMTIME st;
 
416
    memset(&st, 0, sizeof(SYSTEMTIME));
 
417
    st.wYear = 2000;
 
418
    st.wMonth = month;
 
419
    st.wDay = 1;
 
420
    const wchar_t mmm_t[] = L"MMM"; // workaround for Borland
 
421
    QT_WA({
 
422
        TCHAR buf[255];
 
423
        if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, mmm_t, buf, 255))
 
424
            return QString::fromUtf16((ushort*)buf);
 
425
    } , {
 
426
        char buf[255];
 
427
        if (GetDateFormatA(LOCALE_USER_DEFAULT, 0, &st, "MMM", (char*)&buf, 255))
 
428
            return QString::fromLocal8Bit(buf);
 
429
    });
 
430
#endif
 
431
    return QString();
 
432
}
 
433
 
 
434
/*!
 
435
    Returns the long name of the \a month using the following
 
436
    convention:
 
437
 
 
438
    \list
 
439
    \i 1 = "January"
 
440
    \i 2 = "February"
 
441
    \i 3 = "March"
 
442
    \i 4 = "April"
 
443
    \i 5 = "May"
 
444
    \i 6 = "June"
 
445
    \i 7 = "July"
 
446
    \i 8 = "August"
 
447
    \i 9 = "September"
 
448
    \i 10 = "October"
 
449
    \i 11 = "November"
 
450
    \i 12 = "December"
 
451
    \endlist
 
452
 
 
453
    The month names will be localized according to the system's locale
 
454
    settings.
 
455
 
 
456
    \sa toString(), shortMonthName(), shortDayName(), longDayName()
 
457
*/
 
458
 
 
459
QString QDate::longMonthName(int month)
 
460
{
 
461
    if (month < 1 || month > 12) {
 
462
        qWarning("QDate::longMonthName: Parameter out ouf range");
 
463
        month = 1;
 
464
    }
 
465
#ifndef Q_WS_WIN
 
466
    char buffer[255];
 
467
    tm tt;
 
468
    memset(&tt, 0, sizeof(tm));
 
469
    tt.tm_mon = month - 1;
 
470
    const QByteArray lctime(setlocale(LC_TIME, ""));
 
471
    if (strftime(buffer, sizeof(buffer), "%B", &tt)) {
 
472
        setlocale(LC_TIME, lctime.data());
 
473
        return QString::fromLocal8Bit(buffer);
 
474
    }
 
475
    setlocale(LC_TIME, lctime.data());
 
476
#else
 
477
    SYSTEMTIME st;
 
478
    memset(&st, 0, sizeof(SYSTEMTIME));
 
479
    st.wYear = 2000;
 
480
    st.wMonth = month;
 
481
    st.wDay = 1;
 
482
    const wchar_t mmmm_t[] = L"MMMM"; // workaround for Borland
 
483
    QT_WA({
 
484
        TCHAR buf[255];
 
485
        if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, mmmm_t, buf, 255))
 
486
            return QString::fromUtf16((ushort*)buf);
 
487
    } , {
 
488
        char buf[255];
 
489
        if (GetDateFormatA(LOCALE_USER_DEFAULT, 0, &st, "MMMM", (char*)&buf, 255))
 
490
            return QString::fromLocal8Bit(buf);
 
491
    })
 
492
#endif
 
493
    return QString();
 
494
}
 
495
 
 
496
/*!
 
497
    Returns the name of the \a weekday using the following
 
498
    convention:
 
499
 
 
500
    \list
 
501
    \i 1 = "Mon"
 
502
    \i 2 = "Tue"
 
503
    \i 3 = "Wed"
 
504
    \i 4 = "Thu"
 
505
    \i 5 = "Fri"
 
506
    \i 6 = "Sat"
 
507
    \i 7 = "Sun"
 
508
    \endlist
 
509
 
 
510
    The day names will be localized according to the system's locale
 
511
    settings.
 
512
 
 
513
    \sa toString(), shortMonthName(), longMonthName(), longDayName()
 
514
*/
 
515
 
 
516
QString QDate::shortDayName(int weekday)
 
517
{
 
518
    if (weekday < 1 || weekday > 7) {
 
519
        qWarning("QDate::shortDayName: Parameter out of range");
 
520
        weekday = 1;
 
521
    }
 
522
#ifndef Q_WS_WIN
 
523
    char buffer[255];
 
524
    tm tt;
 
525
    memset(&tt, 0, sizeof(tm));
 
526
    tt.tm_wday = (weekday == 7) ? 0 : weekday;
 
527
    const QByteArray lctime(setlocale(LC_TIME, ""));
 
528
    if (strftime(buffer, sizeof(buffer), "%a", &tt)) {
 
529
        setlocale(LC_TIME, lctime.data());
 
530
        return QString::fromLocal8Bit(buffer);
 
531
    }
 
532
    setlocale(LC_TIME, lctime.data());
 
533
 
 
534
#else
 
535
    SYSTEMTIME st;
 
536
    memset(&st, 0, sizeof(SYSTEMTIME));
 
537
    st.wYear = 2001;
 
538
    st.wMonth = 10;
 
539
    st.wDayOfWeek = (weekday == 7) ? 0 : weekday;
 
540
    st.wDay = 21 + st.wDayOfWeek;
 
541
    const wchar_t ddd_t[] = L"ddd"; // workaround for Borland
 
542
    QT_WA({
 
543
        TCHAR buf[255];
 
544
        if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, ddd_t, buf, 255))
 
545
            return QString::fromUtf16((ushort*)buf);
 
546
    } , {
 
547
        char buf[255];
 
548
        if (GetDateFormatA(LOCALE_USER_DEFAULT, 0, &st, "ddd", (char*)&buf, 255))
 
549
            return QString::fromLocal8Bit(buf);
 
550
    });
 
551
#endif
 
552
    return QString();
 
553
}
 
554
 
 
555
/*!
 
556
    Returns the long name of the \a weekday using the following
 
557
    convention:
 
558
 
 
559
    \list
 
560
    \i 1 = "Monday"
 
561
    \i 2 = "Tuesday"
 
562
    \i 3 = "Wednesday"
 
563
    \i 4 = "Thursday"
 
564
    \i 5 = "Friday"
 
565
    \i 6 = "Saturday"
 
566
    \i 7 = "Sunday"
 
567
    \endlist
 
568
 
 
569
    The day names will be localized according to the system's locale
 
570
    settings.
 
571
 
 
572
    \sa toString(), shortDayName(), shortMonthName(), longMonthName()
 
573
*/
 
574
 
 
575
QString QDate::longDayName(int weekday)
 
576
{
 
577
    if (weekday < 1 || weekday > 7) {
 
578
        qWarning("QDate::longDayName: Parameter out of range");
 
579
        weekday = 1;
 
580
    }
 
581
#ifndef Q_WS_WIN
 
582
    char buffer[255];
 
583
    tm tt;
 
584
    memset(&tt, 0, sizeof(tm));
 
585
    tt.tm_wday = (weekday == 7) ? 0 : weekday;
 
586
    const QByteArray lctime(setlocale(LC_TIME, ""));
 
587
    if (strftime(buffer, sizeof(buffer), "%A", &tt)) {
 
588
        setlocale(LC_TIME, lctime.data());
 
589
        return QString::fromLocal8Bit(buffer);
 
590
    }
 
591
    setlocale(LC_TIME, lctime.data());
 
592
#else
 
593
    SYSTEMTIME st;
 
594
    memset(&st, 0, sizeof(SYSTEMTIME));
 
595
    st.wYear = 2001;
 
596
    st.wMonth = 10;
 
597
    st.wDayOfWeek = (weekday == 7) ? 0 : weekday;
 
598
    st.wDay = 21 + st.wDayOfWeek;
 
599
    const wchar_t dddd_t[] = L"dddd"; // workaround for Borland
 
600
    QT_WA({
 
601
        TCHAR buf[255];
 
602
        if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, dddd_t, buf, 255))
 
603
            return QString::fromUtf16((ushort*)buf);
 
604
    } , {
 
605
        char buf[255];
 
606
        if (GetDateFormatA(LOCALE_USER_DEFAULT, 0, &st, "dddd", (char*)&buf, 255))
 
607
            return QString::fromLocal8Bit(buf);
 
608
    });
 
609
#endif
 
610
    return QString();
 
611
}
 
612
#endif //QT_NO_TEXTDATE
 
613
 
 
614
#ifndef QT_NO_DATESTRING
 
615
 
 
616
/*!
 
617
    \fn QString QDate::toString(Qt::DateFormat format) const
 
618
 
 
619
    \overload
 
620
 
 
621
    Returns the date as a string. The \a format parameter determines
 
622
    the format of the string.
 
623
 
 
624
    If the \a format is \c Qt::TextDate, the string is formatted in
 
625
    the default way. QDate::shortDayName() and QDate::shortMonthName()
 
626
    are used to generate the string, so the day and month names will
 
627
    be localized names. An example of this formatting is
 
628
    "Sat May 20 1995".
 
629
 
 
630
    If the \a format is \c Qt::ISODate, the string format corresponds
 
631
    to the ISO 8601 extended specification for representations of
 
632
    dates and times, taking the form YYYY-MM-DD, where YYYY is the
 
633
    year, MM is the month of the year (between 01 and 12), and DD is
 
634
    the day of the month between 01 and 31.
 
635
 
 
636
    If the \a format is \c Qt::LocalDate, the string format depends
 
637
    on the locale settings of the system.
 
638
 
 
639
    If the datetime is invalid, an empty string will be returned.
 
640
 
 
641
    \sa shortDayName(), shortMonthName()
 
642
*/
 
643
QString QDate::toString(Qt::DateFormat f) const
 
644
{
 
645
    if (!isValid())
 
646
        return QString();
 
647
    int y, m, d;
 
648
    julianToGregorian(jd, y, m, d);
 
649
    switch (f) {
 
650
    case Qt::LocalDate:
 
651
        {
 
652
#ifdef Q_WS_WIN
 
653
            SYSTEMTIME st;
 
654
            memset(&st, 0, sizeof(SYSTEMTIME));
 
655
            st.wYear = year();
 
656
            st.wMonth = month();
 
657
            st.wDay = day();
 
658
            QT_WA({
 
659
                TCHAR buf[255];
 
660
                if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, 0, buf, 255))
 
661
                    return QString::fromUtf16((ushort*)buf);
 
662
            } , {
 
663
                char buf[255];
 
664
                if (GetDateFormatA(LOCALE_USER_DEFAULT, 0, &st, 0, (char*)&buf, 255))
 
665
                    return QString::fromLocal8Bit(buf);
 
666
            });
 
667
#elif defined(Q_WS_MAC)
 
668
            CFGregorianDate macGDate;
 
669
            macGDate.year = year();
 
670
            macGDate.month = month();
 
671
            macGDate.day = day();
 
672
            macGDate.hour = 0;
 
673
            macGDate.minute = 0;
 
674
            macGDate.second = 0.0;
 
675
            QCFType<CFDateRef> myDate = CFDateCreate(0, CFGregorianDateGetAbsoluteTime(macGDate, 0));
 
676
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
 
677
            if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_3) {
 
678
                QCFType<CFLocaleRef> mylocale = CFLocaleCopyCurrent();
 
679
                QCFType<CFDateFormatterRef> myFormatter = CFDateFormatterCreate(kCFAllocatorDefault,
 
680
                                                                                mylocale, kCFDateFormatterLongStyle,
 
681
                                                                                kCFDateFormatterNoStyle);
 
682
                return QCFString(CFDateFormatterCreateStringWithDate(0, myFormatter, myDate));
 
683
            } else
 
684
#endif
 
685
            {
 
686
                Handle intlHandle = GetIntlResource(1);
 
687
                LongDateTime oldDate;
 
688
                UCConvertCFAbsoluteTimeToLongDateTime(CFGregorianDateGetAbsoluteTime(macGDate, 0),
 
689
                                                      &oldDate);
 
690
                Str255 pString;
 
691
                LongDateString(&oldDate, longDate, pString, intlHandle);
 
692
                return qt_mac_from_pascal_string(pString);
 
693
            }
 
694
#else
 
695
            tm tt;
 
696
            memset(&tt, 0, sizeof(tm));
 
697
            char buf[255];
 
698
            tt.tm_mday = day();
 
699
            tt.tm_mon = month() - 1;
 
700
            tt.tm_year = year() - 1900;
 
701
 
 
702
            const char *avoidEgcsWarning = "%x";
 
703
            const QByteArray lctime(setlocale(LC_TIME, ""));
 
704
            if (strftime(buf, sizeof(buf), avoidEgcsWarning, &tt)) {
 
705
                setlocale(LC_TIME, lctime.data());
 
706
                return QString::fromLocal8Bit(buf);
 
707
            }
 
708
            setlocale(LC_TIME, lctime.data());
 
709
#endif
 
710
            return QString();
 
711
        }
 
712
    default:
 
713
#ifndef QT_NO_TEXTDATE
 
714
    case Qt::TextDate:
 
715
        {
 
716
            return QString::fromLatin1("%0 %1 %2 %3")
 
717
                .arg(shortDayName(dayOfWeek()))
 
718
                .arg(shortMonthName(m))
 
719
                .arg(d)
 
720
                .arg(y);
 
721
        }
 
722
#endif
 
723
    case Qt::ISODate:
 
724
        {
 
725
            QString month(QString::number(m).rightJustified(2, QLatin1Char('0')));
 
726
            QString day(QString::number(d).rightJustified(2, QLatin1Char('0')));
 
727
            return QString::number(y) + QLatin1Char('-') + month + QLatin1Char('-') + day;
 
728
        }
 
729
    }
 
730
}
 
731
 
 
732
/*!
 
733
    Returns the date as a string. The \a format parameter determines
 
734
    the format of the result string.
 
735
 
 
736
    These expressions may be used:
 
737
 
 
738
    \table
 
739
    \header \i Expression \i Output
 
740
    \row \i d \i the day as number without a leading zero (1 to31)
 
741
    \row \i dd \i the day as number with a leading zero (01 to 31)
 
742
    \row \i ddd
 
743
         \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
 
744
            Uses QDate::shortDayName().
 
745
    \row \i dddd
 
746
         \i the long localized day name (e.g. 'Qt::Monday' to 'Qt::Sunday').
 
747
            Uses QDate::longDayName().
 
748
    \row \i M \i the month as number without a leading zero (1-12)
 
749
    \row \i MM \i the month as number with a leading zero (01-12)
 
750
    \row \i MMM
 
751
         \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
 
752
            Uses QDate::shortMonthName().
 
753
    \row \i MMMM
 
754
         \i the long localized month name (e.g. 'January' to 'December').
 
755
            Uses QDate::longMonthName().
 
756
    \row \i yy \i the year as two digit number (00 to 99)
 
757
    \row \i yyyy \i the year as four digit number (1752 to 8000)
 
758
    \endtable
 
759
 
 
760
    All other input characters will be ignored. Any sequence of characters that
 
761
    are enclosed in singlequotes will be treated as text and not be used as an
 
762
    expression.
 
763
 
 
764
    Example format strings (assuming that the QDate is the 20 July
 
765
    1969):
 
766
 
 
767
    \table
 
768
    \header \o Format            \o Result
 
769
    \row    \o dd.MM.yyyy        \o 20.07.1969
 
770
    \row    \o ddd MMMM d yy     \o Sun July 20 69
 
771
    \row    \o 'The day is' dddd \o The day is Sunday
 
772
    \endtable
 
773
 
 
774
    If the datetime is invalid, an empty string will be returned.
 
775
 
 
776
    \sa QDateTime::toString() QTime::toString()
 
777
 
 
778
*/
 
779
QString QDate::toString(const QString& format) const
 
780
{
 
781
    return fmtDateTime(format, 0, this);
 
782
}
 
783
#endif //QT_NO_DATESTRING
 
784
 
 
785
/*!
 
786
    Sets the date's year \a y, month \a m, and day \a d.
 
787
 
 
788
    \a y must be in the range 1752 to 8000, \a m must be in the range
 
789
    1 to 12, and \a d must be in the range 1 to 31.
 
790
 
 
791
    \warning If \a y is in the range 0 to 99, it is interpreted as
 
792
    1900 to 1999.
 
793
 
 
794
    Returns true if the date is valid; otherwise returns false.
 
795
*/
 
796
 
 
797
bool QDate::setYMD(int y, int m, int d)
 
798
{
 
799
    if (year() == y && month() == m && day() == d)
 
800
        return isValid();
 
801
    if (!isValid(y,m,d)) {
 
802
        jd = 0;
 
803
        return false;
 
804
    }
 
805
    jd = gregorianToJulian(y, m, d);
 
806
    return true;
 
807
}
 
808
 
 
809
/*!
 
810
    Returns a QDate object containing a date \a ndays later than the
 
811
    date of this object (or earlier if \a ndays is negative).
 
812
 
 
813
    \sa addMonths() addYears() daysTo()
 
814
*/
 
815
 
 
816
QDate QDate::addDays(int ndays) const
 
817
{
 
818
    QDate d;
 
819
    d.jd = jd + ndays;
 
820
    return d;
 
821
}
 
822
 
 
823
/*!
 
824
    Returns a QDate object containing a date \a nmonths later than the
 
825
    date of this object (or earlier if \a nmonths is negative).
 
826
 
 
827
    \sa addDays() addYears()
 
828
*/
 
829
 
 
830
QDate QDate::addMonths(int nmonths) const
 
831
{
 
832
    int y, m, d;
 
833
    julianToGregorian(jd, y, m, d);
 
834
 
 
835
    while (nmonths != 0) {
 
836
        if (nmonths < 0 && nmonths + 12 <= 0) {
 
837
            y--;
 
838
            nmonths+=12;
 
839
        } else if (nmonths < 0) {
 
840
            m+= nmonths;
 
841
            nmonths = 0;
 
842
            if (m <= 0) {
 
843
                --y;
 
844
                m+=12;
 
845
            }
 
846
        } else if (nmonths - 12 >= 0) {
 
847
            y++;
 
848
            nmonths -= 12;
 
849
        } else if (m == 12) {
 
850
            y++;
 
851
            m = 0;
 
852
        } else {
 
853
            m+= nmonths;
 
854
            nmonths = 0;
 
855
            if (m > 12) {
 
856
                ++y;
 
857
                m -= 12;
 
858
            }
 
859
        }
 
860
    }
 
861
 
 
862
    QDate tmp(y, m, 1);
 
863
    if (d > tmp.daysInMonth())
 
864
        d = tmp.daysInMonth();
 
865
 
 
866
    return QDate(y, m, d);
 
867
}
 
868
 
 
869
/*!
 
870
    Returns a QDate object containing a date \a nyears later than the
 
871
    date of this object (or earlier if \a nyears is negative).
 
872
 
 
873
    \sa addDays(), addMonths()
 
874
*/
 
875
 
 
876
QDate QDate::addYears(int nyears) const
 
877
{
 
878
    int y, m, d;
 
879
    julianToGregorian(jd, y, m, d);
 
880
    y += nyears;
 
881
 
 
882
    QDate tmp(y,m,1);
 
883
 
 
884
    if(d > tmp.daysInMonth())
 
885
        d = tmp.daysInMonth();
 
886
 
 
887
    QDate date(y, m, d);
 
888
    return date;
 
889
}
 
890
 
 
891
 
 
892
 
 
893
/*!
 
894
    Returns the number of days from this date to \a d (which is
 
895
    negative if \a d is earlier than this date).
 
896
 
 
897
    Example:
 
898
    \code
 
899
        QDate d1(1995, 5, 17);  // May 17, 1995
 
900
        QDate d2(1995, 5, 20);  // May 20, 1995
 
901
        d1.daysTo(d2);          // returns 3
 
902
        d2.daysTo(d1);          // returns -3
 
903
    \endcode
 
904
 
 
905
    \sa addDays()
 
906
*/
 
907
 
 
908
int QDate::daysTo(const QDate &d) const
 
909
{
 
910
    return d.jd - jd;
 
911
}
 
912
 
 
913
 
 
914
/*!
 
915
    \fn bool QDate::operator==(const QDate &d) const
 
916
 
 
917
    Returns true if this date is equal to \a d; otherwise returns
 
918
    false.
 
919
*/
 
920
 
 
921
/*!
 
922
    \fn bool QDate::operator!=(const QDate &d) const
 
923
 
 
924
    Returns true if this date is different from \a d; otherwise
 
925
    returns false.
 
926
*/
 
927
 
 
928
/*!
 
929
    \fn bool QDate::operator<(const QDate &d) const
 
930
 
 
931
    Returns true if this date is earlier than \a d; otherwise returns
 
932
    false.
 
933
*/
 
934
 
 
935
/*!
 
936
    \fn bool QDate::operator<=(const QDate &d) const
 
937
 
 
938
    Returns true if this date is earlier than or equal to \a d;
 
939
    otherwise returns false.
 
940
*/
 
941
 
 
942
/*!
 
943
    \fn bool QDate::operator>(const QDate &d) const
 
944
 
 
945
    Returns true if this date is later than \a d; otherwise returns
 
946
    false.
 
947
*/
 
948
 
 
949
/*!
 
950
    \fn bool QDate::operator>=(const QDate &d) const
 
951
 
 
952
    Returns true if this date is later than or equal to \a d;
 
953
    otherwise returns false.
 
954
*/
 
955
 
 
956
/*!
 
957
    \overload
 
958
    Returns the current date, as reported by the system clock.
 
959
 
 
960
    \sa QTime::currentTime(), QDateTime::currentDateTime()
 
961
*/
 
962
 
 
963
QDate QDate::currentDate()
 
964
{
 
965
    QDate d;
 
966
#if defined(Q_OS_WIN32)
 
967
    SYSTEMTIME st;
 
968
    memset(&st, 0, sizeof(SYSTEMTIME));
 
969
    GetLocalTime(&st);
 
970
    d.jd = QDate::gregorianToJulian(st.wYear, st.wMonth, st.wDay);
 
971
#else
 
972
    // posix compliant system
 
973
    time_t ltime;
 
974
    time(&ltime);
 
975
    tm *t;
 
976
 
 
977
#if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
 
978
    // use the reentrant version of localtime() where available
 
979
    tm res;
 
980
    t = localtime_r(&ltime, &res);
 
981
#else
 
982
    t = localtime(&ltime);
 
983
#endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
 
984
 
 
985
    d.jd = gregorianToJulian(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
 
986
#endif
 
987
    return d;
 
988
}
 
989
 
 
990
#ifndef QT_NO_DATESTRING
 
991
/*!
 
992
    \fn QDate QDate::fromString(const QString &string, Qt::DateFormat format)
 
993
 
 
994
    Returns the QDate represented by the \a string, using the
 
995
    \a format given, or an invalid date if the string cannot be
 
996
    parsed.
 
997
 
 
998
    Note for \c Qt::TextDate: It is recommended that you use the
 
999
    English short month names (e.g. "Jan"). Although localized month
 
1000
    names can also be used, they depend on the user's locale settings.
 
1001
 
 
1002
    \warning \c Qt::LocalDate cannot be used here.
 
1003
*/
 
1004
QDate QDate::fromString(const QString& s, Qt::DateFormat f)
 
1005
{
 
1006
    if ((s.isEmpty()) || (f == Qt::LocalDate)) {
 
1007
        QDate d;
 
1008
        d.jd = 0;
 
1009
        return d;
 
1010
    }
 
1011
    switch (f) {
 
1012
    case Qt::ISODate:
 
1013
        {
 
1014
            int year(s.mid(0, 4).toInt());
 
1015
            int month(s.mid(5, 2).toInt());
 
1016
            int day(s.mid(8, 2).toInt());
 
1017
            if (year && month && day)
 
1018
                return QDate(year, month, day);
 
1019
        }
 
1020
        break;
 
1021
    default:
 
1022
#ifndef QT_NO_TEXTDATE
 
1023
    case Qt::TextDate:
 
1024
        {
 
1025
            /*
 
1026
              This will fail gracefully if the input string doesn't
 
1027
              contain any space.
 
1028
            */
 
1029
            int monthPos = s.indexOf(QLatin1Char(' ')) + 1;
 
1030
            int dayPos = s.indexOf(QLatin1Char(' '), monthPos) + 1;
 
1031
 
 
1032
            QString monthName(s.mid(monthPos, dayPos - monthPos - 1));
 
1033
            int month = -1;
 
1034
 
 
1035
            // try English names first
 
1036
            for (int i = 0; i < 12; i++) {
 
1037
                if (monthName == QLatin1String(qt_shortMonthNames[i])) {
 
1038
                    month = i + 1;
 
1039
                    break;
 
1040
                }
 
1041
            }
 
1042
 
 
1043
            // try the localized names
 
1044
            if (month == -1) {
 
1045
                for (int i = 0; i < 12; i++) {
 
1046
                    if (monthName == shortMonthName(i + 1)) {
 
1047
                        month = i + 1;
 
1048
                        break;
 
1049
                    }
 
1050
                }
 
1051
            }
 
1052
            if (month < 1 || month > 12) {
 
1053
                QDate d;
 
1054
                d.jd = 0;
 
1055
                return d;
 
1056
            }
 
1057
            int day = s.mid(dayPos, 2).trimmed().toInt();
 
1058
            int year = s.right(4).toInt();
 
1059
            return QDate(year, month, day);
 
1060
        }
 
1061
#else
 
1062
        break;
 
1063
#endif
 
1064
    }
 
1065
    return QDate();
 
1066
}
 
1067
#endif //QT_NO_DATESTRING
 
1068
 
 
1069
/*!
 
1070
    \fn QDate::fromString(const QString &string, const QString &format)
 
1071
 
 
1072
    Returns the QDate represented by the \a string, using the \a
 
1073
    format given, or an invalid date if the string cannot be parsed.
 
1074
 
 
1075
    These expressions may be used for the format:
 
1076
 
 
1077
    \table
 
1078
    \header \i Expression \i Output
 
1079
    \row \i d \i The day as a number without a leading zero (1 to 31)
 
1080
    \row \i dd \i The day as a number with a leading zero (01 to 31)
 
1081
    \row \i ddd
 
1082
         \i The abbreviated localized day name (e.g. 'Mon' to 'Sun').
 
1083
            Uses QDate::shortDayName().
 
1084
    \row \i dddd
 
1085
         \i The long localized day name (e.g. 'Monday' to 'Sunday').
 
1086
            Uses QDate::longDayName().
 
1087
    \row \i M \i The month as a number without a leading zero (1 to 12)
 
1088
    \row \i MM \i The month as a number with a leading zero (01 to 12)
 
1089
    \row \i MMM
 
1090
         \i The abbreviated localized month name (e.g. 'Jan' to 'Dec').
 
1091
            Uses QDate::shortMonthName().
 
1092
    \row \i MMMM
 
1093
         \i The long localized month name (e.g. 'January' to 'December').
 
1094
            Uses QDate::longMonthName().
 
1095
    \row \i yy \i The year as two digit number (00 to 99)
 
1096
    \row \i yyyy \i The year as four digit number (1752 to 8000)
 
1097
    \endtable
 
1098
 
 
1099
    All other input characters will be treated as text. Any sequence
 
1100
    of characters that are enclosed in single quotes will also be
 
1101
    treated as text and will not be used as an expression. For example:
 
1102
 
 
1103
    \code
 
1104
        QDate date = QDate::fromString("1MM12car2003", "d'MM'MMcaryyyy");
 
1105
        // date is 1 December 2003
 
1106
    \endcode
 
1107
 
 
1108
    If the format is not satisfied, an invalid QDate is returned. The
 
1109
    expressions that don't expect leading zeroes (d, M) will be
 
1110
    greedy. This means that they will use two digits even if this
 
1111
    will put them outside the accepted range of values and leaves too
 
1112
    few digits for other sections. For example, the following format
 
1113
    string could have meant January 30 but the M will grab two
 
1114
    digits, resulting in an invalid date:
 
1115
 
 
1116
    \code
 
1117
        QDate date = QDate::fromString("130", "Md"); // invalid
 
1118
    \endcode
 
1119
 
 
1120
    For any field that is not represented in the format the following
 
1121
    defaults are used:
 
1122
 
 
1123
    \table
 
1124
    \header \i Field  \i Default value
 
1125
    \row    \i Year   \i The current year
 
1126
    \row    \i Month  \i 1
 
1127
    \row    \i Day    \i 1
 
1128
    \endtable
 
1129
 
 
1130
    The following examples demonstrate the default values:
 
1131
 
 
1132
    \code
 
1133
        QDate::fromString("1.30", "M.d");           // January 30 in the current year
 
1134
        QDate::fromString("20000110", "yyyyMMdd");  // January 10, 2000
 
1135
        QDate::fromString("20000110", "yyyyMd");    // January 10, 2000
 
1136
    \endcode
 
1137
 
 
1138
    \sa QDateTime::fromString(), QTime::fromString(), QDate::toString(),
 
1139
        QDateTime::toString(), QTime::toString()
 
1140
*/
 
1141
 
 
1142
QDate QDate::fromString(const QString &string, const QString &format)
 
1143
{
 
1144
    QDateTimeParser dt(format, QVariant::Date);
 
1145
    QDate date;
 
1146
    return dt.fromString(string, &date, 0) ? date : QDate();
 
1147
}
 
1148
 
 
1149
/*!
 
1150
    \overload
 
1151
 
 
1152
    Returns true if the specified date (year \a y, month \a m, and day
 
1153
    \a d) is valid; otherwise returns false.
 
1154
 
 
1155
    Example:
 
1156
    \code
 
1157
        QDate::isValid(2002, 5, 17);  // true
 
1158
        QDate::isValid(2002, 2, 30);  // false (Feb 30 does not exist)
 
1159
        QDate::isValid(2004, 2, 29);  // true (2004 is a leap year)
 
1160
        QDate::isValid(1202, 6, 6);   // false (1202 is pre-Gregorian)
 
1161
    \endcode
 
1162
 
 
1163
    \warning A \a y value in the range 00 to 99 is interpreted as
 
1164
    1900 to 1999.
 
1165
 
 
1166
    \sa isNull(), setYMD()
 
1167
*/
 
1168
 
 
1169
bool QDate::isValid(int y, int m, int d)
 
1170
{
 
1171
    if (y >= 0 && y <= 99)
 
1172
        y += 1900;
 
1173
    else if (y < FIRST_YEAR || (y == FIRST_YEAR && (m < 9 || (m == 9 && d < 14))))
 
1174
        return false;
 
1175
    return (d > 0 && m > 0 && m <= 12) &&
 
1176
           (d <= monthDays[m] || (d == 29 && m == 2 && isLeapYear(y)));
 
1177
}
 
1178
 
 
1179
/*!
 
1180
    \fn bool QDate::isLeapYear(int year)
 
1181
 
 
1182
    Returns true if the specified \a year is a leap year; otherwise
 
1183
    returns false.
 
1184
*/
 
1185
 
 
1186
bool QDate::isLeapYear(int y)
 
1187
{
 
1188
    return y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
 
1189
}
 
1190
 
 
1191
/*!
 
1192
  \internal
 
1193
  Converts a Gregorian date to a Julian day.
 
1194
  This algorithm is taken from Communications of the ACM, Vol 6, No 8.
 
1195
  \sa julianToGregorian()
 
1196
*/
 
1197
 
 
1198
uint QDate::gregorianToJulian(int y, int m, int d)
 
1199
{
 
1200
    uint c, ya;
 
1201
    if (y <= 99)
 
1202
        y += 1900;
 
1203
    if (m > 2) {
 
1204
        m -= 3;
 
1205
    } else {
 
1206
        m += 9;
 
1207
        y--;
 
1208
    }
 
1209
    c = y;                                        // NOTE: Sym C++ 6.0 bug
 
1210
    c /= 100;
 
1211
    ya = y - 100*c;
 
1212
    return 1721119 + d + (146097*c)/4 + (1461*ya)/4 + (153*m+2)/5;
 
1213
}
 
1214
 
 
1215
/*!
 
1216
  \internal
 
1217
  Converts a Julian day to a Gregorian date.
 
1218
  This algorithm is taken from Communications of the ACM, Vol 6, No 8.
 
1219
  \sa gregorianToJulian()
 
1220
*/
 
1221
 
 
1222
void QDate::julianToGregorian(uint jd, int &y, int &m, int &d)
 
1223
{
 
1224
    uint x;
 
1225
    uint j = jd - 1721119;
 
1226
    y = (j*4 - 1)/146097;
 
1227
    j = j*4 - 146097*y - 1;
 
1228
    x = j/4;
 
1229
    j = (x*4 + 3) / 1461;
 
1230
    y = 100*y + j;
 
1231
    x = (x*4) + 3 - 1461*j;
 
1232
    x = (x + 4)/4;
 
1233
    m = (5*x - 3)/153;
 
1234
    x = 5*x - 3 - 153*m;
 
1235
    d = (x + 5)/5;
 
1236
    if (m < 10) {
 
1237
        m += 3;
 
1238
    } else {
 
1239
        m -= 9;
 
1240
        y++;
 
1241
    }
 
1242
}
 
1243
 
 
1244
/*! \fn static QDate QDate::fromJulianDay(int jd)
 
1245
 
 
1246
    Converts the Julian day \a jd to a QDate.
 
1247
 
 
1248
    \sa toJulianDay()
 
1249
*/
 
1250
 
 
1251
/*! \fn int QDate::toJulianDay() const
 
1252
 
 
1253
    Converts the date to a Julian day.
 
1254
 
 
1255
    \sa fromJulianDay()
 
1256
*/
 
1257
 
 
1258
/*****************************************************************************
 
1259
  QTime member functions
 
1260
 *****************************************************************************/
 
1261
 
 
1262
/*!
 
1263
    \class QTime
 
1264
    \reentrant
 
1265
 
 
1266
    \brief The QTime class provides clock time functions.
 
1267
 
 
1268
    \ingroup time
 
1269
    \mainclass
 
1270
 
 
1271
    A QTime object contains a clock time, i.e. the number of hours,
 
1272
    minutes, seconds, and milliseconds since midnight. It can read the
 
1273
    current time from the system clock and measure a span of elapsed
 
1274
    time. It provides functions for comparing times and for
 
1275
    manipulating a time by adding a number of (milli)seconds.
 
1276
 
 
1277
    QTime uses the 24-hour clock format; it has no concept of AM/PM.
 
1278
    It operates in local time; it knows nothing about time zones or
 
1279
    daylight savings time.
 
1280
 
 
1281
    A QTime object is typically created either by giving the number of
 
1282
    hours, minutes, seconds, and milliseconds explicitly, or by using
 
1283
    the static function currentTime(), which creates a QTime object
 
1284
    that contains the system's clock time. Note that the accuracy
 
1285
    depends on the accuracy of the underlying operating system; not
 
1286
    all systems provide 1-millisecond accuracy.
 
1287
 
 
1288
    The hour(), minute(), second(), and msec() functions provide
 
1289
    access to the number of hours, minutes, seconds, and milliseconds
 
1290
    of the time. The same information is provided in textual format by
 
1291
    the toString() function.
 
1292
 
 
1293
    QTime provides a full set of operators to compare two QTime
 
1294
    objects. One time is considered smaller than another if it is
 
1295
    earlier than the other.
 
1296
 
 
1297
    The time a given number of seconds or milliseconds later than a
 
1298
    given time can be found using the addSecs() or addMSecs()
 
1299
    functions. Correspondingly, the number of (milli)seconds between
 
1300
    two times can be found using the secsTo() or msecsTo() functions.
 
1301
 
 
1302
    QTime can be used to measure a span of elapsed time using the
 
1303
    start(), restart(), and elapsed() functions.
 
1304
 
 
1305
    \sa QDate, QDateTime
 
1306
*/
 
1307
 
 
1308
/*!
 
1309
    \fn QTime::QTime()
 
1310
 
 
1311
    Constructs the time 0 hours, minutes, seconds and milliseconds,
 
1312
    i.e. 00:00:00.000 (midnight). This is a valid time.
 
1313
 
 
1314
    \sa isValid()
 
1315
*/
 
1316
 
 
1317
/*!
 
1318
    Constructs a time with hour \a h, minute \a m, seconds \a s and
 
1319
    milliseconds \a ms.
 
1320
 
 
1321
    \a h must be in the range 0 to 23, \a m and \a s must be in the
 
1322
    range 0 to 59, and \a ms must be in the range 0 to 999.
 
1323
 
 
1324
    \sa isValid()
 
1325
*/
 
1326
 
 
1327
QTime::QTime(int h, int m, int s, int ms)
 
1328
{
 
1329
    setHMS(h, m, s, ms);
 
1330
}
 
1331
 
 
1332
 
 
1333
/*!
 
1334
    \fn bool QTime::isNull() const
 
1335
 
 
1336
    Returns true if the time is equal to 00:00:00.000; otherwise
 
1337
    returns false. A null time is valid.
 
1338
 
 
1339
    \sa isValid()
 
1340
*/
 
1341
 
 
1342
/*!
 
1343
    Returns true if the time is valid; otherwise returns false. For example,
 
1344
    the time 23:30:55.746 is valid, but 24:12:30 is invalid.
 
1345
 
 
1346
    \sa isNull()
 
1347
*/
 
1348
 
 
1349
bool QTime::isValid() const
 
1350
{
 
1351
    return ds < MSECS_PER_DAY;
 
1352
}
 
1353
 
 
1354
 
 
1355
/*!
 
1356
    Returns the hour part (0 to 23) of the time.
 
1357
 
 
1358
    \sa minute(), second(), msec()
 
1359
*/
 
1360
 
 
1361
int QTime::hour() const
 
1362
{
 
1363
    return ds / MSECS_PER_HOUR;
 
1364
}
 
1365
 
 
1366
/*!
 
1367
    Returns the minute part (0 to 59) of the time.
 
1368
 
 
1369
    \sa hour(), second(), msec()
 
1370
*/
 
1371
 
 
1372
int QTime::minute() const
 
1373
{
 
1374
    return (ds % MSECS_PER_HOUR)/MSECS_PER_MIN;
 
1375
}
 
1376
 
 
1377
/*!
 
1378
    Returns the second part (0 to 59) of the time.
 
1379
 
 
1380
    \sa hour(), minute(), msec()
 
1381
*/
 
1382
 
 
1383
int QTime::second() const
 
1384
{
 
1385
    return (ds / 1000)%SECS_PER_MIN;
 
1386
}
 
1387
 
 
1388
/*!
 
1389
    Returns the millisecond part (0 to 999) of the time.
 
1390
 
 
1391
    \sa hour(), minute(), second()
 
1392
*/
 
1393
 
 
1394
int QTime::msec() const
 
1395
{
 
1396
    return ds % 1000;
 
1397
}
 
1398
 
 
1399
#ifndef QT_NO_DATESTRING
 
1400
/*!
 
1401
    \overload
 
1402
 
 
1403
    Returns the time as a string. Milliseconds are not included. The
 
1404
    \a f parameter determines the format of the string.
 
1405
 
 
1406
    If \a f is \c Qt::TextDate, the string format is HH:MM:SS; e.g. 1
 
1407
    second before midnight would be "23:59:59".
 
1408
 
 
1409
    If \a f is \c Qt::ISODate, the string format corresponds to the
 
1410
    ISO 8601 extended specification for representations of dates,
 
1411
    which is also HH:MM:SS.
 
1412
 
 
1413
    If \a f is Qt::LocalDate, the string format depends on the locale
 
1414
    settings of the system.
 
1415
 
 
1416
    If the datetime is invalid, an empty string will be returned.
 
1417
*/
 
1418
 
 
1419
QString QTime::toString(Qt::DateFormat f) const
 
1420
{
 
1421
    if (!isValid())
 
1422
        return QString();
 
1423
 
 
1424
    switch (f) {
 
1425
    case Qt::LocalDate:
 
1426
        {
 
1427
#ifdef Q_WS_WIN
 
1428
            SYSTEMTIME st;
 
1429
            memset(&st, 0, sizeof(SYSTEMTIME));
 
1430
            st.wHour = hour();
 
1431
            st.wMinute = minute();
 
1432
            st.wSecond = second();
 
1433
            st.wMilliseconds = 0;
 
1434
            QT_WA({
 
1435
                TCHAR buf[255];
 
1436
                if (GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, 0, buf, 255))
 
1437
                    return QString::fromUtf16((ushort*)buf);
 
1438
            } , {
 
1439
                char buf[255];
 
1440
                if (GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, 0, (char*)&buf, 255))
 
1441
                    return QString::fromLocal8Bit(buf);
 
1442
            });
 
1443
#elif defined (Q_WS_MAC)
 
1444
            CFGregorianDate macGDate;
 
1445
            // Assume this is local time and the current date
 
1446
            QDate dt = QDate::currentDate();
 
1447
            macGDate.year = dt.year();
 
1448
            macGDate.month = dt.month();
 
1449
            macGDate.day = dt.day();
 
1450
            macGDate.hour = hour();
 
1451
            macGDate.minute = minute();
 
1452
            macGDate.second = second();
 
1453
            QCFType<CFTimeZoneRef> myTz = CFTimeZoneCopyDefault();
 
1454
            QCFType<CFDateRef> myDate = CFDateCreate(0,
 
1455
                                                     CFGregorianDateGetAbsoluteTime(macGDate,
 
1456
                                                                                    myTz));
 
1457
#  if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
 
1458
            if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_3) {
 
1459
 
 
1460
                QCFType<CFLocaleRef> mylocale = CFLocaleCopyCurrent();
 
1461
                QCFType<CFDateFormatterRef> myFormatter = CFDateFormatterCreate(kCFAllocatorDefault,
 
1462
                                                                       mylocale,
 
1463
                                                                       kCFDateFormatterNoStyle,
 
1464
                                                                       kCFDateFormatterMediumStyle);
 
1465
                return QCFString(CFDateFormatterCreateStringWithDate(0, myFormatter, myDate));
 
1466
            } else
 
1467
#  endif
 
1468
            {
 
1469
                // For Jaguar, must use the older non-recommended Stuff
 
1470
                Handle intlHandle = GetIntlResource(0);
 
1471
                LongDateTime oldDate;
 
1472
                UCConvertCFAbsoluteTimeToLongDateTime(CFGregorianDateGetAbsoluteTime(macGDate, myTz),
 
1473
                                                      &oldDate);
 
1474
                Str255 pString;
 
1475
                LongTimeString(&oldDate, true, pString, intlHandle);
 
1476
                return qt_mac_from_pascal_string(pString);
 
1477
            }
 
1478
#else
 
1479
            tm tt;
 
1480
            memset(&tt, 0, sizeof(tm));
 
1481
            char buf[255];
 
1482
            tt.tm_sec = second();
 
1483
            tt.tm_min = minute();
 
1484
            tt.tm_hour = hour();
 
1485
 
 
1486
            const QByteArray lctime(setlocale(LC_TIME, ""));
 
1487
            if (strftime(buf, sizeof(buf), "%X", &tt)) {
 
1488
                setlocale(LC_TIME, lctime.data());
 
1489
                return QString::fromLocal8Bit(buf);
 
1490
            }
 
1491
            setlocale(LC_TIME, lctime.data());
 
1492
#endif
 
1493
            return QString();
 
1494
        }
 
1495
    default:
 
1496
    case Qt::ISODate:
 
1497
    case Qt::TextDate:
 
1498
        return QString::fromLatin1("%1:%2:%3")
 
1499
            .arg(hour(), 2, 10, QLatin1Char('0'))
 
1500
            .arg(minute(), 2, 10, QLatin1Char('0'))
 
1501
            .arg(second(), 2, 10, QLatin1Char('0'));
 
1502
    }
 
1503
}
 
1504
 
 
1505
/*!
 
1506
    Returns the time as a string. The \a format parameter determines
 
1507
    the format of the result string.
 
1508
 
 
1509
    These expressions may be used:
 
1510
 
 
1511
    \table
 
1512
    \header \i Expression \i Output
 
1513
    \row \i h
 
1514
         \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
 
1515
    \row \i hh
 
1516
         \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
 
1517
    \row \i m \i the minute without a leading zero (0 to 59)
 
1518
    \row \i mm \i the minute with a leading zero (00 to 59)
 
1519
    \row \i s \i the second whithout a leading zero (0 to 59)
 
1520
    \row \i ss \i the second whith a leading zero (00 to 59)
 
1521
    \row \i z \i the milliseconds without leading zeroes (0 to 999)
 
1522
    \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
 
1523
    \row \i AP
 
1524
         \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
 
1525
    \row \i ap
 
1526
         \i use am/pm display. \e ap will be replaced by either "am" or "pm".
 
1527
    \endtable
 
1528
 
 
1529
    All other input characters will be ignored. Any sequence of characters that
 
1530
    are enclosed in singlequotes will be treated as text and not be used as an
 
1531
    expression.
 
1532
 
 
1533
    Example format strings (assuming that the QTime is 14:13:09.042)
 
1534
 
 
1535
    \table
 
1536
    \header \i Format \i Result
 
1537
    \row \i hh:mm:ss.zzz \i 14:13:09.042
 
1538
    \row \i h:m:s ap     \i 2:13:9 pm
 
1539
    \endtable
 
1540
 
 
1541
    If the datetime is invalid, an empty string will be returned.
 
1542
 
 
1543
    \sa QDate::toString() QDateTime::toString()
 
1544
*/
 
1545
QString QTime::toString(const QString& format) const
 
1546
{
 
1547
    return fmtDateTime(format, this, 0);
 
1548
}
 
1549
#endif //QT_NO_DATESTRING
 
1550
/*!
 
1551
    Sets the time to hour \a h, minute \a m, seconds \a s and
 
1552
    milliseconds \a ms.
 
1553
 
 
1554
    \a h must be in the range 0 to 23, \a m and \a s must be in the
 
1555
    range 0 to 59, and \a ms must be in the range 0 to 999.
 
1556
    Returns true if the set time is valid; otherwise returns false.
 
1557
 
 
1558
    \sa isValid()
 
1559
*/
 
1560
 
 
1561
bool QTime::setHMS(int h, int m, int s, int ms)
 
1562
{
 
1563
    if (!isValid(h,m,s,ms)) {
 
1564
        ds = MSECS_PER_DAY;                // make this invalid
 
1565
        return false;
 
1566
    }
 
1567
    ds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;
 
1568
    return true;
 
1569
}
 
1570
 
 
1571
/*!
 
1572
    Returns a QTime object containing a time \a nsecs seconds later
 
1573
    than the time of this object (or earlier if \a nsecs is negative).
 
1574
 
 
1575
    Note that the time will wrap if it passes midnight.
 
1576
 
 
1577
    Example:
 
1578
 
 
1579
    \code
 
1580
        QTime n(14, 0, 0);                // n == 14:00:00
 
1581
        QTime t;
 
1582
        t = n.addSecs(70);                // t == 14:01:10
 
1583
        t = n.addSecs(-70);               // t == 13:58:50
 
1584
        t = n.addSecs(10 * 60 * 60 + 5);  // t == 00:00:05
 
1585
        t = n.addSecs(-15 * 60 * 60);     // t == 23:00:00
 
1586
    \endcode
 
1587
 
 
1588
    \sa addMSecs(), secsTo(), QDateTime::addSecs()
 
1589
*/
 
1590
 
 
1591
QTime QTime::addSecs(int nsecs) const
 
1592
{
 
1593
    return addMSecs(nsecs * 1000);
 
1594
}
 
1595
 
 
1596
/*!
 
1597
    Returns the number of seconds from this time to \a t.
 
1598
    If \a t is earlier than this time, the number of seconds returned
 
1599
    is negative.
 
1600
 
 
1601
    Because QTime measures time within a day and there are 86400
 
1602
    seconds in a day, the result is always between -86400 and 86400.
 
1603
 
 
1604
    \sa addSecs(), QDateTime::secsTo()
 
1605
*/
 
1606
 
 
1607
int QTime::secsTo(const QTime &t) const
 
1608
{
 
1609
    return ((int)t.ds - (int)ds)/1000;
 
1610
}
 
1611
 
 
1612
/*!
 
1613
    Returns a QTime object containing a time \a ms milliseconds later
 
1614
    than the time of this object (or earlier if \a ms is negative).
 
1615
 
 
1616
    Note that the time will wrap if it passes midnight. See addSecs()
 
1617
    for an example.
 
1618
 
 
1619
    \sa addSecs(), msecsTo()
 
1620
*/
 
1621
 
 
1622
QTime QTime::addMSecs(int ms) const
 
1623
{
 
1624
    QTime t;
 
1625
    if (ms < 0) {
 
1626
        // % not well-defined for -ve, but / is.
 
1627
        int negdays = (MSECS_PER_DAY-ms) / MSECS_PER_DAY;
 
1628
        t.ds = ((int)ds + ms + negdays*MSECS_PER_DAY)
 
1629
                % MSECS_PER_DAY;
 
1630
    } else {
 
1631
        t.ds = ((int)ds + ms) % MSECS_PER_DAY;
 
1632
    }
 
1633
    return t;
 
1634
}
 
1635
 
 
1636
/*!
 
1637
    Returns the number of milliseconds from this time to \a t.
 
1638
    If \a t is earlier than this time, the number of milliseconds returned
 
1639
    is negative.
 
1640
 
 
1641
    Because QTime measures time within a day and there are 86400
 
1642
    seconds in a day, the result is always between -86400000 and
 
1643
    86400000 msec.
 
1644
 
 
1645
    \sa secsTo(), addMSecs()
 
1646
*/
 
1647
 
 
1648
int QTime::msecsTo(const QTime &t) const
 
1649
{
 
1650
    return (int)t.ds - (int)ds;
 
1651
}
 
1652
 
 
1653
 
 
1654
/*!
 
1655
    \fn bool QTime::operator==(const QTime &t) const
 
1656
 
 
1657
    Returns true if this time is equal to \a t; otherwise returns false.
 
1658
*/
 
1659
 
 
1660
/*!
 
1661
    \fn bool QTime::operator!=(const QTime &t) const
 
1662
 
 
1663
    Returns true if this time is different from \a t; otherwise returns false.
 
1664
*/
 
1665
 
 
1666
/*!
 
1667
    \fn bool QTime::operator<(const QTime &t) const
 
1668
 
 
1669
    Returns true if this time is earlier than \a t; otherwise returns false.
 
1670
*/
 
1671
 
 
1672
/*!
 
1673
    \fn bool QTime::operator<=(const QTime &t) const
 
1674
 
 
1675
    Returns true if this time is earlier than or equal to \a t;
 
1676
    otherwise returns false.
 
1677
*/
 
1678
 
 
1679
/*!
 
1680
    \fn bool QTime::operator>(const QTime &t) const
 
1681
 
 
1682
    Returns true if this time is later than \a t; otherwise returns false.
 
1683
*/
 
1684
 
 
1685
/*!
 
1686
    \fn bool QTime::operator>=(const QTime &t) const
 
1687
 
 
1688
    Returns true if this time is later than or equal to \a t;
 
1689
    otherwise returns false.
 
1690
*/
 
1691
 
 
1692
/*!
 
1693
    \overload
 
1694
 
 
1695
    Returns the current time as reported by the system clock.
 
1696
 
 
1697
    Note that the accuracy depends on the accuracy of the underlying
 
1698
    operating system; not all systems provide 1-millisecond accuracy.
 
1699
*/
 
1700
 
 
1701
QTime QTime::currentTime()
 
1702
{
 
1703
    QTime ct;
 
1704
 
 
1705
#if defined(Q_OS_WIN32)
 
1706
    SYSTEMTIME st;
 
1707
    memset(&st, 0, sizeof(SYSTEMTIME));
 
1708
    GetLocalTime(&st);
 
1709
    ct.ds = (uint)(MSECS_PER_HOUR * st.wHour + MSECS_PER_MIN * st.wMinute + 1000 * st.wSecond
 
1710
                   + st.wMilliseconds);
 
1711
#elif defined(Q_OS_UNIX)
 
1712
    // posix compliant system
 
1713
    struct timeval tv;
 
1714
    gettimeofday(&tv, 0);
 
1715
    time_t ltime = tv.tv_sec;
 
1716
    tm *t;
 
1717
 
 
1718
#if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
 
1719
    // use the reentrant version of localtime() where available
 
1720
    tm res;
 
1721
    t = localtime_r(&ltime, &res);
 
1722
#else
 
1723
    t = localtime(&ltime);
 
1724
#endif
 
1725
 
 
1726
    ct.ds = (uint)(MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec
 
1727
                   + tv.tv_usec / 1000);
 
1728
#else
 
1729
    time_t ltime; // no millisecond resolution
 
1730
    ::time(&ltime);
 
1731
    tm *t;
 
1732
    localtime(&ltime);
 
1733
    ct.ds = (uint)(MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec);
 
1734
#endif
 
1735
    return ct;
 
1736
}
 
1737
 
 
1738
#ifndef QT_NO_DATESTRING
 
1739
/*!
 
1740
    \fn QTime QTime::fromString(const QString &string, Qt::DateFormat format)
 
1741
 
 
1742
    Returns the time represented in the \a string as a QTime using the
 
1743
    \a format given, or an invalid time if this is not possible.
 
1744
 
 
1745
    \warning Note that \c Qt::LocalDate cannot be used here.
 
1746
*/
 
1747
QTime QTime::fromString(const QString& s, Qt::DateFormat f)
 
1748
{
 
1749
    if (s.isEmpty() || f == Qt::LocalDate) {
 
1750
        qWarning("QTime::fromString: Parameter out of range");
 
1751
        QTime t;
 
1752
        t.ds = MSECS_PER_DAY;
 
1753
        return t;
 
1754
    }
 
1755
 
 
1756
    int hour(s.mid(0, 2).toInt());
 
1757
    int minute(s.mid(3, 2).toInt());
 
1758
    int second(s.mid(6, 2).toInt());
 
1759
    int msec(s.mid(9, 3).toInt());
 
1760
    return QTime(hour, minute, second, msec);
 
1761
}
 
1762
#endif
 
1763
 
 
1764
 
 
1765
/*!
 
1766
    \fn QTime::fromString(const QString &string, const QString &format)
 
1767
 
 
1768
    Returns the QTime represented by the \a string, using the \a
 
1769
    format given, or an invalid time if the string cannot be parsed.
 
1770
 
 
1771
    These expressions may be used for the format:
 
1772
 
 
1773
    \table
 
1774
    \header \i Expression \i Output
 
1775
    \row \i h
 
1776
         \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
 
1777
    \row \i hh
 
1778
         \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
 
1779
    \row \i m \i the minute without a leading zero (0 to 59)
 
1780
    \row \i mm \i the minute with a leading zero (00 to 59)
 
1781
    \row \i s \i the second whithout a leading zero (0 to 59)
 
1782
    \row \i ss \i the second whith a leading zero (00 to 59)
 
1783
    \row \i z \i the milliseconds without leading zeroes (0 to 999)
 
1784
    \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
 
1785
    \row \i AP
 
1786
         \i interpret as an AM/PM time. \e AP must be either "AM" or "PM".
 
1787
    \row \i ap
 
1788
         \i Interpret as an AM/PM time. \e ap must be either "am" or "pm".
 
1789
    \endtable
 
1790
 
 
1791
    All other input characters will be treated as text. Any sequence
 
1792
    of characters that are enclosed in single quotes will also be
 
1793
    treated as text and not be used as an expression.
 
1794
 
 
1795
    \code
 
1796
        QTime time = QTime::fromString("1mm12car00", "m'mm'hcarss");
 
1797
        // time is 12:01.00
 
1798
    \endcode
 
1799
 
 
1800
    If the format is not satisfied an invalid QTime is returned.
 
1801
    Expressions that do not expect leading zeroes to be given (h, m, s
 
1802
    and z) are greedy. This means that they will use two digits even if
 
1803
    this puts them outside the range of accepted values and leaves too
 
1804
    few digits for other sections. For example, the following string
 
1805
    could have meant 00:07:10, but the m will grab two digits, resulting
 
1806
    in an invalid time:
 
1807
 
 
1808
    \code
 
1809
        QTime time = QTime::fromString("00:710", "hh:ms"); // invalid
 
1810
    \endcode
 
1811
 
 
1812
    Any field that is not represented in the format will be set to zero.
 
1813
    For example:
 
1814
 
 
1815
    \code
 
1816
        QTime time = QTime::fromString("1.30", "m.s");
 
1817
        // time is 00:01:30.000
 
1818
    \endcode
 
1819
 
 
1820
    \sa QDateTime::fromString() QDate::fromString() QDate::toString()
 
1821
    QDateTime::toString() QTime::toString()
 
1822
*/
 
1823
 
 
1824
QTime QTime::fromString(const QString &string, const QString &format)
 
1825
{
 
1826
    QDateTimeParser dt(format, QVariant::Time);
 
1827
    QTime time;
 
1828
    return dt.fromString(string, 0, &time) ? time : QTime(-1, -1, -1);
 
1829
}
 
1830
 
 
1831
/*!
 
1832
    \overload
 
1833
 
 
1834
    Returns true if the specified time is valid; otherwise returns
 
1835
    false.
 
1836
 
 
1837
    The time is valid if \a h is in the range 0 to 23, \a m and
 
1838
    \a s are in the range 0 to 59, and \a ms is in the range 0 to 999.
 
1839
 
 
1840
    Example:
 
1841
 
 
1842
    \code
 
1843
        QTime::isValid(21, 10, 30); // returns true
 
1844
        QTime::isValid(22, 5,  62); // returns false
 
1845
    \endcode
 
1846
*/
 
1847
 
 
1848
bool QTime::isValid(int h, int m, int s, int ms)
 
1849
{
 
1850
    return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
 
1851
}
 
1852
 
 
1853
 
 
1854
/*!
 
1855
    Sets this time to the current time. This is practical for timing:
 
1856
 
 
1857
    \code
 
1858
        QTime t;
 
1859
        t.start();
 
1860
        some_lengthy_task();
 
1861
        qDebug("Time elapsed: %d ms", t.elapsed());
 
1862
    \endcode
 
1863
 
 
1864
    \sa restart(), elapsed(), currentTime()
 
1865
*/
 
1866
 
 
1867
void QTime::start()
 
1868
{
 
1869
    *this = currentTime();
 
1870
}
 
1871
 
 
1872
/*!
 
1873
    Sets this time to the current time and returns the number of
 
1874
    milliseconds that have elapsed since the last time start() or
 
1875
    restart() was called.
 
1876
 
 
1877
    This function is guaranteed to be atomic and is thus very handy
 
1878
    for repeated measurements. Call start() to start the first
 
1879
    measurement, and restart() for each later measurement.
 
1880
 
 
1881
    Note that the counter wraps to zero 24 hours after the last call
 
1882
    to start() or restart().
 
1883
 
 
1884
    \warning If the system's clock setting has been changed since the
 
1885
    last time start() or restart() was called, the result is
 
1886
    undefined. This can happen when daylight savings time is turned on
 
1887
    or off.
 
1888
 
 
1889
    \sa start(), elapsed(), currentTime()
 
1890
*/
 
1891
 
 
1892
int QTime::restart()
 
1893
{
 
1894
    QTime t = currentTime();
 
1895
    int n = msecsTo(t);
 
1896
    if (n < 0)                                // passed midnight
 
1897
        n += 86400*1000;
 
1898
    *this = t;
 
1899
    return n;
 
1900
}
 
1901
 
 
1902
/*!
 
1903
    Returns the number of milliseconds that have elapsed since the
 
1904
    last time start() or restart() was called.
 
1905
 
 
1906
    Note that the counter wraps to zero 24 hours after the last call
 
1907
    to start() or restart.
 
1908
 
 
1909
    Note that the accuracy depends on the accuracy of the underlying
 
1910
    operating system; not all systems provide 1-millisecond accuracy.
 
1911
 
 
1912
    \warning If the system's clock setting has been changed since the
 
1913
    last time start() or restart() was called, the result is
 
1914
    undefined. This can happen when daylight savings time is turned on
 
1915
    or off.
 
1916
 
 
1917
    \sa start(), restart()
 
1918
*/
 
1919
 
 
1920
int QTime::elapsed() const
 
1921
{
 
1922
    int n = msecsTo(currentTime());
 
1923
    if (n < 0)                                // passed midnight
 
1924
        n += 86400 * 1000;
 
1925
    return n;
 
1926
}
 
1927
 
 
1928
 
 
1929
/*****************************************************************************
 
1930
  QDateTime member functions
 
1931
 *****************************************************************************/
 
1932
 
 
1933
/*!
 
1934
    \class QDateTime
 
1935
    \reentrant
 
1936
    \brief The QDateTime class provides date and time functions.
 
1937
 
 
1938
    \ingroup time
 
1939
    \mainclass
 
1940
 
 
1941
    A QDateTime object contains a calendar date and a clock time (a
 
1942
    "datetime"). It is a combination of the QDate and QTime classes.
 
1943
    It can read the current datetime from the system clock. It
 
1944
    provides functions for comparing datetimes and for manipulating a
 
1945
    datetime by adding a number of seconds, days, months, or years.
 
1946
 
 
1947
    A QDateTime object is typically created either by giving a date
 
1948
    and time explicitly in the constructor, or by using the static
 
1949
    function currentDateTime() that returns a QDateTime object set
 
1950
    to the system clock's time. The date and time can be changed with
 
1951
    setDate() and setTime(). A datetime can also be set using the
 
1952
    setTime_t() function that takes a POSIX-standard "number of
 
1953
    seconds since 00:00:00 on January 1, 1970" value. The fromString()
 
1954
    function returns a QDateTime, given a string and a date format
 
1955
    used to interpret the date within the string.
 
1956
 
 
1957
    The date() and time() functions provide access to the date and
 
1958
    time parts of the datetime. The same information is provided in
 
1959
    textual format by the toString() function.
 
1960
 
 
1961
    QDateTime provides a full set of operators to compare two
 
1962
    QDateTime objects where smaller means earlier and larger means
 
1963
    later.
 
1964
 
 
1965
    You can increment (or decrement) a datetime by a given number of
 
1966
    seconds using addSecs(), or days using addDays(). Similarly you can
 
1967
    use addMonths() and addYears(). The daysTo() function returns the
 
1968
    number of days between two datetimes, and secsTo() returns the
 
1969
    number of seconds between two datetimes.
 
1970
 
 
1971
    QDateTime can store datetimes as \l{Qt::LocalTime}{local time} or
 
1972
    as \l{Qt::UTC}{UTC}. QDateTime::currentDateTime() returns a
 
1973
    QDateTime expressed as local time; use toUTC() to convert it to
 
1974
    UTC. You can also use timeSpec() to find out if a QDateTime
 
1975
    object stores a UTC time or a local time. Operations such as
 
1976
    addSecs() and secsTo() are aware of daylight saving time (DST).
 
1977
 
 
1978
    \sa QDate QTime QDateTimeEdit
 
1979
*/
 
1980
 
 
1981
/*!
 
1982
    Constructs a null datetime (i.e. null date and null time). A null
 
1983
    datetime is invalid, since the date is invalid.
 
1984
 
 
1985
    \sa isValid()
 
1986
*/
 
1987
QDateTime::QDateTime()
 
1988
{
 
1989
    d = new QDateTimePrivate;
 
1990
}
 
1991
 
 
1992
 
 
1993
/*!
 
1994
    Constructs a datetime with the given \a date, and a null but valid
 
1995
    time (00:00:00.000).
 
1996
*/
 
1997
 
 
1998
QDateTime::QDateTime(const QDate &date)
 
1999
{
 
2000
    d = new QDateTimePrivate;
 
2001
    d->date = date;
 
2002
}
 
2003
 
 
2004
/*!
 
2005
    Constructs a datetime with the given \a date and \a time, using
 
2006
    the time specification defined by \a spec.
 
2007
*/
 
2008
 
 
2009
QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec)
 
2010
{
 
2011
    d = new QDateTimePrivate;
 
2012
    d->date = date;
 
2013
    d->time = time;
 
2014
    d->spec = (spec == Qt::UTC) ? QDateTimePrivate::UTC : QDateTimePrivate::LocalUnknown;
 
2015
}
 
2016
 
 
2017
/*!
 
2018
    Constructs a copy of the \a other datetime.
 
2019
*/
 
2020
 
 
2021
QDateTime::QDateTime(const QDateTime &other)
 
2022
{
 
2023
    d = other.d;
 
2024
    d->ref.ref();
 
2025
}
 
2026
 
 
2027
/*!
 
2028
    Destroys the datetime.
 
2029
*/
 
2030
QDateTime::~QDateTime()
 
2031
{
 
2032
    if (!d->ref.deref())
 
2033
        delete d;
 
2034
}
 
2035
 
 
2036
/*!
 
2037
    Makes a copy of the \a other datetime and returns a reference to the
 
2038
    copy.
 
2039
*/
 
2040
 
 
2041
QDateTime &QDateTime::operator=(const QDateTime &other)
 
2042
{
 
2043
    qAtomicAssign(d, other.d);
 
2044
    return *this;
 
2045
}
 
2046
 
 
2047
/*!
 
2048
    Returns true if both the date and the time are null; otherwise
 
2049
    returns false. A null datetime is invalid.
 
2050
 
 
2051
    \sa QDate::isNull(), QTime::isNull(), isValid()
 
2052
*/
 
2053
 
 
2054
bool QDateTime::isNull() const
 
2055
{
 
2056
    return d->date.isNull() && d->time.isNull();
 
2057
}
 
2058
 
 
2059
/*!
 
2060
    Returns true if both the date and the time are valid; otherwise
 
2061
    returns false.
 
2062
 
 
2063
    \sa QDate::isValid(), QTime::isValid()
 
2064
*/
 
2065
 
 
2066
bool QDateTime::isValid() const
 
2067
{
 
2068
    return d->date.isValid() && d->time.isValid();
 
2069
}
 
2070
 
 
2071
/*!
 
2072
    Returns the date part of the datetime.
 
2073
 
 
2074
    \sa setDate(), time(), timeSpec()
 
2075
*/
 
2076
 
 
2077
QDate QDateTime::date() const
 
2078
{
 
2079
    return d->date;
 
2080
}
 
2081
 
 
2082
/*!
 
2083
    Returns the time part of the datetime.
 
2084
 
 
2085
    \sa setTime(), date(), timeSpec()
 
2086
*/
 
2087
 
 
2088
QTime QDateTime::time() const
 
2089
{
 
2090
    return d->time;
 
2091
}
 
2092
 
 
2093
/*!
 
2094
    Returns the time specification of the datetime.
 
2095
 
 
2096
    \sa setTimeSpec(), date(), time(), Qt::TimeSpec
 
2097
*/
 
2098
 
 
2099
Qt::TimeSpec QDateTime::timeSpec() const
 
2100
{
 
2101
    return d->spec == QDateTimePrivate::UTC ? Qt::UTC : Qt::LocalTime;
 
2102
}
 
2103
 
 
2104
/*!
 
2105
    Sets the date part of this datetime to \a date.
 
2106
 
 
2107
    \sa date(), setTime(), setTimeSpec()
 
2108
*/
 
2109
 
 
2110
void QDateTime::setDate(const QDate &date)
 
2111
{
 
2112
    detach();
 
2113
    d->date = date;
 
2114
}
 
2115
 
 
2116
/*!
 
2117
    Sets the time part of this datetime to \a time.
 
2118
 
 
2119
    \sa time(), setDate(), setTimeSpec()
 
2120
*/
 
2121
 
 
2122
void QDateTime::setTime(const QTime &time)
 
2123
{
 
2124
    detach();
 
2125
    d->time = time;
 
2126
}
 
2127
 
 
2128
/*!
 
2129
    Sets the time specification used in this datetime to \a spec.
 
2130
 
 
2131
    \sa timeSpec(), setDate(), setTime(), Qt::TimeSpec
 
2132
*/
 
2133
 
 
2134
void QDateTime::setTimeSpec(Qt::TimeSpec spec)
 
2135
{
 
2136
    detach();
 
2137
    d->spec = (spec == Qt::UTC) ? QDateTimePrivate::UTC : QDateTimePrivate::LocalUnknown;
 
2138
}
 
2139
 
 
2140
static uint toTime_t(const QDate &utcDate, const QTime &utcTime)
 
2141
{
 
2142
    return (QDate(1970, 1, 1).daysTo(utcDate) * SECS_PER_DAY) + QTime().secsTo(utcTime);
 
2143
}
 
2144
 
 
2145
/*!
 
2146
    Returns the datetime as the number of seconds that have passed
 
2147
    since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC).
 
2148
 
 
2149
    On systems that do not support timezones, this function will
 
2150
    behave as if local time were \c Qt::UTC.
 
2151
 
 
2152
    \sa setTime_t()
 
2153
*/
 
2154
 
 
2155
uint QDateTime::toTime_t() const
 
2156
{
 
2157
    QDate utcDate;
 
2158
    QTime utcTime;
 
2159
    d->getUTC(utcDate, utcTime);
 
2160
 
 
2161
    int secsSince1Jan1970UTC = ::toTime_t(utcDate, utcTime);
 
2162
    if (secsSince1Jan1970UTC < 0)
 
2163
        return (uint)-1;
 
2164
    return (uint)secsSince1Jan1970UTC;
 
2165
}
 
2166
 
 
2167
/*!
 
2168
    \fn void QDateTime::setTime_t(uint seconds)
 
2169
 
 
2170
    Sets the date and time given the number of \a seconds that have
 
2171
    passed since 1970-01-01T00:00:00, Coordinated Universal Time
 
2172
    (Qt::UTC). On systems that do not support timezones this function
 
2173
    will behave as if local time were Qt::UTC.
 
2174
 
 
2175
    \sa toTime_t()
 
2176
*/
 
2177
 
 
2178
void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
 
2179
{
 
2180
    detach();
 
2181
 
 
2182
    QDateTimePrivate::Spec oldSpec = d->spec;
 
2183
 
 
2184
    d->date = QDate(1970, 1, 1).addDays(secsSince1Jan1970UTC / SECS_PER_DAY);
 
2185
    d->time = QTime().addSecs(secsSince1Jan1970UTC % SECS_PER_DAY);
 
2186
    d->spec = QDateTimePrivate::UTC;
 
2187
 
 
2188
    if (oldSpec != QDateTimePrivate::UTC)
 
2189
        d->spec = d->getLocal(d->date, d->time);
 
2190
}
 
2191
 
 
2192
#ifndef QT_NO_DATESTRING
 
2193
/*!
 
2194
    \fn QString QDateTime::toString(Qt::DateFormat format) const
 
2195
 
 
2196
    \overload
 
2197
 
 
2198
    Returns the datetime as a string in the \a format given.
 
2199
 
 
2200
    If the \a format is \c Qt::TextDate, the string is formatted in
 
2201
    the default way. QDate::shortDayName(), QDate::shortMonthName(),
 
2202
    and QTime::toString() are used to generate the string, so the
 
2203
    day and month names will be localized names. An example of this
 
2204
    formatting is "Wed May 20 03:40:13 1998".
 
2205
 
 
2206
    If the \a format is \c Qt::ISODate, the string format corresponds
 
2207
    to the ISO 8601 extended specification for representations of
 
2208
    dates and times, taking the form YYYY-MM-DDTHH:MM:SS.
 
2209
 
 
2210
    If the \a format is \c Qt::LocalDate, the string format depends
 
2211
    on the locale settings of the system.
 
2212
 
 
2213
    If the datetime is invalid, an empty string will be returned.
 
2214
 
 
2215
    \sa QDate::toString() QTime::toString() Qt::DateFormat
 
2216
*/
 
2217
 
 
2218
QString QDateTime::toString(Qt::DateFormat f) const
 
2219
{
 
2220
    QString buf;
 
2221
    if (!isValid())
 
2222
        return buf;
 
2223
 
 
2224
    if (f == Qt::ISODate) {
 
2225
        buf = d->date.toString(Qt::ISODate);
 
2226
        buf += QLatin1Char('T');
 
2227
        buf += d->time.toString(Qt::ISODate);
 
2228
    }
 
2229
#ifndef QT_NO_TEXTDATE
 
2230
    else if (f == Qt::TextDate) {
 
2231
#ifndef Q_WS_WIN
 
2232
        buf = d->date.shortDayName(d->date.dayOfWeek());
 
2233
        buf += QLatin1Char(' ');
 
2234
        buf += d->date.shortMonthName(d->date.month());
 
2235
        buf += QLatin1Char(' ');
 
2236
        buf += QString::number(d->date.day());
 
2237
#else
 
2238
        QString winstr;
 
2239
        QT_WA({
 
2240
            TCHAR out[255];
 
2241
            GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255);
 
2242
            winstr = QString::fromUtf16((ushort*)out);
 
2243
        } , {
 
2244
            char out[255];
 
2245
            GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ILDATE, (char*)&out, 255);
 
2246
            winstr = QString::fromLocal8Bit(out);
 
2247
        });
 
2248
        switch (winstr.toInt()) {
 
2249
        case 1:
 
2250
            buf = d->date.shortDayName(d->date.dayOfWeek());
 
2251
            buf += QLatin1Char(' ');
 
2252
            buf += QString::number(d->date.day());
 
2253
            buf += QLatin1String(". ");
 
2254
            buf += d->date.shortMonthName(d->date.month());
 
2255
            break;
 
2256
        default:
 
2257
            buf = d->date.shortDayName(d->date.dayOfWeek());
 
2258
            buf += QLatin1Char(' ');
 
2259
            buf += d->date.shortMonthName(d->date.month());
 
2260
            buf += QLatin1Char(' ');
 
2261
            buf += QString::number(d->date.day());
 
2262
        }
 
2263
#endif
 
2264
        buf += QLatin1Char(' ');
 
2265
        buf += d->time.toString();
 
2266
        buf += QLatin1Char(' ');
 
2267
        buf += QString::number(d->date.year());
 
2268
    }
 
2269
#endif
 
2270
    else if (f == Qt::LocalDate) {
 
2271
        buf = d->date.toString(Qt::LocalDate);
 
2272
        buf += QLatin1Char(' ');
 
2273
        buf += d->time.toString(Qt::LocalDate);
 
2274
    }
 
2275
    return buf;
 
2276
}
 
2277
 
 
2278
/*!
 
2279
    Returns the datetime as a string. The \a format parameter
 
2280
    determines the format of the result string.
 
2281
 
 
2282
    These expressions may be used for the date:
 
2283
 
 
2284
    \table
 
2285
    \header \i Expression \i Output
 
2286
    \row \i d \i the day as number without a leading zero (1 to 31)
 
2287
    \row \i dd \i the day as number with a leading zero (01 to 31)
 
2288
    \row \i ddd
 
2289
            \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
 
2290
            Uses QDate::shortDayName().
 
2291
    \row \i dddd
 
2292
            \i the long localized day name (e.g. 'Qt::Monday' to 'Qt::Sunday').
 
2293
            Uses QDate::longDayName().
 
2294
    \row \i M \i the month as number without a leading zero (1-12)
 
2295
    \row \i MM \i the month as number with a leading zero (01-12)
 
2296
    \row \i MMM
 
2297
            \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
 
2298
            Uses QDate::shortMonthName().
 
2299
    \row \i MMMM
 
2300
            \i the long localized month name (e.g. 'January' to 'December').
 
2301
            Uses QDate::longMonthName().
 
2302
    \row \i yy \i the year as two digit number (00-99)
 
2303
    \row \i yyyy \i the year as four digit number (1752-8000)
 
2304
    \endtable
 
2305
 
 
2306
    These expressions may be used for the time:
 
2307
 
 
2308
    \table
 
2309
    \header \i Expression \i Output
 
2310
    \row \i h
 
2311
         \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
 
2312
    \row \i hh
 
2313
         \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
 
2314
    \row \i m \i the minute without a leading zero (0 to 59)
 
2315
    \row \i mm \i the minute with a leading zero (00 to 59)
 
2316
    \row \i s \i the second whithout a leading zero (0 to 59)
 
2317
    \row \i ss \i the second whith a leading zero (00 to 59)
 
2318
    \row \i z \i the milliseconds without leading zeroes (0 to 999)
 
2319
    \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
 
2320
    \row \i AP
 
2321
            \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
 
2322
    \row \i ap
 
2323
            \i use am/pm display. \e ap will be replaced by either "am" or "pm".
 
2324
    \endtable
 
2325
 
 
2326
    All other input characters will be ignored. Any sequence of characters that
 
2327
    are enclosed in singlequotes will be treated as text and not be used as an
 
2328
    expression.
 
2329
 
 
2330
    Example format strings (assumed that the QDateTime is 21 May 2001
 
2331
    14:13:09):
 
2332
 
 
2333
    \table
 
2334
    \header \i Format       \i Result
 
2335
    \row \i dd.MM.yyyy      \i 21.05.2001
 
2336
    \row \i ddd MMMM d yy   \i Tue May 21 01
 
2337
    \row \i hh:mm:ss.zzz    \i 14:13:09.042
 
2338
    \row \i h:m:s ap        \i 2:13:9 pm
 
2339
    \endtable
 
2340
 
 
2341
    If the datetime is invalid, an empty string will be returned.
 
2342
 
 
2343
    \sa QDate::toString() QTime::toString()
 
2344
*/
 
2345
QString QDateTime::toString(const QString& format) const
 
2346
{
 
2347
    return fmtDateTime(format, &d->time, &d->date);
 
2348
}
 
2349
#endif //QT_NO_DATESTRING
 
2350
 
 
2351
/*!
 
2352
    Returns a QDateTime object containing a datetime \a ndays days
 
2353
    later than the datetime of this object (or earlier if \a ndays is
 
2354
    negative).
 
2355
 
 
2356
    \sa daysTo(), addMonths(), addYears(), addSecs()
 
2357
*/
 
2358
 
 
2359
QDateTime QDateTime::addDays(int ndays) const
 
2360
{
 
2361
    return QDateTime(d->date.addDays(ndays), d->time, timeSpec());
 
2362
}
 
2363
 
 
2364
/*!
 
2365
    Returns a QDateTime object containing a datetime \a nmonths months
 
2366
    later than the datetime of this object (or earlier if \a nmonths
 
2367
    is negative).
 
2368
 
 
2369
    \sa daysTo(), addDays(), addYears(), addSecs()
 
2370
*/
 
2371
 
 
2372
QDateTime QDateTime::addMonths(int nmonths) const
 
2373
{
 
2374
    return QDateTime(d->date.addMonths(nmonths), d->time, timeSpec());
 
2375
}
 
2376
 
 
2377
/*!
 
2378
    Returns a QDateTime object containing a datetime \a nyears years
 
2379
    later than the datetime of this object (or earlier if \a nyears is
 
2380
    negative).
 
2381
 
 
2382
    \sa daysTo(), addDays(), addMonths(), addSecs()
 
2383
*/
 
2384
 
 
2385
QDateTime QDateTime::addYears(int nyears) const
 
2386
{
 
2387
    return QDateTime(d->date.addYears(nyears), d->time, timeSpec());
 
2388
}
 
2389
 
 
2390
/*!
 
2391
    Returns a QDateTime object containing a datetime \a nsecs seconds
 
2392
    later than the datetime of this object (or earlier if \a nsecs is
 
2393
    negative).
 
2394
 
 
2395
    \sa secsTo(), addDays(), addMonths(), addYears()
 
2396
*/
 
2397
 
 
2398
QDateTime QDateTime::addSecs(int nsecs) const
 
2399
{
 
2400
    QDate utcDate;
 
2401
    QTime utcTime;
 
2402
    d->getUTC(utcDate, utcTime);
 
2403
 
 
2404
    uint dd = utcDate.jd;
 
2405
    int tt = utcTime.ds;
 
2406
    int sign = 1;
 
2407
    if (nsecs < 0) {
 
2408
        nsecs = -nsecs;
 
2409
        sign = -1;
 
2410
    }
 
2411
    if (nsecs >= (int)SECS_PER_DAY) {
 
2412
        dd += sign * (nsecs / SECS_PER_DAY);
 
2413
        nsecs %= SECS_PER_DAY;
 
2414
    }
 
2415
    tt += sign * nsecs * 1000;
 
2416
    if (tt < 0) {
 
2417
        tt = MSECS_PER_DAY - tt - 1;
 
2418
        dd -= tt / MSECS_PER_DAY;
 
2419
        tt = tt % MSECS_PER_DAY;
 
2420
        tt = MSECS_PER_DAY - tt - 1;
 
2421
    } else if (tt >= (int)MSECS_PER_DAY) {
 
2422
        dd += tt / MSECS_PER_DAY;
 
2423
        tt = tt % MSECS_PER_DAY;
 
2424
    }
 
2425
    utcDate.jd = dd;
 
2426
    utcTime.ds = tt;
 
2427
    return QDateTime(utcDate, utcTime, Qt::UTC).toTimeSpec(timeSpec());
 
2428
}
 
2429
 
 
2430
/*!
 
2431
    Returns the number of days from this datetime to the \a other
 
2432
    datetime. If the \a other datetime is earlier than this datetime,
 
2433
    the value returned is negative.
 
2434
 
 
2435
    \sa addDays(), secsTo()
 
2436
*/
 
2437
 
 
2438
int QDateTime::daysTo(const QDateTime &other) const
 
2439
{
 
2440
    return d->date.daysTo(other.d->date);
 
2441
}
 
2442
 
 
2443
/*!
 
2444
    Returns the number of seconds from this datetime to the \a other
 
2445
    datetime. If the \a other datetime is earlier than this datetime,
 
2446
    the value returned is negative.
 
2447
 
 
2448
    Before performing the comparison, the two datetimes are converted
 
2449
    to Qt::UTC to ensure that the result is correct if one of the two
 
2450
    datetimes has daylight saving time (DST) and the other doesn't.
 
2451
 
 
2452
    Example:
 
2453
    \code
 
2454
        QDateTime now = QDateTime::currentDateTime();
 
2455
        QDateTime xmas(QDate(dt.date().year(), 12, 25), QTime(0, 0));
 
2456
        qDebug("There are %d seconds to Christmas", dt.secsTo(xmas));
 
2457
    \endcode
 
2458
 
 
2459
    \sa addSecs(), daysTo(), QTime::secsTo()
 
2460
*/
 
2461
 
 
2462
int QDateTime::secsTo(const QDateTime &other) const
 
2463
{
 
2464
    QDate date1, date2;
 
2465
    QTime time1, time2;
 
2466
 
 
2467
    d->getUTC(date1, time1);
 
2468
    other.d->getUTC(date2, time2);
 
2469
 
 
2470
    return (date1.daysTo(date2) * SECS_PER_DAY) + time1.secsTo(time2);
 
2471
}
 
2472
 
 
2473
/*!
 
2474
    \fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec specification) const
 
2475
 
 
2476
    Returns a copy of this datetime configured to use the given time
 
2477
    \a specification.
 
2478
 
 
2479
    \sa timeSpec(), toUTC(), toLocalTime()
 
2480
*/
 
2481
 
 
2482
QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
 
2483
{
 
2484
    if ((d->spec == QDateTimePrivate::UTC) == (spec == Qt::UTC))
 
2485
        return *this;
 
2486
 
 
2487
    QDateTime ret;
 
2488
    if (spec == Qt::UTC) {
 
2489
        d->getUTC(ret.d->date, ret.d->time);
 
2490
        ret.d->spec = QDateTimePrivate::UTC;
 
2491
    } else {
 
2492
        ret.d->spec = d->getLocal(ret.d->date, ret.d->time);
 
2493
    }
 
2494
    return ret;
 
2495
}
 
2496
 
 
2497
/*!
 
2498
    Returns true if this datetime is equal to the \a other datetime;
 
2499
    otherwise returns false.
 
2500
 
 
2501
    \sa operator!=()
 
2502
*/
 
2503
 
 
2504
bool QDateTime::operator==(const QDateTime &other) const
 
2505
{
 
2506
    if (d->spec != other.d->spec) {
 
2507
        if (d->spec == QDateTimePrivate::UTC || other.d->spec == QDateTimePrivate::UTC)
 
2508
            return false;
 
2509
        if (d->spec != QDateTimePrivate::LocalUnknown
 
2510
                && other.d->spec != QDateTimePrivate::LocalUnknown)
 
2511
            return false;
 
2512
 
 
2513
        QDate date1, date2;
 
2514
        QTime time1, time2;
 
2515
        d->getUTC(date1, time1);
 
2516
        other.d->getUTC(date2, time2);
 
2517
        return time1 == time2 && date1 == date2;
 
2518
    } else {
 
2519
        return d->time == other.d->time && d->date == other.d->date;
 
2520
    }
 
2521
}
 
2522
 
 
2523
/*!
 
2524
    \fn bool QDateTime::operator!=(const QDateTime &other) const
 
2525
 
 
2526
    Returns true if this datetime is different from the \a other
 
2527
    datetime; otherwise returns false.
 
2528
 
 
2529
    Two datetimes are different if either the date, the time, or the
 
2530
    time zone components are different.
 
2531
 
 
2532
    \sa operator==()
 
2533
*/
 
2534
 
 
2535
/*!
 
2536
    Returns true if this datetime is earlier than the \a other
 
2537
    datetime; otherwise returns false.
 
2538
*/
 
2539
 
 
2540
bool QDateTime::operator<(const QDateTime &other) const
 
2541
{
 
2542
    if (d->spec == other.d->spec) {
 
2543
        if (d->date != other.d->date)
 
2544
            return d->date < other.d->date;
 
2545
        return d->time < other.d->time;
 
2546
    } else {
 
2547
        QDate date1, date2;
 
2548
        QTime time1, time2;
 
2549
        d->getUTC(date1, time1);
 
2550
        other.d->getUTC(date2, time2);
 
2551
        if (date1 != date2)
 
2552
            return date1 < date2;
 
2553
        return time1 < time2;
 
2554
    }
 
2555
}
 
2556
 
 
2557
/*!
 
2558
    \fn bool QDateTime::operator<=(const QDateTime &other) const
 
2559
 
 
2560
    Returns true if this datetime is earlier than or equal to the
 
2561
    \a other datetime; otherwise returns false.
 
2562
*/
 
2563
 
 
2564
/*!
 
2565
    \fn bool QDateTime::operator>(const QDateTime &other) const
 
2566
 
 
2567
    Returns true if this datetime is later than the \a other datetime;
 
2568
    otherwise returns false.
 
2569
*/
 
2570
 
 
2571
/*!
 
2572
    \fn bool QDateTime::operator>=(const QDateTime &other) const
 
2573
 
 
2574
    Returns true if this datetime is later than or equal to the
 
2575
    \a other datetime; otherwise returns false.
 
2576
*/
 
2577
 
 
2578
/*!
 
2579
    Returns the current datetime, as reported by the system clock, in
 
2580
    the local time zone.
 
2581
 
 
2582
    \sa QDate::currentDate(), QTime::currentTime(), toTimeSpec()
 
2583
*/
 
2584
 
 
2585
QDateTime QDateTime::currentDateTime()
 
2586
{
 
2587
#if defined(Q_OS_WIN32)
 
2588
    QDate d;
 
2589
    QTime t;
 
2590
    SYSTEMTIME st;
 
2591
    memset(&st, 0, sizeof(SYSTEMTIME));
 
2592
    GetLocalTime(&st);
 
2593
    d.jd = QDate::gregorianToJulian(st.wYear, st.wMonth, st.wDay);
 
2594
    t.ds = (uint)(MSECS_PER_HOUR * st.wHour + MSECS_PER_MIN * st.wMinute + 1000 * st.wSecond
 
2595
                  + st.wMilliseconds);
 
2596
    return QDateTime(d, t);
 
2597
#else
 
2598
    QDateTime dt;
 
2599
    QTime t;
 
2600
    dt.setDate(QDate::currentDate());
 
2601
    t = QTime::currentTime();
 
2602
    if (t.ds < (uint)MSECS_PER_MIN)                // midnight or right after?
 
2603
        dt.setDate(QDate::currentDate());          // fetch date again
 
2604
    dt.setTime(t);
 
2605
    return dt;
 
2606
#endif
 
2607
}
 
2608
 
 
2609
#ifndef QT_NO_DATESTRING
 
2610
/*!
 
2611
    \fn QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
 
2612
 
 
2613
    Returns the QDateTime represented by the \a string, using the
 
2614
    \a format given, or an invalid datetime if this is not possible.
 
2615
 
 
2616
    Note for \c Qt::TextDate: It is recommended that you use the
 
2617
    English short month names (e.g. "Jan"). Although localized month
 
2618
    names can also be used, they depend on the user's locale settings.
 
2619
 
 
2620
    \warning Note that \c Qt::LocalDate cannot be used here.
 
2621
*/
 
2622
QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
 
2623
{
 
2624
    if (s.isEmpty() || f == Qt::LocalDate) {
 
2625
        qWarning("QDateTime::fromString: Parameter out of range");
 
2626
        return QDateTime();
 
2627
    }
 
2628
    if (f == Qt::ISODate) {
 
2629
        return QDateTime(QDate::fromString(s.mid(0, 10), Qt::ISODate),
 
2630
                         QTime::fromString(s.mid(11), Qt::ISODate));
 
2631
    }
 
2632
#if !defined(QT_NO_REGEXP) && !defined(QT_NO_TEXTDATE)
 
2633
    else if (f == Qt::TextDate) {
 
2634
        QString monthName(s.mid(4, 3));
 
2635
        int month = -1;
 
2636
        // Assume that English monthnames are the default
 
2637
        for (int i = 0; i < 12; ++i) {
 
2638
            if (monthName == QLatin1String(qt_shortMonthNames[i])) {
 
2639
                month = i + 1;
 
2640
                break;
 
2641
            }
 
2642
        }
 
2643
        // If English names can't be found, search the localized ones
 
2644
        if (month == -1) {
 
2645
            for (int i = 1; i <= 12; ++i) {
 
2646
                if (monthName == QDate::shortMonthName(i)) {
 
2647
                    month = i;
 
2648
                    break;
 
2649
                }
 
2650
            }
 
2651
        }
 
2652
        if (month < 1 || month > 12) {
 
2653
            qWarning("QDateTime::fromString: Parameter out of range");
 
2654
            return QDateTime();
 
2655
        }
 
2656
        int day = s.mid(8, 2).simplified().toInt();
 
2657
        int year = s.right(4).toInt();
 
2658
        QDate date(year, month, day);
 
2659
        QTime time;
 
2660
        int hour, minute, second;
 
2661
        int pivot = s.indexOf(QRegExp(QString::fromLatin1("[0-9][0-9]:[0-9][0-9]:[0-9][0-9]")));
 
2662
        if (pivot != -1) {
 
2663
            hour = s.mid(pivot, 2).toInt();
 
2664
            minute = s.mid(pivot + 3, 2).toInt();
 
2665
            second = s.mid(pivot + 6, 2).toInt();
 
2666
            time.setHMS(hour, minute, second);
 
2667
        }
 
2668
        return QDateTime(date, time);
 
2669
    }
 
2670
#endif //QT_NO_REGEXP
 
2671
    return QDateTime();
 
2672
}
 
2673
#endif //QT_NO_DATESTRING
 
2674
 
 
2675
/*!
 
2676
    \fn QDateTime::fromString(const QString &string, const QString &format)
 
2677
 
 
2678
    Returns the QDateTime represented by the \a string, using the \a
 
2679
    format given, or an invalid datetime if the string cannot be parsed.
 
2680
 
 
2681
    These expressions may be used for the date part of the format string:
 
2682
 
 
2683
    \table
 
2684
    \header \i Expression \i Output
 
2685
    \row \i d \i the day as number without a leading zero (1 to 31)
 
2686
    \row \i dd \i the day as number with a leading zero (01 to 31)
 
2687
    \row \i ddd
 
2688
            \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
 
2689
            Uses QDate::shortDayName().
 
2690
    \row \i dddd
 
2691
            \i the long localized day name (e.g. 'Qt::Monday' to 'Qt::Sunday').
 
2692
            Uses QDate::longDayName().
 
2693
    \row \i M \i the month as number without a leading zero (1-12)
 
2694
    \row \i MM \i the month as number with a leading zero (01-12)
 
2695
    \row \i MMM
 
2696
            \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
 
2697
            Uses QDate::shortMonthName().
 
2698
    \row \i MMMM
 
2699
            \i the long localized month name (e.g. 'January' to 'December').
 
2700
            Uses QDate::longMonthName().
 
2701
    \row \i yy \i the year as two digit number (00-99)
 
2702
    \row \i yyyy \i the year as four digit number (1752-8000)
 
2703
    \endtable
 
2704
 
 
2705
    These expressions may be used for the time part of the format string:
 
2706
 
 
2707
    \table
 
2708
    \header \i Expression \i Output
 
2709
    \row \i h
 
2710
            \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
 
2711
    \row \i hh
 
2712
            \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
 
2713
    \row \i m \i the minute without a leading zero (0 to 59)
 
2714
    \row \i mm \i the minute with a leading zero (00 to 59)
 
2715
    \row \i s \i the second whithout a leading zero (0 to 59)
 
2716
    \row \i ss \i the second whith a leading zero (00 to 59)
 
2717
    \row \i z \i the milliseconds without leading zeroes (0 to 999)
 
2718
    \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
 
2719
    \row \i AP
 
2720
         \i interpret as an AM/PM time. \e AP must be either "AM" or "PM".
 
2721
    \row \i ap
 
2722
         \i Interpret as an AM/PM time. \e ap must be either "am" or "pm".
 
2723
    \endtable
 
2724
 
 
2725
    All other input characters will be treated as text. Any sequence
 
2726
    of characters that are enclosed in singlequotes will also be
 
2727
    treated as text and not be used as an expression.
 
2728
 
 
2729
    \code
 
2730
        QDateTime dateTime = QDateTime::fromString("M1d1y9800:01:02",
 
2731
                                                   "'M'M'd'd'y'yyhh:mm:ss");
 
2732
        // dateTime is 1 January 1998 00:01:02
 
2733
    \endcode
 
2734
 
 
2735
    If the format is not satisfied an invalid QDateTime is returned.
 
2736
    The expressions that don't have leading zeroes (d, M, h, m, s, z) will be
 
2737
    greedy. This means that they will use two digits even if this will
 
2738
    put them outside the range and/or leave too few digits for other
 
2739
    sections.
 
2740
 
 
2741
    \code
 
2742
        QDateTime dateTime = QDateTime::fromString("130", "Mm"); // invalid
 
2743
    \endcode
 
2744
 
 
2745
    This could have meant 1 January 00:30.00 but the M will grab
 
2746
    two digits.
 
2747
 
 
2748
    For any field that is not represented in the format the following
 
2749
    defaults are used:
 
2750
 
 
2751
    \table
 
2752
    \header \i Field  \i Default value
 
2753
    \row    \i Year   \i The current year
 
2754
    \row    \i Month  \i 1 (January)
 
2755
    \row    \i Day    \i 1
 
2756
    \row    \i Hour   \i 0
 
2757
    \row    \i Minute \i 0
 
2758
    \row    \i Second \i 0
 
2759
    \endtable
 
2760
 
 
2761
    For example:
 
2762
 
 
2763
    \code
 
2764
        QDateTime dateTime = QDateTime::fromString("1.30.1", "M.d.s");
 
2765
        // dateTime is January 30 in the current year 00:00:01
 
2766
    \endcode
 
2767
 
 
2768
    \sa QDate::fromString() QTime::fromString() QDate::toString()
 
2769
    QDateTime::toString() QTime::toString()
 
2770
*/
 
2771
 
 
2772
QDateTime QDateTime::fromString(const QString &string, const QString &format)
 
2773
{
 
2774
    QDateTimeParser dt(format, QVariant::DateTime);
 
2775
    QTime time;
 
2776
    QDate date;
 
2777
    return dt.fromString(string, &date, &time) ? QDateTime(date, time) : QDateTime(QDate(), QTime(-1, -1, -1));
 
2778
}
 
2779
 
 
2780
/*!
 
2781
    \fn QDateTime QDateTime::toLocalTime() const
 
2782
 
 
2783
    Returns a datetime containing the date and time information in
 
2784
    this datetime, but specified using the Qt::LocalTime definition.
 
2785
 
 
2786
    \sa toTimeSpec()
 
2787
*/
 
2788
 
 
2789
/*!
 
2790
    \fn QDateTime QDateTime::toUTC() const
 
2791
 
 
2792
    Returns a datetime containing the date and time information in
 
2793
    this datetime, but specified using the Qt::UTC definition.
 
2794
 
 
2795
    \sa toTimeSpec()
 
2796
*/
 
2797
 
 
2798
/*! \internal
 
2799
 */
 
2800
void QDateTime::detach()
 
2801
{
 
2802
    qAtomicDetach(d);
 
2803
}
 
2804
 
 
2805
/*****************************************************************************
 
2806
  Date/time stream functions
 
2807
 *****************************************************************************/
 
2808
 
 
2809
#ifndef QT_NO_DATASTREAM
 
2810
/*!
 
2811
    \relates QDate
 
2812
 
 
2813
    Writes the \a date to stream \a out.
 
2814
 
 
2815
    \sa {Format of the QDataStream operators}
 
2816
*/
 
2817
 
 
2818
QDataStream &operator<<(QDataStream &out, const QDate &date)
 
2819
{
 
2820
    return out << (quint32)(date.jd);
 
2821
}
 
2822
 
 
2823
/*!
 
2824
    \relates QDate
 
2825
 
 
2826
    Reads a date from stream \a in into the \a date.
 
2827
 
 
2828
    \sa {Format of the QDataStream operators}
 
2829
*/
 
2830
 
 
2831
QDataStream &operator>>(QDataStream &in, QDate &date)
 
2832
{
 
2833
    quint32 jd;
 
2834
    in >> jd;
 
2835
    date.jd = jd;
 
2836
    return in;
 
2837
}
 
2838
 
 
2839
/*!
 
2840
    \relates QTime
 
2841
 
 
2842
    Writes \a time to stream \a out.
 
2843
 
 
2844
    \sa {Format of the QDataStream operators}
 
2845
*/
 
2846
 
 
2847
QDataStream &operator<<(QDataStream &out, const QTime &time)
 
2848
{
 
2849
    return out << (quint32)time.ds;
 
2850
}
 
2851
 
 
2852
/*!
 
2853
    \relates QTime
 
2854
 
 
2855
    Reads a time from stream \a in into the given \a time.
 
2856
 
 
2857
    \sa {Format of the QDataStream operators}
 
2858
*/
 
2859
 
 
2860
QDataStream &operator>>(QDataStream &in, QTime &time)
 
2861
{
 
2862
    quint32 ds;
 
2863
    in >> ds;
 
2864
    time.ds = ds;
 
2865
    return in;
 
2866
}
 
2867
 
 
2868
/*!
 
2869
    \relates QDateTime
 
2870
 
 
2871
    Writes \a dateTime to the \a out stream.
 
2872
 
 
2873
    \sa {Format of the QDataStream operators}
 
2874
*/
 
2875
QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime)
 
2876
{
 
2877
    out << dateTime.d->date << dateTime.d->time;
 
2878
    if (out.version() >= 7)
 
2879
        out << (qint8)dateTime.d->spec;
 
2880
    return out;
 
2881
}
 
2882
 
 
2883
/*!
 
2884
    \relates QDateTime
 
2885
 
 
2886
    Reads a datetime from the stream \a in into \a dateTime.
 
2887
 
 
2888
    \sa {Format of the QDataStream operators}
 
2889
*/
 
2890
 
 
2891
QDataStream &operator>>(QDataStream &in, QDateTime &dateTime)
 
2892
{
 
2893
    dateTime.detach();
 
2894
 
 
2895
    qint8 ts = (qint8)QDateTimePrivate::LocalUnknown;
 
2896
    in >> dateTime.d->date >> dateTime.d->time;
 
2897
    if (in.version() >= 7)
 
2898
        in >> ts;
 
2899
    dateTime.d->spec = (QDateTimePrivate::Spec)ts;
 
2900
    return in;
 
2901
}
 
2902
#endif // QT_NO_DATASTREAM
 
2903
 
 
2904
 
 
2905
/*!
 
2906
    \fn QString QDate::monthName(int month)
 
2907
 
 
2908
    Use shortMonthName() instead.
 
2909
*/
 
2910
 
 
2911
/*!
 
2912
    \fn QString QDate::dayName(int weekday)
 
2913
 
 
2914
    Use shortDayName() instead.
 
2915
*/
 
2916
 
 
2917
/*!
 
2918
    \fn bool QDate::leapYear(int year)
 
2919
 
 
2920
    Use isLeapYear() instead.
 
2921
*/
 
2922
 
 
2923
/*!
 
2924
    \fn QDate QDate::currentDate(Qt::TimeSpec spec)
 
2925
 
 
2926
    Use the currentDate() overload that takes no parameters; or
 
2927
    extract from currentDateTime() instead.
 
2928
*/
 
2929
 
 
2930
/*!
 
2931
    \fn QDate QTime::currentDate(Qt::TimeSpec spec)
 
2932
 
 
2933
    Use the currentDate() overload that takes no parameters; or
 
2934
    extract from currentDateTime() instead.
 
2935
*/
 
2936
 
 
2937
/*!
 
2938
    \fn QTime QTime::currentTime(Qt::TimeSpec spec)
 
2939
 
 
2940
    Use the currentTime() overload that takes no parameters; or
 
2941
    extract from currentDateTime() instead.
 
2942
*/
 
2943
 
 
2944
/*!
 
2945
    \fn void QDateTime::setTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec)
 
2946
 
 
2947
    Use the single-argument overload of setTime_t() instead.
 
2948
*/
 
2949
 
 
2950
/*!
 
2951
    \fn QDateTime QDateTime::currentDateTime(Qt::TimeSpec spec)
 
2952
 
 
2953
    Use the currentDateTime() overload that takes no parameters
 
2954
    instead.
 
2955
*/
 
2956
 
 
2957
#ifndef QT_NO_DATESTRING
 
2958
/*****************************************************************************
 
2959
  Some static function used by QDate, QTime and QDateTime
 
2960
*****************************************************************************/
 
2961
 
 
2962
// Replaces tokens by their value. See QDateTime::toString() for a list of valid tokens
 
2963
static QString getFmtString(const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = false)
 
2964
{
 
2965
    if (f.isEmpty())
 
2966
        return QString();
 
2967
 
 
2968
    QString buf = f;
 
2969
    int removed = 0;
 
2970
 
 
2971
    if (dt) {
 
2972
        if (f.startsWith(QLatin1String("hh"))) {
 
2973
            if ((am_pm) && (dt->hour() > 12))
 
2974
                buf = QString::number(dt->hour() - 12).rightJustified(2, QLatin1Char('0'), true);
 
2975
            else if ((am_pm) && (dt->hour() == 0))
 
2976
                buf = QLatin1String("12");
 
2977
            else
 
2978
                buf = QString::number(dt->hour()).rightJustified(2, QLatin1Char('0'), true);
 
2979
            removed = 2;
 
2980
        } else if (f.at(0) == QLatin1Char('h')) {
 
2981
            if ((am_pm) && (dt->hour() > 12))
 
2982
                buf = QString::number(dt->hour() - 12);
 
2983
            else if ((am_pm) && (dt->hour() == 0))
 
2984
                buf = QLatin1String("12");
 
2985
            else
 
2986
                buf = QString::number(dt->hour());
 
2987
            removed = 1;
 
2988
        } else if (f.startsWith(QLatin1String("mm"))) {
 
2989
            buf = QString::number(dt->minute()).rightJustified(2, QLatin1Char('0'), true);
 
2990
            removed = 2;
 
2991
        } else if (f.at(0) == (QLatin1Char('m'))) {
 
2992
            buf = QString::number(dt->minute());
 
2993
            removed = 1;
 
2994
        } else if (f.startsWith(QLatin1String("ss"))) {
 
2995
            buf = QString::number(dt->second()).rightJustified(2, QLatin1Char('0'), true);
 
2996
            removed = 2;
 
2997
        } else if (f.at(0) == QLatin1Char('s')) {
 
2998
            buf = QString::number(dt->second());
 
2999
        } else if (f.startsWith(QLatin1String("zzz"))) {
 
3000
            buf = QString::number(dt->msec()).rightJustified(3, QLatin1Char('0'), true);
 
3001
            removed = 3;
 
3002
        } else if (f.at(0) == QLatin1Char('z')) {
 
3003
            buf = QString::number(dt->msec());
 
3004
            removed = 1;
 
3005
        } else if (f.startsWith(QLatin1String("ap"))) {
 
3006
            buf = dt->hour() < 12 ? QLatin1String("am") : QLatin1String("pm");
 
3007
            removed = 2;
 
3008
        } else if (f.startsWith(QLatin1String("AP"))) {
 
3009
            buf = dt->hour() < 12 ? QLatin1String("AM") : QLatin1String("PM");
 
3010
            removed = 2;
 
3011
        }
 
3012
    }
 
3013
 
 
3014
    if (dd) {
 
3015
        if (f.startsWith(QLatin1String("dddd"))) {
 
3016
            buf = dd->longDayName(dd->dayOfWeek());
 
3017
            removed = 4;
 
3018
        } else if (f.startsWith(QLatin1String("ddd"))) {
 
3019
            buf = dd->shortDayName(dd->dayOfWeek());
 
3020
            removed = 3;
 
3021
        } else if (f.startsWith(QLatin1String("dd"))) {
 
3022
            buf = QString::number(dd->day()).rightJustified(2, QLatin1Char('0'), true);
 
3023
            removed = 2;
 
3024
        } else if (f.at(0) == QLatin1Char('d')) {
 
3025
            buf = QString::number(dd->day());
 
3026
            removed = 1;
 
3027
        } else if (f.startsWith(QLatin1String("MMMM"))) {
 
3028
            buf = dd->longMonthName(dd->month());
 
3029
            removed = 4;
 
3030
        } else if (f.startsWith(QLatin1String("MMM"))) {
 
3031
            buf = dd->shortMonthName(dd->month());
 
3032
            removed = 3;
 
3033
        } else if (f.startsWith(QLatin1String("MM"))) {
 
3034
            buf = QString::number(dd->month()).rightJustified(2, QLatin1Char('0'), true);
 
3035
            removed = 2;
 
3036
        } else if (f.at(0) == QLatin1Char('M')) {
 
3037
            buf = QString::number(dd->month());
 
3038
            removed = 1;
 
3039
        } else if (f.startsWith(QLatin1String("yyyy"))) {
 
3040
            buf = QString::number(dd->year());
 
3041
            removed = 4;
 
3042
        } else if (f.startsWith(QLatin1String("yy"))) {
 
3043
            buf = QString::number(dd->year()).right(2);
 
3044
            removed = 2;
 
3045
        }
 
3046
    }
 
3047
    if (removed == 0 || removed >= f.size())
 
3048
        return buf;
 
3049
    return buf + getFmtString(f.mid(removed), dt, dd, am_pm);
 
3050
}
 
3051
 
 
3052
// checks if there is an unqoted 'AP' or 'ap' in the string
 
3053
static bool hasUnqutedAP(const QString &f)
 
3054
{
 
3055
    const char quote = '\'';
 
3056
    QChar status = QLatin1Char('0');
 
3057
    for (int i=0; i<f.size(); ++i) {
 
3058
        if (f.at(i) == quote) {
 
3059
            if (status == quote) {
 
3060
                if (f.at(i - 1) != QLatin1Char('\\'))
 
3061
                    status = QLatin1Char('0');
 
3062
            } else {
 
3063
                status = quote;
 
3064
            }
 
3065
        } else if (status != quote) {
 
3066
            if (f.at(i).toUpper() == QLatin1Char('A')) {
 
3067
                status = f.at(i);
 
3068
            } else if ((f.at(i) == QLatin1Char('p') && status == QLatin1Char('a'))
 
3069
                    || (f.at(i) == QLatin1Char('P') && status == QLatin1Char('A'))) {
 
3070
                return true;
 
3071
            } else {
 
3072
                status = QLatin1Char('0');
 
3073
            }
 
3074
        }
 
3075
    }
 
3076
 
 
3077
    return false;
 
3078
}
 
3079
 
 
3080
// Parses the format string and uses getFmtString to get the values for the tokens. Ret
 
3081
static QString fmtDateTime(const QString& f, const QTime* dt, const QDate* dd)
 
3082
{
 
3083
    const char quote = '\'';
 
3084
    if (f.isEmpty())
 
3085
        return QString();
 
3086
    if (dt && !dt->isValid())
 
3087
        return QString();
 
3088
    if (dd && !dd->isValid())
 
3089
        return QString();
 
3090
 
 
3091
    bool ap = hasUnqutedAP(f);
 
3092
 
 
3093
    QString buf;
 
3094
    QString frm;
 
3095
    QChar status = QLatin1Char('0');
 
3096
 
 
3097
    for (int i = 0; i < (int)f.length(); ++i) {
 
3098
        if (f.at(i) == quote) {
 
3099
            if (status == quote) {
 
3100
                status = QLatin1Char('0');
 
3101
            } else {
 
3102
                if (!frm.isEmpty()) {
 
3103
                    buf += getFmtString(frm, dt, dd, ap);
 
3104
                    frm.clear();
 
3105
                }
 
3106
                status = quote;
 
3107
            }
 
3108
        } else if (status == quote) {
 
3109
            buf += f.at(i);
 
3110
        } else if (f.at(i) == status) {
 
3111
            if ((ap) && ((f.at(i) == QLatin1Char('P')) || (f.at(i) == QLatin1Char('p'))))
 
3112
                status = QLatin1Char('0');
 
3113
            frm += f.at(i);
 
3114
        } else {
 
3115
            buf += getFmtString(frm, dt, dd, ap);
 
3116
            frm.clear();
 
3117
            if ((f.at(i) == QLatin1Char('h')) || (f.at(i) == QLatin1Char('m'))
 
3118
                || (f.at(i) == QLatin1Char('s')) || (f.at(i) == QLatin1Char('z'))) {
 
3119
                status = f.at(i);
 
3120
                frm += f.at(i);
 
3121
            } else if ((f.at(i) == QLatin1Char('d')) || (f.at(i) == QLatin1Char('M')) || (f.at(i) == QLatin1Char('y'))) {
 
3122
                status = f.at(i);
 
3123
                frm += f.at(i);
 
3124
            } else if ((ap) && (f.at(i) == QLatin1Char('A'))) {
 
3125
                status = QLatin1Char('P');
 
3126
                frm += f.at(i);
 
3127
            } else  if((ap) && (f.at(i) == QLatin1Char('a'))) {
 
3128
                status = QLatin1Char('p');
 
3129
                frm += f.at(i);
 
3130
            } else {
 
3131
                buf += f.at(i);
 
3132
                status = QLatin1Char('0');
 
3133
            }
 
3134
        }
 
3135
    }
 
3136
 
 
3137
    buf += getFmtString(frm, dt, dd, ap);
 
3138
 
 
3139
    return buf;
 
3140
}
 
3141
#endif // QT_NO_DATESTRING
 
3142
 
 
3143
#ifdef Q_OS_WIN
 
3144
static const int LowerYear = 1980;
 
3145
#else
 
3146
static const int LowerYear = 1970;
 
3147
#endif
 
3148
 
 
3149
static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time)
 
3150
{
 
3151
    QDate lowerLimit(LowerYear, 1, 2);
 
3152
    QDate upperLimit(2037, 12, 30);
 
3153
 
 
3154
    QDate fakeDate = date;
 
3155
 
 
3156
    if (fakeDate < lowerLimit) {
 
3157
        fakeDate = lowerLimit;
 
3158
    } else if (fakeDate > upperLimit) {
 
3159
        fakeDate = upperLimit;
 
3160
    }
 
3161
 
 
3162
    time_t secsSince1Jan1970UTC = toTime_t(fakeDate, time);
 
3163
 
 
3164
#if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
 
3165
    // use the reentrant version of localtime() where available
 
3166
    tm res;
 
3167
    tm *brokenDown = localtime_r(&secsSince1Jan1970UTC, &res);
 
3168
#else
 
3169
    tm *brokenDown = localtime(&secsSince1Jan1970UTC);
 
3170
#endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
 
3171
    if (!brokenDown) {
 
3172
        date = QDate(1970, 1, 1);
 
3173
        time = QTime();
 
3174
        return QDateTimePrivate::LocalUnknown;
 
3175
    } else {
 
3176
        int deltaDays = fakeDate.daysTo(date);
 
3177
        date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
 
3178
        time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec);
 
3179
        date = date.addDays(deltaDays);
 
3180
        if (brokenDown->tm_isdst > 0)
 
3181
            return QDateTimePrivate::LocalDST;
 
3182
        else if (brokenDown->tm_isdst < 0)
 
3183
            return QDateTimePrivate::LocalUnknown;
 
3184
        else
 
3185
            return QDateTimePrivate::LocalStandard;
 
3186
    }
 
3187
}
 
3188
 
 
3189
static void localToUtc(QDate &date, QTime &time, int isdst)
 
3190
{
 
3191
    if (!date.isValid())
 
3192
        return;
 
3193
 
 
3194
    QDate lowerLimit(LowerYear, 1, 2);
 
3195
    QDate upperLimit(2037, 12, 30);
 
3196
 
 
3197
    QDate fakeDate = date;
 
3198
 
 
3199
    if (fakeDate < lowerLimit) {
 
3200
        fakeDate = lowerLimit;
 
3201
        isdst = false;
 
3202
    } else if (fakeDate > upperLimit) {
 
3203
        fakeDate = upperLimit;
 
3204
        isdst = false;
 
3205
    }
 
3206
 
 
3207
    tm localTM;
 
3208
    localTM.tm_sec = time.second();
 
3209
    localTM.tm_min = time.minute();
 
3210
    localTM.tm_hour = time.hour();
 
3211
    localTM.tm_mday = fakeDate.day();
 
3212
    localTM.tm_mon = fakeDate.month() - 1;
 
3213
    localTM.tm_year = fakeDate.year() - 1900;
 
3214
    localTM.tm_isdst = (int)isdst;
 
3215
 
 
3216
    time_t secsSince1Jan1970UTC = mktime(&localTM);
 
3217
 
 
3218
#if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
 
3219
    // use the reentrant version of gmtime() where available
 
3220
    tm res;
 
3221
    tm *brokenDown = gmtime_r(&secsSince1Jan1970UTC, &res);
 
3222
#else
 
3223
    tm *brokenDown = gmtime(&secsSince1Jan1970UTC);
 
3224
#endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
 
3225
    if (!brokenDown) {
 
3226
        date = QDate(1970, 1, 1);
 
3227
        time = QTime();
 
3228
    } else {
 
3229
        int deltaDays = fakeDate.daysTo(date);
 
3230
        date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);
 
3231
        time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec);
 
3232
        date = date.addDays(deltaDays);
 
3233
    }
 
3234
}
 
3235
 
 
3236
QDateTimePrivate::Spec QDateTimePrivate::getLocal(QDate &outDate, QTime &outTime) const
 
3237
{
 
3238
    outDate = date;
 
3239
    outTime = time;
 
3240
    if (spec == QDateTimePrivate::UTC)
 
3241
        return utcToLocal(outDate, outTime);
 
3242
    return spec;
 
3243
}
 
3244
 
 
3245
void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const
 
3246
{
 
3247
    outDate = date;
 
3248
    outTime = time;
 
3249
    if (spec != QDateTimePrivate::UTC)
 
3250
        localToUtc(outDate, outTime, (int)spec);
 
3251
}
 
3252
 
 
3253
#ifndef QT_NO_DEBUG_STREAM
 
3254
QDebug operator<<(QDebug dbg, const QDate &date)
 
3255
{
 
3256
    dbg.nospace() << "QDate(" << date.toString() << ")";
 
3257
    return dbg.space();
 
3258
}
 
3259
 
 
3260
QDebug operator<<(QDebug dbg, const QTime &time)
 
3261
{
 
3262
    dbg.nospace() << "QTime(" << time.toString() << ")";
 
3263
    return dbg.space();
 
3264
}
 
3265
 
 
3266
QDebug operator<<(QDebug dbg, const QDateTime &date)
 
3267
{
 
3268
    dbg.nospace() << "QDateTime(" << date.toString() << ")";
 
3269
    return dbg.space();
 
3270
}
 
3271
#endif
 
3272
 
 
3273
QFormatSection QDateTimeParser::firstSection = QFormatSection(0, QDateTimeParser::FirstSection);
 
3274
QFormatSection QDateTimeParser::lastSection = QFormatSection(-1, QDateTimeParser::LastSection);
 
3275
 
 
3276
QFormatSection::QFormatSection(int ind, const QString &sep)
 
3277
    : index(ind), chars(sep), type(QDateTimeParser::Separator)
 
3278
{
 
3279
}
 
3280
 
 
3281
QFormatSection::QFormatSection(int ind, QDateTimeParser::Section typ)
 
3282
    : index(ind), type(typ)
 
3283
{
 
3284
}
 
3285
 
 
3286
int QFormatSection::length() const
 
3287
{
 
3288
    return type == QDateTimeParser::Separator ? chars.size() : QFormatSection::length(type);
 
3289
}
 
3290
 
 
3291
int QFormatSection::length(QDateTimeParser::Section t)
 
3292
{
 
3293
    switch (t) {
 
3294
    case QDateTimeParser::Day1: case QDateTimeParser::Month1: case QDateTimeParser::Hour1: case QDateTimeParser::Minute1:
 
3295
    case QDateTimeParser::Second1: case QDateTimeParser::MSecond1: case QDateTimeParser::Quote: return 1;
 
3296
 
 
3297
    case QDateTimeParser::Day2: case QDateTimeParser::Month2: case QDateTimeParser::Year2: case QDateTimeParser::Hour2:
 
3298
    case QDateTimeParser::Minute2: case QDateTimeParser::Second2: case QDateTimeParser::APLower: case QDateTimeParser::APUpper: return 2;
 
3299
 
 
3300
    case QDateTimeParser::Day3: case QDateTimeParser::Month3: case QDateTimeParser::MSecond3: return 3;
 
3301
 
 
3302
    case QDateTimeParser::Day4: case QDateTimeParser::Month4: case QDateTimeParser::Year4: return 4;
 
3303
 
 
3304
    default:
 
3305
        qWarning("%s:%d QDateTimeParser::length() %d should never be called here", __FILE__, __LINE__, t);
 
3306
        return 0;
 
3307
    }
 
3308
}
 
3309
 
 
3310
QDateTimeParser::QDateTimeParser(const QString &f, QVariant::Type t)
 
3311
    : display(0)
 
3312
{
 
3313
    parseFormat(f, t);
 
3314
}
 
3315
 
 
3316
bool QDateTimeParser::withinBounds(QDateTimeParser::Section t, int num)
 
3317
{
 
3318
    int min, max;
 
3319
    if (t == QDateTimeParser::Year2) {
 
3320
        min = 0; max = 99;
 
3321
    } else if (t == QDateTimeParser::Day3 || t == QDateTimeParser::Day4) {
 
3322
        min = 1; max = 7;
 
3323
    } else if (t == QDateTimeParser::Year4) {
 
3324
        min = 1752; max = 7999;
 
3325
    } else if (t & QDateTimeParser::MonthMask) {
 
3326
        min = 1; max = 12;
 
3327
    } else if (t & QDateTimeParser::DayMask) {
 
3328
        min = 1; max = 31;
 
3329
    } else if (t & QDateTimeParser::HourMask) {
 
3330
        min = 0; max = 23;
 
3331
    } else if (t & QDateTimeParser::MinuteMask) {
 
3332
        min = 0; max = 59;
 
3333
    } else if (t & QDateTimeParser::SecondMask) {
 
3334
        min = 0; max = 59;
 
3335
    } else if (t & QDateTimeParser::MSecondMask) {
 
3336
        min = 0; max = 999;
 
3337
    } else {
 
3338
        qWarning("%s:%d QDateTimeParser::withinBounds() %0x should never be called with this argument", __FILE__, __LINE__, t);
 
3339
        return false;
 
3340
    }
 
3341
 
 
3342
    return num >= min && num <= max;
 
3343
}
 
3344
 
 
3345
int QDateTimeParser::getNumber(int index, const QString &str, int mindigits, int maxdigits, bool *ok, int *digits)
 
3346
{
 
3347
    if (str.size() < index + mindigits) {
 
3348
        *ok = false;
 
3349
        *digits = 0;
 
3350
        return 0;
 
3351
    }
 
3352
    *digits = 0;
 
3353
    int i = index;
 
3354
 
 
3355
    while (i < str.size() && str.at(i++).isNumber() && *digits < maxdigits)
 
3356
        ++(*digits);
 
3357
 
 
3358
    if (*digits < mindigits) {
 
3359
        *ok = false;
 
3360
        *digits = 0;
 
3361
        return 0;
 
3362
    } else {
 
3363
        return str.mid(index, *digits).toInt(ok);
 
3364
    }
 
3365
}
 
3366
 
 
3367
bool QDateTimeParser::isSpecial(const QChar &c) const
 
3368
{
 
3369
    switch (c.cell()) {
 
3370
    case 'd': case 'M': case 'y':
 
3371
        return (formatType == QVariant::Date || formatType == QVariant::DateTime);
 
3372
    case 'h': case 'm': case 's': case 'z': case 'a': case 'p': case 'A': case 'P':
 
3373
        return (formatType == QVariant::Time || formatType == QVariant::DateTime);
 
3374
    case '\'': return true;
 
3375
    default: return false;
 
3376
    }
 
3377
}
 
3378
 
 
3379
QFormatSection QDateTimeParser::findNextFormat(const QString &str, const int start)
 
3380
{
 
3381
    const char quote = '\'';
 
3382
    int i = start;
 
3383
    QDateTimeParser::Section typ = QDateTimeParser::NoSection;
 
3384
    while (i < str.size()) {
 
3385
        const QChar &ch = str.at(i);
 
3386
        if (isSpecial(ch)) {
 
3387
            const QString rest = str.mid(i);
 
3388
            switch (ch.cell()) {
 
3389
            case quote: typ = QDateTimeParser::Quote; break;
 
3390
            case 'd':
 
3391
                if (rest.startsWith(QLatin1String("dddd"))) {
 
3392
                    typ = QDateTimeParser::Day4;
 
3393
                } else if (rest.startsWith(QLatin1String("ddd"))) {
 
3394
                    typ = QDateTimeParser::Day3;
 
3395
                } else if (rest.startsWith(QLatin1String("dd"))) {
 
3396
                    typ = QDateTimeParser::Day2;
 
3397
                } else {
 
3398
                    typ = QDateTimeParser::Day1;
 
3399
                }
 
3400
                break;
 
3401
            case 'M':
 
3402
                if (rest.startsWith(QLatin1String("MMMM"))) {
 
3403
                    typ = QDateTimeParser::Month4;
 
3404
                } else if (rest.startsWith(QLatin1String("MMM"))) {
 
3405
                    typ = QDateTimeParser::Month3;
 
3406
                } else if (rest.startsWith(QLatin1String("MM"))) {
 
3407
                    typ = QDateTimeParser::Month2;
 
3408
                } else {
 
3409
                    typ = QDateTimeParser::Month1;
 
3410
                }
 
3411
                break;
 
3412
 
 
3413
            case 'y':
 
3414
                if (rest.startsWith(QLatin1String("yyyy"))) {
 
3415
                    typ = QDateTimeParser::Year4;
 
3416
                } else if (rest.startsWith(QLatin1String("yy"))) {
 
3417
                    typ = QDateTimeParser::Year2;
 
3418
                }
 
3419
                break;
 
3420
 
 
3421
            case 'h':
 
3422
                if (rest.startsWith(QLatin1String("hh"))) {
 
3423
                    typ = QDateTimeParser::Hour2;
 
3424
                } else {
 
3425
                    typ = QDateTimeParser::Hour1;
 
3426
                }
 
3427
                break;
 
3428
 
 
3429
            case 'm':
 
3430
                if (rest.startsWith(QLatin1String("mm"))) {
 
3431
                    typ = QDateTimeParser::Minute2;
 
3432
                } else {
 
3433
                    typ = QDateTimeParser::Minute1;
 
3434
                }
 
3435
                break;
 
3436
 
 
3437
            case 's':
 
3438
                if (rest.startsWith(QLatin1String("ss"))) {
 
3439
                    typ = QDateTimeParser::Second2;
 
3440
                } else {
 
3441
                    typ = QDateTimeParser::Second1;
 
3442
                }
 
3443
                break;
 
3444
 
 
3445
            case 'z':
 
3446
                if (rest.startsWith(QLatin1String("zzz"))) {
 
3447
                    typ = QDateTimeParser::MSecond3;
 
3448
                } else {
 
3449
                    typ = QDateTimeParser::MSecond1;
 
3450
                }
 
3451
                break;
 
3452
 
 
3453
            case 'a':
 
3454
                if (rest.count() > 1 && rest.at(1) == QLatin1Char('p')) {
 
3455
                    typ = QDateTimeParser::APLower;
 
3456
                }
 
3457
                break;
 
3458
 
 
3459
            case 'A':
 
3460
                if (rest.count() > 1 && rest.at(1) == QLatin1Char('P')) {
 
3461
                    typ = QDateTimeParser::APUpper;
 
3462
                }
 
3463
                break;
 
3464
 
 
3465
            default: qFatal("Should never happen"); break;
 
3466
            }
 
3467
 
 
3468
            if (typ != QDateTimeParser::NoSection) {
 
3469
                if (i == start) {
 
3470
                    return QFormatSection(start, typ);
 
3471
                } else {
 
3472
                    break; // found a separator before this section
 
3473
                }
 
3474
            }
 
3475
        }
 
3476
        ++i;
 
3477
    }
 
3478
    return QFormatSection(start, str.mid(start, i - start));
 
3479
}
 
3480
 
 
3481
void QDateTimeParser::parseFormat(const QString &f, QVariant::Type t)
 
3482
{
 
3483
    const char quote = '\'';
 
3484
    display = 0;
 
3485
    formatType = t;
 
3486
    format = f;
 
3487
    sect.clear();
 
3488
 
 
3489
    int i = 0;
 
3490
    while (i < format.size()) {
 
3491
        QFormatSection s;
 
3492
        if (format.at(i) == quote) {
 
3493
            int nextQuote = format.indexOf(quote, i + 1);
 
3494
            if (nextQuote == -1)
 
3495
                nextQuote = format.size() + 1;
 
3496
            s = QFormatSection(i, format.mid(i, nextQuote - i + 1));
 
3497
        } else {
 
3498
            s = findNextFormat(format, i);
 
3499
        }
 
3500
        if (s.type == QDateTimeParser::Separator && !sect.isEmpty() && sect.last().type == QDateTimeParser::Separator) {
 
3501
            sect.last().chars += s.chars;
 
3502
        } else {
 
3503
            sect << s;
 
3504
            display |= s.type;
 
3505
        }
 
3506
        i = s.index + s.length();
 
3507
    }
 
3508
}
 
3509
 
 
3510
bool QDateTimeParser::fromString(const QString &string, QDate *dateIn, QTime *timeIn)
 
3511
{
 
3512
    Q_ASSERT(dateIn || timeIn);
 
3513
    const char quote = '\'';
 
3514
    int msec = -1;
 
3515
    int sec = -1;
 
3516
    int minute = -1;
 
3517
    int hour = -1;
 
3518
    int day = -1;
 
3519
    int month = -1;
 
3520
    int year = -1;
 
3521
    int ampm = -1;
 
3522
    int dayOfWeek = -1;
 
3523
 
 
3524
    int index = 0;
 
3525
    int i = 0;
 
3526
    while (i<sect.size()) {
 
3527
        if (index >= string.size()) {
 
3528
            return false;
 
3529
        }
 
3530
        int *num = 0;
 
3531
        QString (*nameFunction)(int) = 0;
 
3532
        const char * const * nameArray = 0;
 
3533
        int max = -1;
 
3534
        int min = 1;
 
3535
        const QFormatSection &s = sect.at(i);
 
3536
        switch (s.type) {
 
3537
        case QDateTimeParser::Separator: {
 
3538
            QString sep = s.chars;
 
3539
            sep.remove(quote);
 
3540
 
 
3541
            if (string.mid(index, sep.length()) != sep) {
 
3542
                return false;
 
3543
            }
 
3544
            index += sep.size();
 
3545
            break; }
 
3546
 
 
3547
        case QDateTimeParser::APLower: {
 
3548
        case QDateTimeParser::APUpper:
 
3549
            const QChar a = s.type == QDateTimeParser::APLower ? QLatin1Char('a') : QLatin1Char('A');
 
3550
            const QChar p = s.type == QDateTimeParser::APLower ? QLatin1Char('p') : QLatin1Char('P');
 
3551
            const QChar m = s.type == QDateTimeParser::APLower ? QLatin1Char('m') : QLatin1Char('M');
 
3552
 
 
3553
            if ((string.at(index) != a && string.at(index) != p)
 
3554
                || string.size() < index + 2
 
3555
                || string.at(index + 1) != m) {
 
3556
                return false;
 
3557
            }
 
3558
            int newampm = string.at(index) == a ? 0 : 1;
 
3559
            if (ampm != -1 && newampm != ampm) {
 
3560
                return false;
 
3561
            }
 
3562
            ampm = newampm;
 
3563
            index += 2;
 
3564
            break; }
 
3565
 
 
3566
        case QDateTimeParser::Day3: num = &day; nameFunction = &QDate::shortDayName; nameArray = qt_shortDayNames; max = 7; break;
 
3567
        case QDateTimeParser::Day4: num = &day; nameFunction = &QDate::longDayName; nameArray = qt_longDayNames; max = 7; break;
 
3568
        case QDateTimeParser::Month3: num = &month; nameFunction = &QDate::shortMonthName; nameArray = qt_shortMonthNames; max = 12; break;
 
3569
        case QDateTimeParser::Month4: num = &month; nameFunction = &QDate::longMonthName; nameArray = qt_longMonthNames; max = 12; break;
 
3570
 
 
3571
        case QDateTimeParser::Day1: num = &day; max = 2; break;
 
3572
        case QDateTimeParser::Month1: num = &month; max = 2; break;
 
3573
        case QDateTimeParser::Hour1: num = &hour; max = 2; break;
 
3574
        case QDateTimeParser::Minute1: num = &minute; max = 2; break;
 
3575
        case QDateTimeParser::Second1: num = &sec; max = 2; break;
 
3576
        case QDateTimeParser::MSecond1: num = &msec; max = 3; break;
 
3577
        case QDateTimeParser::Day2: num = &day; min = 2; max = 2; break;
 
3578
        case QDateTimeParser::Month2: num = &month; min = 2; max = 2; break;
 
3579
        case QDateTimeParser::Year2: num = &year; min = 2; max = 2; break;
 
3580
        case QDateTimeParser::Hour2: num = &hour; min = 2; max = 2; break;
 
3581
        case QDateTimeParser::Minute2: num = &minute; min = 2; max = 2; break;
 
3582
        case QDateTimeParser::Second2: num = &sec; min = 2; max = 2; break;
 
3583
        case QDateTimeParser::MSecond3: num = &msec; min = 3; max = 3; break;
 
3584
        case QDateTimeParser::Year4: num = &year; min = 4; max = 4; break;
 
3585
 
 
3586
        default:
 
3587
            qWarning("%s:%d QDateTimeParser::fromString() %d should never be called here", __FILE__, __LINE__, s.type);
 
3588
            return false;
 
3589
        }
 
3590
 
 
3591
        if (nameFunction) {
 
3592
            const QString rest = string.mid(index);
 
3593
            int add = -1;
 
3594
            int j;
 
3595
            for (j=min; j<=max; ++j) {
 
3596
                const QString tmp = nameFunction(j);
 
3597
                if (rest.startsWith(tmp)) {
 
3598
                    add = tmp.size();
 
3599
                    break;
 
3600
                }
 
3601
                const QLatin1String tmp2(nameArray[j - 1]);
 
3602
                if (rest.startsWith(tmp2)) {
 
3603
                    add = strlen(tmp2.latin1());
 
3604
                    break;
 
3605
                }
 
3606
            }
 
3607
            if (j > max || (*num != -1 && *num != j) || add == -1) {
 
3608
                return false;
 
3609
            }
 
3610
            *num = j;
 
3611
            index += add;
 
3612
        } else if (num) {
 
3613
            bool ok;
 
3614
            int digits;
 
3615
            int number = getNumber(index, string, min, max, &ok, &digits);
 
3616
            if (!ok || !withinBounds(s.type, number) || (*num != -1 && *num != number)) {
 
3617
                return false;
 
3618
            }
 
3619
 
 
3620
            *num = number;
 
3621
            index += digits;
 
3622
        }
 
3623
        ++i;
 
3624
    }
 
3625
    if (index < string.size()) {
 
3626
        return false;
 
3627
    }
 
3628
 
 
3629
    if (month == -1)
 
3630
        month = 1;
 
3631
    if (year == -1)
 
3632
        year = QDate::currentDate().year();
 
3633
    if (dayOfWeek != -1) {
 
3634
        if (day != -1) {
 
3635
            QDate dt(year, month, day);
 
3636
            if (dt.dayOfWeek() != dayOfWeek) {
 
3637
                return false;
 
3638
            }
 
3639
        } else {
 
3640
            QDate dt(year, month, 1);
 
3641
            if (dt.dayOfWeek() < dayOfWeek) {
 
3642
                dt = dt.addDays(dayOfWeek - dt.dayOfWeek());
 
3643
            } else if (dt.dayOfWeek() > dayOfWeek) {
 
3644
                dt = dt.addDays(7 + dayOfWeek - dt.dayOfWeek());
 
3645
            }
 
3646
            day = dt.day();
 
3647
        }
 
3648
    }
 
3649
    if (day == -1)
 
3650
        day = 1;
 
3651
    if (hour == -1)
 
3652
        hour = 0;
 
3653
    if (minute == -1)
 
3654
        minute = 0;
 
3655
    if (sec == -1)
 
3656
        sec = 0;
 
3657
    if (msec == -1)
 
3658
        msec = 0;
 
3659
    if (ampm == 0){
 
3660
        if (hour == 12) {
 
3661
            hour = 0;
 
3662
        } else if (hour > 12) {
 
3663
            return false;
 
3664
        }
 
3665
    } else if (ampm == 1) {
 
3666
        if (hour < 12) {
 
3667
            hour += 12;
 
3668
        } else if (hour > 12) {
 
3669
            return false;
 
3670
        }
 
3671
    }
 
3672
 
 
3673
    if (timeIn) {
 
3674
        QTime t(hour, minute, sec, msec);
 
3675
        if (!t.isValid()) {
 
3676
            return false;
 
3677
        }
 
3678
        *timeIn = t;
 
3679
    }
 
3680
 
 
3681
    if (dateIn) {
 
3682
        QDate dt(year, month, day);
 
3683
        if (!dt.isValid()) {
 
3684
            return false;
 
3685
        }
 
3686
        *dateIn = dt;
 
3687
    }
 
3688
 
 
3689
    return true;
 
3690
}