/****************************************************************************+ −
**+ −
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).+ −
** All rights reserved.+ −
** Contact: Nokia Corporation (qt-info@nokia.com)+ −
**+ −
** This file is part of the QtCore module of the Qt Toolkit.+ −
**+ −
** $QT_BEGIN_LICENSE:LGPL$+ −
** No Commercial Usage+ −
** This file contains pre-release code and may not be distributed.+ −
** You may use this file in accordance with the terms and conditions+ −
** contained in the Technology Preview License Agreement accompanying+ −
** this package.+ −
**+ −
** GNU Lesser General Public License Usage+ −
** Alternatively, this file may be used under the terms of the GNU Lesser+ −
** General Public License version 2.1 as published by the Free Software+ −
** Foundation and appearing in the file LICENSE.LGPL included in the+ −
** packaging of this file. Please review the following information to+ −
** ensure the GNU Lesser General Public License version 2.1 requirements+ −
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.+ −
**+ −
** In addition, as a special exception, Nokia gives you certain additional+ −
** rights. These rights are described in the Nokia Qt LGPL Exception+ −
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.+ −
**+ −
** If you have questions regarding the use of this file, please contact+ −
** Nokia at qt-info@nokia.com.+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
** $QT_END_LICENSE$+ −
**+ −
****************************************************************************/+ −
+ −
#include "qplatformdefs.h"+ −
#include "private/qdatetime_p.h"+ −
+ −
#include "qdatastream.h"+ −
#include "qset.h"+ −
#include "qlocale.h"+ −
#include "qdatetime.h"+ −
#include "qregexp.h"+ −
#include "qdebug.h"+ −
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)+ −
#include <qt_windows.h>+ −
#endif+ −
#ifndef Q_WS_WIN+ −
#include <locale.h>+ −
#endif+ −
+ −
#include <time.h>+ −
#if defined(Q_OS_WINCE)+ −
#include "qfunctions_wince.h"+ −
#endif+ −
+ −
//#define QDATETIMEPARSER_DEBUG+ −
#if defined (QDATETIMEPARSER_DEBUG) && !defined(QT_NO_DEBUG_STREAM)+ −
# define QDTPDEBUG qDebug() << QString("%1:%2").arg(__FILE__).arg(__LINE__)+ −
# define QDTPDEBUGN qDebug+ −
#else+ −
# define QDTPDEBUG if (false) qDebug()+ −
# define QDTPDEBUGN if (false) qDebug+ −
#endif+ −
+ −
#if defined(Q_WS_MAC)+ −
#include <private/qcore_mac_p.h>+ −
#endif+ −
+ −
#if defined(Q_OS_SYMBIAN)+ −
#include <e32std.h>+ −
#endif+ −
+ −
QT_BEGIN_NAMESPACE+ −
+ −
enum {+ −
FIRST_YEAR = -4713,+ −
FIRST_MONTH = 1,+ −
FIRST_DAY = 2, // ### Qt 5: make FIRST_DAY = 1, by support jd == 0 as valid+ −
SECS_PER_DAY = 86400,+ −
MSECS_PER_DAY = 86400000,+ −
SECS_PER_HOUR = 3600,+ −
MSECS_PER_HOUR = 3600000,+ −
SECS_PER_MIN = 60,+ −
MSECS_PER_MIN = 60000,+ −
JULIAN_DAY_FOR_EPOCH = 2440588 // result of julianDayFromGregorianDate(1970, 1, 1)+ −
};+ −
+ −
static inline QDate fixedDate(int y, int m, int d)+ −
{+ −
QDate result(y, m, 1);+ −
result.setDate(y, m, qMin(d, result.daysInMonth()));+ −
return result;+ −
}+ −
+ −
static inline uint julianDayFromGregorianDate(int year, int month, int day)+ −
{+ −
// Gregorian calendar starting from October 15, 1582+ −
// Algorithm from Henry F. Fliegel and Thomas C. Van Flandern+ −
return (1461 * (year + 4800 + (month - 14) / 12)) / 4+ −
+ (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12+ −
- (3 * ((year + 4900 + (month - 14) / 12) / 100)) / 4+ −
+ day - 32075;+ −
}+ −
+ −
static uint julianDayFromDate(int year, int month, int day)+ −
{+ −
if (year < 0)+ −
++year;+ −
+ −
if (year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15)))) {+ −
return julianDayFromGregorianDate(year, month, day);+ −
} else if (year < 1582 || (year == 1582 && (month < 10 || (month == 10 && day <= 4)))) {+ −
// Julian calendar until October 4, 1582+ −
// Algorithm from Frequently Asked Questions about Calendars by Claus Toendering+ −
int a = (14 - month) / 12;+ −
return (153 * (month + (12 * a) - 3) + 2) / 5+ −
+ (1461 * (year + 4800 - a)) / 4+ −
+ day - 32083;+ −
} else {+ −
// the day following October 4, 1582 is October 15, 1582+ −
return 0;+ −
}+ −
}+ −
+ −
static void getDateFromJulianDay(uint julianDay, int *year, int *month, int *day)+ −
{+ −
int y, m, d;+ −
+ −
if (julianDay >= 2299161) {+ −
// Gregorian calendar starting from October 15, 1582+ −
// This algorithm is from Henry F. Fliegel and Thomas C. Van Flandern+ −
qulonglong ell, n, i, j;+ −
ell = qulonglong(julianDay) + 68569;+ −
n = (4 * ell) / 146097;+ −
ell = ell - (146097 * n + 3) / 4;+ −
i = (4000 * (ell + 1)) / 1461001;+ −
ell = ell - (1461 * i) / 4 + 31;+ −
j = (80 * ell) / 2447;+ −
d = ell - (2447 * j) / 80;+ −
ell = j / 11;+ −
m = j + 2 - (12 * ell);+ −
y = 100 * (n - 49) + i + ell;+ −
} else {+ −
// Julian calendar until October 4, 1582+ −
// Algorithm from Frequently Asked Questions about Calendars by Claus Toendering+ −
julianDay += 32082;+ −
int dd = (4 * julianDay + 3) / 1461;+ −
int ee = julianDay - (1461 * dd) / 4;+ −
int mm = ((5 * ee) + 2) / 153;+ −
d = ee - (153 * mm + 2) / 5 + 1;+ −
m = mm + 3 - 12 * (mm / 10);+ −
y = dd - 4800 + (mm / 10);+ −
if (y <= 0)+ −
--y;+ −
}+ −
if (year)+ −
*year = y;+ −
if (month)+ −
*month = m;+ −
if (day)+ −
*day = d;+ −
}+ −
+ −
+ −
static const char monthDays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };+ −
+ −
#ifndef QT_NO_TEXTDATE+ −
static const char * const qt_shortMonthNames[] = {+ −
"Jan", "Feb", "Mar", "Apr", "May", "Jun",+ −
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };+ −
#endif+ −
#ifndef QT_NO_DATESTRING+ −
static QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* dd = 0);+ −
#endif+ −
+ −
/*****************************************************************************+ −
QDate member functions+ −
*****************************************************************************/+ −
+ −
/*!+ −
\since 4.5+ −
+ −
\enum QDate::MonthNameType+ −
+ −
This enum describes the types of the string representation used+ −
for the month name.+ −
+ −
\value DateFormat This type of name can be used for date-to-string formatting.+ −
\value StandaloneFormat This type is used when you need to enumerate months or weekdays.+ −
Usually standalone names are represented in singular forms with+ −
capitalized first letter.+ −
*/+ −
+ −
/*!+ −
\class QDate+ −
\reentrant+ −
\brief The QDate class provides date functions.+ −
+ −
+ −
A QDate object contains a calendar date, i.e. year, month, and day+ −
numbers, in the Gregorian calendar. (see \l{QDate G and J} {Use of+ −
Gregorian and Julian Calendars} for dates prior to 15 October+ −
1582). It can read the current date from the system clock. It+ −
provides functions for comparing dates, and for manipulating+ −
dates. For example, it is possible to add and subtract days,+ −
months, and years to dates.+ −
+ −
A QDate object is typically created either by giving the year,+ −
month, and day numbers explicitly. Note that QDate interprets two+ −
digit years as is, i.e., years 0 - 99. A QDate can also be+ −
constructed with the static function currentDate(), which creates+ −
a QDate object containing the system clock's date. An explicit+ −
date can also be set using setDate(). The fromString() function+ −
returns a QDate given a string and a date format which is used to+ −
interpret the date within the string.+ −
+ −
The year(), month(), and day() functions provide access to the+ −
year, month, and day numbers. Also, dayOfWeek() and dayOfYear()+ −
functions are provided. The same information is provided in+ −
textual format by the toString(), shortDayName(), longDayName(),+ −
shortMonthName(), and longMonthName() functions.+ −
+ −
QDate provides a full set of operators to compare two QDate+ −
objects where smaller means earlier, and larger means later.+ −
+ −
You can increment (or decrement) a date by a given number of days+ −
using addDays(). Similarly you can use addMonths() and addYears().+ −
The daysTo() function returns the number of days between two+ −
dates.+ −
+ −
The daysInMonth() and daysInYear() functions return how many days+ −
there are in this date's month and year, respectively. The+ −
isLeapYear() function indicates whether a date is in a leap year.+ −
+ −
\section1+ −
+ −
\target QDate G and J+ −
\section2 Use of Gregorian and Julian Calendars+ −
+ −
QDate uses the Gregorian calendar in all locales, beginning+ −
on the date 15 October 1582. For dates up to and including 4+ −
October 1582, the Julian calendar is used. This means there is a+ −
10-day gap in the internal calendar between the 4th and the 15th+ −
of October 1582. When you use QDateTime for dates in that epoch,+ −
the day after 4 October 1582 is 15 October 1582, and the dates in+ −
the gap are invalid.+ −
+ −
The Julian to Gregorian changeover date used here is the date when+ −
the Gregorian calendar was first introduced, by Pope Gregory+ −
XIII. That change was not universally accepted and some localities+ −
only executed it at a later date (if at all). QDateTime+ −
doesn't take any of these historical facts into account. If an+ −
application must support a locale-specific dating system, it must+ −
do so on its own, remembering to convert the dates using the+ −
Julian day.+ −
+ −
\section2 No Year 0+ −
+ −
There is no year 0. Dates in that year are considered invalid. The+ −
year -1 is the year "1 before Christ" or "1 before current era."+ −
The day before 0001-01-01 is December 31st, 1 BCE.+ −
+ −
\section2 Range of Valid Dates+ −
+ −
The range of valid dates is from January 2nd, 4713 BCE, to+ −
sometime in the year 11 million CE. The Julian Day returned by+ −
QDate::toJulianDay() is a number in the contiguous range from 1 to+ −
\e{overflow}, even across QDateTime's "date holes". It is suitable+ −
for use in applications that must convert a QDateTime to a date in+ −
another calendar system, e.g., Hebrew, Islamic or Chinese.+ −
+ −
\sa QTime, QDateTime, QDateEdit, QDateTimeEdit, QCalendarWidget+ −
*/+ −
+ −
/*!+ −
\fn QDate::QDate()+ −
+ −
Constructs a null date. Null dates are invalid.+ −
+ −
\sa isNull(), isValid()+ −
*/+ −
+ −
/*!+ −
Constructs a date with year \a y, month \a m and day \a d.+ −
+ −
If the specified date is invalid, the date is not set and+ −
isValid() returns false. A date before 2 January 4713 B.C. is+ −
considered invalid.+ −
+ −
\warning Years 0 to 99 are interpreted as is, i.e., years+ −
0-99.+ −
+ −
\sa isValid()+ −
*/+ −
+ −
QDate::QDate(int y, int m, int d)+ −
{+ −
setDate(y, m, d);+ −
}+ −
+ −
+ −
/*!+ −
\fn bool QDate::isNull() const+ −
+ −
Returns true if the date is null; otherwise returns false. A null+ −
date is invalid.+ −
+ −
\note The behavior of this function is equivalent to isValid().+ −
+ −
\sa isValid()+ −
*/+ −
+ −
+ −
/*!+ −
Returns true if this date is valid; otherwise returns false.+ −
+ −
\sa isNull()+ −
*/+ −
+ −
bool QDate::isValid() const+ −
{+ −
return !isNull();+ −
}+ −
+ −
+ −
/*!+ −
Returns the year of this date. Negative numbers indicate years+ −
before 1 A.D. = 1 C.E., such that year -44 is 44 B.C.+ −
+ −
\sa month(), day()+ −
*/+ −
+ −
int QDate::year() const+ −
{+ −
int y;+ −
getDateFromJulianDay(jd, &y, 0, 0);+ −
return y;+ −
}+ −
+ −
/*!+ −
Returns the number corresponding to the month of this date, using+ −
the following convention:+ −
+ −
\list+ −
\i 1 = "January"+ −
\i 2 = "February"+ −
\i 3 = "March"+ −
\i 4 = "April"+ −
\i 5 = "May"+ −
\i 6 = "June"+ −
\i 7 = "July"+ −
\i 8 = "August"+ −
\i 9 = "September"+ −
\i 10 = "October"+ −
\i 11 = "November"+ −
\i 12 = "December"+ −
\endlist+ −
+ −
\sa year(), day()+ −
*/+ −
+ −
int QDate::month() const+ −
{+ −
int m;+ −
getDateFromJulianDay(jd, 0, &m, 0);+ −
return m;+ −
}+ −
+ −
/*!+ −
Returns the day of the month (1 to 31) of this date.+ −
+ −
\sa year(), month(), dayOfWeek()+ −
*/+ −
+ −
int QDate::day() const+ −
{+ −
int d;+ −
getDateFromJulianDay(jd, 0, 0, &d);+ −
return d;+ −
}+ −
+ −
/*!+ −
Returns the weekday (1 to 7) for this date.+ −
+ −
\sa day(), dayOfYear(), Qt::DayOfWeek+ −
*/+ −
+ −
int QDate::dayOfWeek() const+ −
{+ −
return (jd % 7) + 1;+ −
}+ −
+ −
/*!+ −
Returns the day of the year (1 to 365 or 366 on leap years) for+ −
this date.+ −
+ −
\sa day(), dayOfWeek()+ −
*/+ −
+ −
int QDate::dayOfYear() const+ −
{+ −
return jd - julianDayFromDate(year(), 1, 1) + 1;+ −
}+ −
+ −
/*!+ −
Returns the number of days in the month (28 to 31) for this date.+ −
+ −
\sa day(), daysInYear()+ −
*/+ −
+ −
int QDate::daysInMonth() const+ −
{+ −
int y, m, d;+ −
getDateFromJulianDay(jd, &y, &m, &d);+ −
if (m == 2 && isLeapYear(y))+ −
return 29;+ −
else+ −
return monthDays[m];+ −
}+ −
+ −
/*!+ −
Returns the number of days in the year (365 or 366) for this date.+ −
+ −
\sa day(), daysInMonth()+ −
*/+ −
+ −
int QDate::daysInYear() const+ −
{+ −
int y, m, d;+ −
getDateFromJulianDay(jd, &y, &m, &d);+ −
return isLeapYear(y) ? 366 : 365;+ −
}+ −
+ −
/*!+ −
Returns the week number (1 to 53), and stores the year in+ −
*\a{yearNumber} unless \a yearNumber is null (the default).+ −
+ −
Returns 0 if the date is invalid.+ −
+ −
In accordance with ISO 8601, weeks start on Monday and the first+ −
Thursday of a year is always in week 1 of that year. Most years+ −
have 52 weeks, but some have 53.+ −
+ −
*\a{yearNumber} is not always the same as year(). For example, 1+ −
January 2000 has week number 52 in the year 1999, and 31 December+ −
2002 has week number 1 in the year 2003.+ −
+ −
\legalese+ −
Copyright (c) 1989 The Regents of the University of California.+ −
All rights reserved.+ −
+ −
Redistribution and use in source and binary forms are permitted+ −
provided that the above copyright notice and this paragraph are+ −
duplicated in all such forms and that any documentation,+ −
advertising materials, and other materials related to such+ −
distribution and use acknowledge that the software was developed+ −
by the University of California, Berkeley. The name of the+ −
University may not be used to endorse or promote products derived+ −
from this software without specific prior written permission.+ −
THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR+ −
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED+ −
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.+ −
+ −
\sa isValid()+ −
*/+ −
+ −
int QDate::weekNumber(int *yearNumber) const+ −
{+ −
if (!isValid())+ −
return 0;+ −
+ −
int year = QDate::year();+ −
int yday = dayOfYear() - 1;+ −
int wday = dayOfWeek();+ −
if (wday == 7)+ −
wday = 0;+ −
int w;+ −
+ −
for (;;) {+ −
int len;+ −
int bot;+ −
int top;+ −
+ −
len = isLeapYear(year) ? 366 : 365;+ −
/*+ −
** What yday (-3 ... 3) does+ −
** the ISO year begin on?+ −
*/+ −
bot = ((yday + 11 - wday) % 7) - 3;+ −
/*+ −
** What yday does the NEXT+ −
** ISO year begin on?+ −
*/+ −
top = bot - (len % 7);+ −
if (top < -3)+ −
top += 7;+ −
top += len;+ −
if (yday >= top) {+ −
++year;+ −
w = 1;+ −
break;+ −
}+ −
if (yday >= bot) {+ −
w = 1 + ((yday - bot) / 7);+ −
break;+ −
}+ −
--year;+ −
yday += isLeapYear(year) ? 366 : 365;+ −
}+ −
if (yearNumber != 0)+ −
*yearNumber = year;+ −
return w;+ −
}+ −
+ −
#ifndef QT_NO_TEXTDATE+ −
/*!+ −
\since 4.5+ −
+ −
Returns the short name of the \a month for the representation specified+ −
by \a type.+ −
+ −
The months are enumerated using the following convention:+ −
+ −
\list+ −
\i 1 = "Jan"+ −
\i 2 = "Feb"+ −
\i 3 = "Mar"+ −
\i 4 = "Apr"+ −
\i 5 = "May"+ −
\i 6 = "Jun"+ −
\i 7 = "Jul"+ −
\i 8 = "Aug"+ −
\i 9 = "Sep"+ −
\i 10 = "Oct"+ −
\i 11 = "Nov"+ −
\i 12 = "Dec"+ −
\endlist+ −
+ −
The month names will be localized according to the system's locale+ −
settings.+ −
+ −
\sa toString(), longMonthName(), shortDayName(), longDayName()+ −
*/+ −
+ −
QString QDate::shortMonthName(int month, QDate::MonthNameType type)+ −
{+ −
if (month < 1 || month > 12) {+ −
month = 1;+ −
}+ −
switch (type) {+ −
case QDate::DateFormat:+ −
return QLocale::system().monthName(month, QLocale::ShortFormat);+ −
case QDate::StandaloneFormat:+ −
return QLocale::system().standaloneMonthName(month, QLocale::ShortFormat);+ −
default:+ −
break;+ −
}+ −
return QString();+ −
}+ −
+ −
/*!+ −
Returns the short version of the name of the \a month. The+ −
returned name is in normal type which can be used for date formatting.+ −
+ −
\sa toString(), longMonthName(), shortDayName(), longDayName()+ −
*/+ −
+ −
QString QDate::shortMonthName(int month)+ −
{+ −
return shortMonthName(month, QDate::DateFormat);+ −
}+ −
+ −
/*!+ −
\since 4.5+ −
+ −
Returns the long name of the \a month for the representation specified+ −
by \a type.+ −
+ −
The months are enumerated using the following convention:+ −
+ −
\list+ −
\i 1 = "January"+ −
\i 2 = "February"+ −
\i 3 = "March"+ −
\i 4 = "April"+ −
\i 5 = "May"+ −
\i 6 = "June"+ −
\i 7 = "July"+ −
\i 8 = "August"+ −
\i 9 = "September"+ −
\i 10 = "October"+ −
\i 11 = "November"+ −
\i 12 = "December"+ −
\endlist+ −
+ −
The month names will be localized according to the system's locale+ −
settings.+ −
+ −
\sa toString(), shortMonthName(), shortDayName(), longDayName()+ −
*/+ −
+ −
QString QDate::longMonthName(int month, MonthNameType type)+ −
{+ −
if (month < 1 || month > 12) {+ −
month = 1;+ −
}+ −
switch (type) {+ −
case QDate::DateFormat:+ −
return QLocale::system().monthName(month, QLocale::LongFormat);+ −
case QDate::StandaloneFormat:+ −
return QLocale::system().standaloneMonthName(month, QLocale::LongFormat);+ −
default:+ −
break;+ −
}+ −
return QString();+ −
}+ −
+ −
/*!+ −
Returns the long version of the name of the \a month. The+ −
returned name is in normal type which can be used for date formatting.+ −
+ −
\sa toString(), shortMonthName(), shortDayName(), longDayName()+ −
*/+ −
+ −
QString QDate::longMonthName(int month)+ −
{+ −
if (month < 1 || month > 12) {+ −
month = 1;+ −
}+ −
return QLocale::system().monthName(month, QLocale::LongFormat);+ −
}+ −
+ −
/*!+ −
\since 4.5+ −
+ −
Returns the short name of the \a weekday for the representation specified+ −
by \a type.+ −
+ −
The days are enumerated using the following convention:+ −
+ −
\list+ −
\i 1 = "Mon"+ −
\i 2 = "Tue"+ −
\i 3 = "Wed"+ −
\i 4 = "Thu"+ −
\i 5 = "Fri"+ −
\i 6 = "Sat"+ −
\i 7 = "Sun"+ −
\endlist+ −
+ −
The day names will be localized according to the system's locale+ −
settings.+ −
+ −
\sa toString(), shortMonthName(), longMonthName(), longDayName()+ −
*/+ −
+ −
QString QDate::shortDayName(int weekday, MonthNameType type)+ −
{+ −
if (weekday < 1 || weekday > 7) {+ −
weekday = 1;+ −
}+ −
switch (type) {+ −
case QDate::DateFormat:+ −
return QLocale::system().dayName(weekday, QLocale::ShortFormat);+ −
case QDate::StandaloneFormat:+ −
return QLocale::system().standaloneDayName(weekday, QLocale::ShortFormat);+ −
default:+ −
break;+ −
}+ −
return QString();+ −
}+ −
+ −
/*!+ −
Returns the short version of the name of the \a weekday. The+ −
returned name is in normal type which can be used for date formatting.+ −
+ −
\sa toString(), longDayName(), shortMonthName(), longMonthName()+ −
*/+ −
+ −
QString QDate::shortDayName(int weekday)+ −
{+ −
if (weekday < 1 || weekday > 7) {+ −
weekday = 1;+ −
}+ −
return QLocale::system().dayName(weekday, QLocale::ShortFormat);+ −
}+ −
+ −
/*!+ −
\since 4.5+ −
+ −
Returns the long name of the \a weekday for the representation specified+ −
by \a type.+ −
+ −
The days are enumerated using the following convention:+ −
+ −
\list+ −
\i 1 = "Monday"+ −
\i 2 = "Tuesday"+ −
\i 3 = "Wednesday"+ −
\i 4 = "Thursday"+ −
\i 5 = "Friday"+ −
\i 6 = "Saturday"+ −
\i 7 = "Sunday"+ −
\endlist+ −
+ −
The day names will be localized according to the system's locale+ −
settings.+ −
+ −
\sa toString(), shortDayName(), shortMonthName(), longMonthName()+ −
*/+ −
+ −
QString QDate::longDayName(int weekday, MonthNameType type)+ −
{+ −
if (weekday < 1 || weekday > 7) {+ −
weekday = 1;+ −
}+ −
switch (type) {+ −
case QDate::DateFormat:+ −
return QLocale::system().dayName(weekday, QLocale::LongFormat);+ −
case QDate::StandaloneFormat:+ −
return QLocale::system().standaloneDayName(weekday, QLocale::LongFormat);+ −
default:+ −
break;+ −
}+ −
return QLocale::system().dayName(weekday, QLocale::LongFormat);+ −
}+ −
+ −
/*!+ −
Returns the long version of the name of the \a weekday. The+ −
returned name is in normal type which can be used for date formatting.+ −
+ −
\sa toString(), shortDayName(), shortMonthName(), longMonthName()+ −
*/+ −
+ −
QString QDate::longDayName(int weekday)+ −
{+ −
if (weekday < 1 || weekday > 7) {+ −
weekday = 1;+ −
}+ −
return QLocale::system().dayName(weekday, QLocale::LongFormat);+ −
}+ −
#endif //QT_NO_TEXTDATE+ −
+ −
#ifndef QT_NO_DATESTRING+ −
+ −
/*!+ −
\fn QString QDate::toString(Qt::DateFormat format) const+ −
+ −
\overload+ −
+ −
Returns the date as a string. The \a format parameter determines+ −
the format of the string.+ −
+ −
If the \a format is Qt::TextDate, the string is formatted in+ −
the default way. QDate::shortDayName() and QDate::shortMonthName()+ −
are used to generate the string, so the day and month names will+ −
be localized names. An example of this formatting is+ −
"Sat May 20 1995".+ −
+ −
If the \a format is Qt::ISODate, the string format corresponds+ −
to the ISO 8601 extended specification for representations of+ −
dates and times, taking the form YYYY-MM-DD, where YYYY is the+ −
year, MM is the month of the year (between 01 and 12), and DD is+ −
the day of the month between 01 and 31.+ −
+ −
If the \a format is Qt::SystemLocaleShortDate or+ −
Qt::SystemLocaleLongDate, the string format depends on the locale+ −
settings of the system. Identical to calling+ −
QLocale::system().toString(date, QLocale::ShortFormat) or+ −
QLocale::system().toString(date, QLocale::LongFormat).+ −
+ −
If the \a format is Qt::DefaultLocaleShortDate or+ −
Qt::DefaultLocaleLongDate, the string format depends on the+ −
default application locale. This is the locale set with+ −
QLocale::setDefault(), or the system locale if no default locale+ −
has been set. Identical to calling QLocale().toString(date,+ −
QLocale::ShortFormat) or QLocale().toString(date,+ −
QLocale::LongFormat).+ −
+ −
If the date is invalid, an empty string will be returned.+ −
+ −
\warning The Qt::ISODate format is only valid for years in the+ −
range 0 to 9999. This restriction may apply to locale-aware+ −
formats as well, depending on the locale settings.+ −
+ −
\sa shortDayName(), shortMonthName()+ −
*/+ −
QString QDate::toString(Qt::DateFormat f) const+ −
{+ −
if (!isValid())+ −
return QString();+ −
int y, m, d;+ −
getDateFromJulianDay(jd, &y, &m, &d);+ −
switch (f) {+ −
case Qt::SystemLocaleDate:+ −
case Qt::SystemLocaleShortDate:+ −
case Qt::SystemLocaleLongDate:+ −
return QLocale::system().toString(*this, f == Qt::SystemLocaleLongDate ? QLocale::LongFormat+ −
: QLocale::ShortFormat);+ −
case Qt::LocaleDate:+ −
case Qt::DefaultLocaleShortDate:+ −
case Qt::DefaultLocaleLongDate:+ −
return QLocale().toString(*this, f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat+ −
: QLocale::ShortFormat);+ −
default:+ −
#ifndef QT_NO_TEXTDATE+ −
case Qt::TextDate:+ −
{+ −
return QString::fromLatin1("%0 %1 %2 %3")+ −
.arg(shortDayName(dayOfWeek()))+ −
.arg(shortMonthName(m))+ −
.arg(d)+ −
.arg(y);+ −
}+ −
#endif+ −
case Qt::ISODate:+ −
{+ −
if (year() < 0 || year() > 9999)+ −
return QString();+ −
QString month(QString::number(m).rightJustified(2, QLatin1Char('0')));+ −
QString day(QString::number(d).rightJustified(2, QLatin1Char('0')));+ −
return QString::number(y) + QLatin1Char('-') + month + QLatin1Char('-') + day;+ −
}+ −
}+ −
}+ −
+ −
/*!+ −
Returns the date as a string. The \a format parameter determines+ −
the format of the result string.+ −
+ −
These expressions may be used:+ −
+ −
\table+ −
\header \i Expression \i Output+ −
\row \i d \i the day as number without a leading zero (1 to 31)+ −
\row \i dd \i the day as number with a leading zero (01 to 31)+ −
\row \i ddd+ −
\i the abbreviated localized day name (e.g. 'Mon' to 'Sun').+ −
Uses QDate::shortDayName().+ −
\row \i dddd+ −
\i the long localized day name (e.g. 'Monday' to 'Sunday').+ −
Uses QDate::longDayName().+ −
\row \i M \i the month as number without a leading zero (1 to 12)+ −
\row \i MM \i the month as number with a leading zero (01 to 12)+ −
\row \i MMM+ −
\i the abbreviated localized month name (e.g. 'Jan' to 'Dec').+ −
Uses QDate::shortMonthName().+ −
\row \i MMMM+ −
\i the long localized month name (e.g. 'January' to 'December').+ −
Uses QDate::longMonthName().+ −
\row \i yy \i the year as two digit number (00 to 99)+ −
\row \i yyyy \i the year as four digit number. If the year is negative,+ −
a minus sign is prepended in addition.+ −
\endtable+ −
+ −
All other input characters will be ignored. Any sequence of characters that+ −
are enclosed in singlequotes will be treated as text and not be used as an+ −
expression. Two consecutive singlequotes ("''") are replaced by a singlequote+ −
in the output.+ −
+ −
Example format strings (assuming that the QDate is the 20 July+ −
1969):+ −
+ −
\table+ −
\header \o Format \o Result+ −
\row \o dd.MM.yyyy \o 20.07.1969+ −
\row \o ddd MMMM d yy \o Sun July 20 69+ −
\row \o 'The day is' dddd \o The day is Sunday+ −
\endtable+ −
+ −
If the datetime is invalid, an empty string will be returned.+ −
+ −
\warning The Qt::ISODate format is only valid for years in the+ −
range 0 to 9999. This restriction may apply to locale-aware+ −
formats as well, depending on the locale settings.+ −
+ −
\sa QDateTime::toString() QTime::toString()+ −
+ −
*/+ −
QString QDate::toString(const QString& format) const+ −
{+ −
if (year() > 9999)+ −
return QString();+ −
return fmtDateTime(format, 0, this);+ −
}+ −
#endif //QT_NO_DATESTRING+ −
+ −
/*!+ −
\obsolete+ −
+ −
Sets the date's year \a y, month \a m, and day \a d.+ −
+ −
If \a y is in the range 0 to 99, it is interpreted as 1900 to+ −
1999.+ −
+ −
Use setDate() instead.+ −
*/+ −
+ −
bool QDate::setYMD(int y, int m, int d)+ −
{+ −
if (uint(y) <= 99)+ −
y += 1900;+ −
return setDate(y, m, d);+ −
}+ −
+ −
/*!+ −
\since 4.2+ −
+ −
Sets the date's \a year, \a month, and \a day. Returns true if+ −
the date is valid; otherwise returns false.+ −
+ −
If the specified date is invalid, the QDate object is set to be+ −
invalid. Any date before 2 January 4713 B.C. is considered+ −
invalid.+ −
+ −
\sa isValid()+ −
*/+ −
bool QDate::setDate(int year, int month, int day)+ −
{+ −
if (!isValid(year, month, day)) {+ −
jd = 0;+ −
} else {+ −
jd = julianDayFromDate(year, month, day);+ −
}+ −
return jd != 0;+ −
}+ −
+ −
/*!+ −
\since 4.5+ −
+ −
Extracts the date's year, month, and day, and assigns them to+ −
*\a year, *\a month, and *\a day. The pointers may be null.+ −
+ −
\sa year(), month(), day(), isValid()+ −
*/+ −
void QDate::getDate(int *year, int *month, int *day)+ −
{+ −
getDateFromJulianDay(jd, year, month, day);+ −
}+ −
+ −
/*!+ −
Returns a QDate object containing a date \a ndays later than the+ −
date of this object (or earlier if \a ndays is negative).+ −
+ −
\sa addMonths() addYears() daysTo()+ −
*/+ −
+ −
QDate QDate::addDays(int ndays) const+ −
{+ −
QDate d;+ −
// this is basically "d.jd = jd + ndays" with checks for integer overflow+ −
if (ndays >= 0)+ −
d.jd = (jd + ndays >= jd) ? jd + ndays : 0;+ −
else+ −
d.jd = (jd + ndays < jd) ? jd + ndays : 0;+ −
return d;+ −
}+ −
+ −
/*!+ −
Returns a QDate object containing a date \a nmonths later than the+ −
date of this object (or earlier if \a nmonths is negative).+ −
+ −
\note If the ending day/month combination does not exist in the+ −
resulting month/year, this function will return a date that is the+ −
latest valid date.+ −
+ −
\warning QDate has a date hole around the days introducing the+ −
Gregorian calendar (the days 5 to 14 October 1582, inclusive, do+ −
not exist). If the calculation ends in one of those days, QDate+ −
will return either October 4 or October 15.+ −
+ −
\sa addDays() addYears()+ −
*/+ −
+ −
QDate QDate::addMonths(int nmonths) const+ −
{+ −
if (!isValid())+ −
return QDate();+ −
if (!nmonths)+ −
return *this;+ −
+ −
int old_y, y, m, d;+ −
getDateFromJulianDay(jd, &y, &m, &d);+ −
old_y = y;+ −
+ −
bool increasing = nmonths > 0;+ −
+ −
while (nmonths != 0) {+ −
if (nmonths < 0 && nmonths + 12 <= 0) {+ −
y--;+ −
nmonths+=12;+ −
} else if (nmonths < 0) {+ −
m+= nmonths;+ −
nmonths = 0;+ −
if (m <= 0) {+ −
--y;+ −
m += 12;+ −
}+ −
} else if (nmonths - 12 >= 0) {+ −
y++;+ −
nmonths -= 12;+ −
} else if (m == 12) {+ −
y++;+ −
m = 0;+ −
} else {+ −
m += nmonths;+ −
nmonths = 0;+ −
if (m > 12) {+ −
++y;+ −
m -= 12;+ −
}+ −
}+ −
}+ −
+ −
// was there a sign change?+ −
if ((old_y > 0 && y <= 0) ||+ −
(old_y < 0 && y >= 0))+ −
// yes, adjust the date by +1 or -1 years+ −
y += increasing ? +1 : -1;+ −
+ −
// did we end up in the Gregorian/Julian conversion hole?+ −
if (y == 1582 && m == 10 && d > 4 && d < 15)+ −
d = increasing ? 15 : 4;+ −
+ −
return fixedDate(y, m, d);+ −
}+ −
+ −
/*!+ −
Returns a QDate object containing a date \a nyears later than the+ −
date of this object (or earlier if \a nyears is negative).+ −
+ −
\note If the ending day/month combination does not exist in the+ −
resulting year (i.e., if the date was Feb 29 and the final year is+ −
not a leap year), this function will return a date that is the+ −
latest valid date (that is, Feb 28).+ −
+ −
\sa addDays(), addMonths()+ −
*/+ −
+ −
QDate QDate::addYears(int nyears) const+ −
{+ −
if (!isValid())+ −
return QDate();+ −
+ −
int y, m, d;+ −
getDateFromJulianDay(jd, &y, &m, &d);+ −
+ −
int old_y = y;+ −
y += nyears;+ −
+ −
// was there a sign change?+ −
if ((old_y > 0 && y <= 0) ||+ −
(old_y < 0 && y >= 0))+ −
// yes, adjust the date by +1 or -1 years+ −
y += nyears > 0 ? +1 : -1;+ −
+ −
return fixedDate(y, m, d);+ −
}+ −
+ −
/*!+ −
Returns the number of days from this date to \a d (which is+ −
negative if \a d is earlier than this date).+ −
+ −
Example:+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 0+ −
+ −
\sa addDays()+ −
*/+ −
+ −
int QDate::daysTo(const QDate &d) const+ −
{+ −
return d.jd - jd;+ −
}+ −
+ −
+ −
/*!+ −
\fn bool QDate::operator==(const QDate &d) const+ −
+ −
Returns true if this date is equal to \a d; otherwise returns+ −
false.+ −
+ −
*/+ −
+ −
/*!+ −
\fn bool QDate::operator!=(const QDate &d) const+ −
+ −
Returns true if this date is different from \a d; otherwise+ −
returns false.+ −
*/+ −
+ −
/*!+ −
\fn bool QDate::operator<(const QDate &d) const+ −
+ −
Returns true if this date is earlier than \a d; otherwise returns+ −
false.+ −
*/+ −
+ −
/*!+ −
\fn bool QDate::operator<=(const QDate &d) const+ −
+ −
Returns true if this date is earlier than or equal to \a d;+ −
otherwise returns false.+ −
*/+ −
+ −
/*!+ −
\fn bool QDate::operator>(const QDate &d) const+ −
+ −
Returns true if this date is later than \a d; otherwise returns+ −
false.+ −
*/+ −
+ −
/*!+ −
\fn bool QDate::operator>=(const QDate &d) const+ −
+ −
Returns true if this date is later than or equal to \a d;+ −
otherwise returns false.+ −
*/+ −
+ −
/*!+ −
\fn QDate::currentDate()+ −
Returns the current date, as reported by the system clock.+ −
+ −
\sa QTime::currentTime(), QDateTime::currentDateTime()+ −
*/+ −
+ −
#ifndef QT_NO_DATESTRING+ −
/*!+ −
\fn QDate QDate::fromString(const QString &string, Qt::DateFormat format)+ −
+ −
Returns the QDate represented by the \a string, using the+ −
\a format given, or an invalid date if the string cannot be+ −
parsed.+ −
+ −
Note for Qt::TextDate: It is recommended that you use the+ −
English short month names (e.g. "Jan"). Although localized month+ −
names can also be used, they depend on the user's locale settings.+ −
*/+ −
QDate QDate::fromString(const QString& s, Qt::DateFormat f)+ −
{+ −
if (s.isEmpty())+ −
return QDate();+ −
+ −
switch (f) {+ −
case Qt::ISODate:+ −
{+ −
int year(s.mid(0, 4).toInt());+ −
int month(s.mid(5, 2).toInt());+ −
int day(s.mid(8, 2).toInt());+ −
if (year && month && day)+ −
return QDate(year, month, day);+ −
}+ −
break;+ −
case Qt::SystemLocaleDate:+ −
case Qt::SystemLocaleShortDate:+ −
case Qt::SystemLocaleLongDate:+ −
return fromString(s, QLocale::system().dateFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat+ −
: QLocale::ShortFormat));+ −
case Qt::LocaleDate:+ −
case Qt::DefaultLocaleShortDate:+ −
case Qt::DefaultLocaleLongDate:+ −
return fromString(s, QLocale().dateFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat+ −
: QLocale::ShortFormat));+ −
default:+ −
#ifndef QT_NO_TEXTDATE+ −
case Qt::TextDate: {+ −
QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts);+ −
+ −
if (parts.count() != 4) {+ −
return QDate();+ −
}+ −
+ −
QString monthName = parts.at(1);+ −
int month = -1;+ −
// Assume that English monthnames are the default+ −
for (int i = 0; i < 12; ++i) {+ −
if (monthName == QLatin1String(qt_shortMonthNames[i])) {+ −
month = i + 1;+ −
break;+ −
}+ −
}+ −
// If English names can't be found, search the localized ones+ −
if (month == -1) {+ −
for (int i = 1; i <= 12; ++i) {+ −
if (monthName == QDate::shortMonthName(i)) {+ −
month = i;+ −
break;+ −
}+ −
}+ −
}+ −
if (month < 1 || month > 12) {+ −
return QDate();+ −
}+ −
+ −
bool ok;+ −
int day = parts.at(2).toInt(&ok);+ −
if (!ok) {+ −
return QDate();+ −
}+ −
+ −
int year = parts.at(3).toInt(&ok);+ −
if (!ok) {+ −
return QDate();+ −
}+ −
+ −
return QDate(year, month, day);+ −
}+ −
#else+ −
break;+ −
#endif+ −
}+ −
return QDate();+ −
}+ −
+ −
/*!+ −
\fn QDate::fromString(const QString &string, const QString &format)+ −
+ −
Returns the QDate represented by the \a string, using the \a+ −
format given, or an invalid date if the string cannot be parsed.+ −
+ −
These expressions may be used for the format:+ −
+ −
\table+ −
\header \i Expression \i Output+ −
\row \i d \i The day as a number without a leading zero (1 to 31)+ −
\row \i dd \i The day as a number with a leading zero (01 to 31)+ −
\row \i ddd+ −
\i The abbreviated localized day name (e.g. 'Mon' to 'Sun').+ −
Uses QDate::shortDayName().+ −
\row \i dddd+ −
\i The long localized day name (e.g. 'Monday' to 'Sunday').+ −
Uses QDate::longDayName().+ −
\row \i M \i The month as a number without a leading zero (1 to 12)+ −
\row \i MM \i The month as a number with a leading zero (01 to 12)+ −
\row \i MMM+ −
\i The abbreviated localized month name (e.g. 'Jan' to 'Dec').+ −
Uses QDate::shortMonthName().+ −
\row \i MMMM+ −
\i The long localized month name (e.g. 'January' to 'December').+ −
Uses QDate::longMonthName().+ −
\row \i yy \i The year as two digit number (00 to 99)+ −
\row \i yyyy \i The year as four digit number. If the year is negative,+ −
a minus sign is prepended in addition.+ −
\endtable+ −
+ −
All other input characters will be treated as text. Any sequence+ −
of characters that are enclosed in single quotes will also be+ −
treated as text and will not be used as an expression. For example:+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 1+ −
+ −
If the format is not satisfied, an invalid QDate is returned. The+ −
expressions that don't expect leading zeroes (d, M) will be+ −
greedy. This means that they will use two digits even if this+ −
will put them outside the accepted range of values and leaves too+ −
few digits for other sections. For example, the following format+ −
string could have meant January 30 but the M will grab two+ −
digits, resulting in an invalid date:+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 2+ −
+ −
For any field that is not represented in the format the following+ −
defaults are used:+ −
+ −
\table+ −
\header \i Field \i Default value+ −
\row \i Year \i 1900+ −
\row \i Month \i 1+ −
\row \i Day \i 1+ −
\endtable+ −
+ −
The following examples demonstrate the default values:+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 3+ −
+ −
\sa QDateTime::fromString(), QTime::fromString(), QDate::toString(),+ −
QDateTime::toString(), QTime::toString()+ −
*/+ −
+ −
QDate QDate::fromString(const QString &string, const QString &format)+ −
{+ −
QDate date;+ −
#ifndef QT_BOOTSTRAPPED+ −
QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);+ −
if (dt.parseFormat(format))+ −
dt.fromString(string, &date, 0);+ −
#else+ −
Q_UNUSED(string);+ −
Q_UNUSED(format);+ −
#endif+ −
return date;+ −
}+ −
#endif // QT_NO_DATESTRING+ −
+ −
/*!+ −
\overload+ −
+ −
Returns true if the specified date (\a year, \a month, and \a+ −
day) is valid; otherwise returns false.+ −
+ −
Example:+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 4+ −
+ −
\sa isNull(), setDate()+ −
*/+ −
+ −
bool QDate::isValid(int year, int month, int day)+ −
{+ −
if (year < FIRST_YEAR+ −
|| (year == FIRST_YEAR &&+ −
(month < FIRST_MONTH+ −
|| (month == FIRST_MONTH && day < FIRST_DAY)))+ −
|| year == 0) // there is no year 0 in the Julian calendar+ −
return false;+ −
+ −
// passage from Julian to Gregorian calendar+ −
if (year == 1582 && month == 10 && day > 4 && day < 15)+ −
return 0;+ −
+ −
return (day > 0 && month > 0 && month <= 12) &&+ −
(day <= monthDays[month] || (day == 29 && month == 2 && isLeapYear(year)));+ −
}+ −
+ −
/*!+ −
\fn bool QDate::isLeapYear(int year)+ −
+ −
Returns true if the specified \a year is a leap year; otherwise+ −
returns false.+ −
*/+ −
+ −
bool QDate::isLeapYear(int y)+ −
{+ −
if (y < 1582) {+ −
if ( y < 1) { // No year 0 in Julian calendar, so -1, -5, -9 etc are leap years+ −
++y;+ −
}+ −
return y % 4 == 0;+ −
} else {+ −
return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;+ −
}+ −
}+ −
+ −
/*!+ −
\internal+ −
+ −
This function has a confusing name and shouldn't be part of the+ −
API anyway, since we have toJulian() and fromJulian().+ −
### Qt 5: remove it+ −
*/+ −
uint QDate::gregorianToJulian(int y, int m, int d)+ −
{+ −
return julianDayFromDate(y, m, d);+ −
}+ −
+ −
/*!+ −
\internal+ −
+ −
This function has a confusing name and shouldn't be part of the+ −
API anyway, since we have toJulian() and fromJulian().+ −
### Qt 5: remove it+ −
*/+ −
void QDate::julianToGregorian(uint jd, int &y, int &m, int &d)+ −
{+ −
getDateFromJulianDay(jd, &y, &m, &d);+ −
}+ −
+ −
/*! \fn static QDate QDate::fromJulianDay(int jd)+ −
+ −
Converts the Julian day \a jd to a QDate.+ −
+ −
\sa toJulianDay()+ −
*/+ −
+ −
/*! \fn int QDate::toJulianDay() const+ −
+ −
Converts the date to a Julian day.+ −
+ −
\sa fromJulianDay()+ −
*/+ −
+ −
/*****************************************************************************+ −
QTime member functions+ −
*****************************************************************************/+ −
+ −
/*!+ −
\class QTime+ −
\reentrant+ −
+ −
\brief The QTime class provides clock time functions.+ −
+ −
+ −
A QTime object contains a clock time, i.e. the number of hours,+ −
minutes, seconds, and milliseconds since midnight. It can read the+ −
current time from the system clock and measure a span of elapsed+ −
time. It provides functions for comparing times and for+ −
manipulating a time by adding a number of milliseconds.+ −
+ −
QTime uses the 24-hour clock format; it has no concept of AM/PM.+ −
Unlike QDateTime, QTime knows nothing about time zones or+ −
daylight savings time (DST).+ −
+ −
A QTime object is typically created either by giving the number+ −
of hours, minutes, seconds, and milliseconds explicitly, or by+ −
using the static function currentTime(), which creates a QTime+ −
object that contains the system's local time. Note that the+ −
accuracy depends on the accuracy of the underlying operating+ −
system; not all systems provide 1-millisecond accuracy.+ −
+ −
The hour(), minute(), second(), and msec() functions provide+ −
access to the number of hours, minutes, seconds, and milliseconds+ −
of the time. The same information is provided in textual format by+ −
the toString() function.+ −
+ −
QTime provides a full set of operators to compare two QTime+ −
objects. One time is considered smaller than another if it is+ −
earlier than the other.+ −
+ −
The time a given number of seconds or milliseconds later than a+ −
given time can be found using the addSecs() or addMSecs()+ −
functions. Correspondingly, the number of seconds or milliseconds+ −
between two times can be found using secsTo() or msecsTo().+ −
+ −
QTime can be used to measure a span of elapsed time using the+ −
start(), restart(), and elapsed() functions.+ −
+ −
\sa QDate, QDateTime+ −
*/+ −
+ −
/*!+ −
\fn QTime::QTime()+ −
+ −
Constructs a null time object. A null time can be a QTime(0, 0, 0, 0)+ −
(i.e., midnight) object, except that isNull() returns true and isValid()+ −
returns false.+ −
+ −
\sa isNull(), isValid()+ −
*/+ −
+ −
/*!+ −
Constructs a time with hour \a h, minute \a m, seconds \a s and+ −
milliseconds \a ms.+ −
+ −
\a h must be in the range 0 to 23, \a m and \a s must be in the+ −
range 0 to 59, and \a ms must be in the range 0 to 999.+ −
+ −
\sa isValid()+ −
*/+ −
+ −
QTime::QTime(int h, int m, int s, int ms)+ −
{+ −
setHMS(h, m, s, ms);+ −
}+ −
+ −
+ −
/*!+ −
\fn bool QTime::isNull() const+ −
+ −
Returns true if the time is null (i.e., the QTime object was+ −
constructed using the default constructor); otherwise returns+ −
false. A null time is also an invalid time.+ −
+ −
\sa isValid()+ −
*/+ −
+ −
/*!+ −
Returns true if the time is valid; otherwise returns false. For example,+ −
the time 23:30:55.746 is valid, but 24:12:30 is invalid.+ −
+ −
\sa isNull()+ −
*/+ −
+ −
bool QTime::isValid() const+ −
{+ −
return mds > NullTime && mds < MSECS_PER_DAY;+ −
}+ −
+ −
+ −
/*!+ −
Returns the hour part (0 to 23) of the time.+ −
+ −
\sa minute(), second(), msec()+ −
*/+ −
+ −
int QTime::hour() const+ −
{+ −
return ds() / MSECS_PER_HOUR;+ −
}+ −
+ −
/*!+ −
Returns the minute part (0 to 59) of the time.+ −
+ −
\sa hour(), second(), msec()+ −
*/+ −
+ −
int QTime::minute() const+ −
{+ −
return (ds() % MSECS_PER_HOUR) / MSECS_PER_MIN;+ −
}+ −
+ −
/*!+ −
Returns the second part (0 to 59) of the time.+ −
+ −
\sa hour(), minute(), msec()+ −
*/+ −
+ −
int QTime::second() const+ −
{+ −
return (ds() / 1000)%SECS_PER_MIN;+ −
}+ −
+ −
/*!+ −
Returns the millisecond part (0 to 999) of the time.+ −
+ −
\sa hour(), minute(), second()+ −
*/+ −
+ −
int QTime::msec() const+ −
{+ −
return ds() % 1000;+ −
}+ −
+ −
#ifndef QT_NO_DATESTRING+ −
/*!+ −
\overload+ −
+ −
Returns the time as a string. Milliseconds are not included. The+ −
\a format parameter determines the format of the string.+ −
+ −
If \a format is Qt::TextDate, the string format is HH:MM:SS; e.g. 1+ −
second before midnight would be "23:59:59".+ −
+ −
If \a format is Qt::ISODate, the string format corresponds to the+ −
ISO 8601 extended specification for representations of dates,+ −
which is also HH:MM:SS. (However, contrary to ISO 8601, dates+ −
before 15 October 1582 are handled as Julian dates, not Gregorian+ −
dates. See \l{QDate G and J} {Use of Gregorian and Julian+ −
Calendars}. This might change in a future version of Qt.)+ −
+ −
If the \a format is Qt::SystemLocaleShortDate or+ −
Qt::SystemLocaleLongDate, the string format depends on the locale+ −
settings of the system. Identical to calling+ −
QLocale::system().toString(time, QLocale::ShortFormat) or+ −
QLocale::system().toString(time, QLocale::LongFormat).+ −
+ −
If the \a format is Qt::DefaultLocaleShortDate or+ −
Qt::DefaultLocaleLongDate, the string format depends on the+ −
default application locale. This is the locale set with+ −
QLocale::setDefault(), or the system locale if no default locale+ −
has been set. Identical to calling QLocale().toString(time,+ −
QLocale::ShortFormat) or QLocale().toString(time,+ −
QLocale::LongFormat).+ −
+ −
If the time is invalid, an empty string will be returned.+ −
*/+ −
+ −
QString QTime::toString(Qt::DateFormat format) const+ −
{+ −
if (!isValid())+ −
return QString();+ −
+ −
switch (format) {+ −
case Qt::SystemLocaleDate:+ −
case Qt::SystemLocaleShortDate:+ −
case Qt::SystemLocaleLongDate:+ −
return QLocale::system().toString(*this, format == Qt::SystemLocaleLongDate ? QLocale::LongFormat+ −
: QLocale::ShortFormat);+ −
case Qt::LocaleDate:+ −
case Qt::DefaultLocaleShortDate:+ −
case Qt::DefaultLocaleLongDate:+ −
return QLocale().toString(*this, format == Qt::DefaultLocaleLongDate ? QLocale::LongFormat+ −
: QLocale::ShortFormat);+ −
+ −
default:+ −
case Qt::ISODate:+ −
case Qt::TextDate:+ −
return QString::fromLatin1("%1:%2:%3")+ −
.arg(hour(), 2, 10, QLatin1Char('0'))+ −
.arg(minute(), 2, 10, QLatin1Char('0'))+ −
.arg(second(), 2, 10, QLatin1Char('0'));+ −
}+ −
}+ −
+ −
/*!+ −
Returns the time as a string. The \a format parameter determines+ −
the format of the result string.+ −
+ −
These expressions may be used:+ −
+ −
\table+ −
\header \i Expression \i Output+ −
\row \i h+ −
\i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)+ −
\row \i hh+ −
\i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)+ −
\row \i H+ −
\i the hour without a leading zero (0 to 23, even with AM/PM display)+ −
\row \i HH+ −
\i the hour with a leading zero (00 to 23, even with AM/PM display)+ −
\row \i m \i the minute without a leading zero (0 to 59)+ −
\row \i mm \i the minute with a leading zero (00 to 59)+ −
\row \i s \i the second without a leading zero (0 to 59)+ −
\row \i ss \i the second with a leading zero (00 to 59)+ −
\row \i z \i the milliseconds without leading zeroes (0 to 999)+ −
\row \i zzz \i the milliseconds with leading zeroes (000 to 999)+ −
\row \i AP or A+ −
\i use AM/PM display. \e AP will be replaced by either "AM" or "PM".+ −
\row \i ap or a+ −
\i use am/pm display. \e ap will be replaced by either "am" or "pm".+ −
\row \i t \i the timezone (for example "CEST")+ −
\endtable+ −
+ −
All other input characters will be ignored. Any sequence of characters that+ −
are enclosed in singlequotes will be treated as text and not be used as an+ −
expression. Two consecutive singlequotes ("''") are replaced by a singlequote+ −
in the output.+ −
+ −
Example format strings (assuming that the QTime is 14:13:09.042)+ −
+ −
\table+ −
\header \i Format \i Result+ −
\row \i hh:mm:ss.zzz \i 14:13:09.042+ −
\row \i h:m:s ap \i 2:13:9 pm+ −
\row \i H:m:s a \i 14:13:9 pm+ −
\endtable+ −
+ −
If the datetime is invalid, an empty string will be returned.+ −
+ −
\sa QDate::toString() QDateTime::toString()+ −
*/+ −
QString QTime::toString(const QString& format) const+ −
{+ −
return fmtDateTime(format, this, 0);+ −
}+ −
#endif //QT_NO_DATESTRING+ −
/*!+ −
Sets the time to hour \a h, minute \a m, seconds \a s and+ −
milliseconds \a ms.+ −
+ −
\a h must be in the range 0 to 23, \a m and \a s must be in the+ −
range 0 to 59, and \a ms must be in the range 0 to 999.+ −
Returns true if the set time is valid; otherwise returns false.+ −
+ −
\sa isValid()+ −
*/+ −
+ −
bool QTime::setHMS(int h, int m, int s, int ms)+ −
{+ −
#if defined(Q_OS_WINCE)+ −
startTick = NullTime;+ −
#endif+ −
if (!isValid(h,m,s,ms)) {+ −
mds = NullTime; // make this invalid+ −
return false;+ −
}+ −
mds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;+ −
return true;+ −
}+ −
+ −
/*!+ −
Returns a QTime object containing a time \a s seconds later+ −
than the time of this object (or earlier if \a s is negative).+ −
+ −
Note that the time will wrap if it passes midnight.+ −
+ −
Example:+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 5+ −
+ −
\sa addMSecs(), secsTo(), QDateTime::addSecs()+ −
*/+ −
+ −
QTime QTime::addSecs(int s) const+ −
{+ −
return addMSecs(s * 1000);+ −
}+ −
+ −
/*!+ −
Returns the number of seconds from this time to \a t.+ −
If \a t is earlier than this time, the number of seconds returned+ −
is negative.+ −
+ −
Because QTime measures time within a day and there are 86400+ −
seconds in a day, the result is always between -86400 and 86400.+ −
+ −
secsTo() does not take into account any milliseconds.+ −
+ −
\sa addSecs(), QDateTime::secsTo()+ −
*/+ −
+ −
int QTime::secsTo(const QTime &t) const+ −
{+ −
return (t.ds() - ds()) / 1000;+ −
}+ −
+ −
/*!+ −
Returns a QTime object containing a time \a ms milliseconds later+ −
than the time of this object (or earlier if \a ms is negative).+ −
+ −
Note that the time will wrap if it passes midnight. See addSecs()+ −
for an example.+ −
+ −
\sa addSecs(), msecsTo(), QDateTime::addMSecs()+ −
*/+ −
+ −
QTime QTime::addMSecs(int ms) const+ −
{+ −
QTime t;+ −
if (ms < 0) {+ −
// % not well-defined for -ve, but / is.+ −
int negdays = (MSECS_PER_DAY - ms) / MSECS_PER_DAY;+ −
t.mds = (ds() + ms + negdays * MSECS_PER_DAY) % MSECS_PER_DAY;+ −
} else {+ −
t.mds = (ds() + ms) % MSECS_PER_DAY;+ −
}+ −
#if defined(Q_OS_WINCE)+ −
if (startTick > NullTime)+ −
t.startTick = (startTick + ms) % MSECS_PER_DAY;+ −
#endif+ −
return t;+ −
}+ −
+ −
/*!+ −
Returns the number of milliseconds from this time to \a t.+ −
If \a t is earlier than this time, the number of milliseconds returned+ −
is negative.+ −
+ −
Because QTime measures time within a day and there are 86400+ −
seconds in a day, the result is always between -86400000 and+ −
86400000 ms.+ −
+ −
\sa secsTo(), addMSecs(), QDateTime::msecsTo()+ −
*/+ −
+ −
int QTime::msecsTo(const QTime &t) const+ −
{+ −
#if defined(Q_OS_WINCE)+ −
// GetLocalTime() for Windows CE has no milliseconds resolution+ −
if (t.startTick > NullTime && startTick > NullTime)+ −
return t.startTick - startTick;+ −
else+ −
#endif+ −
return t.ds() - ds();+ −
}+ −
+ −
+ −
/*!+ −
\fn bool QTime::operator==(const QTime &t) const+ −
+ −
Returns true if this time is equal to \a t; otherwise returns false.+ −
*/+ −
+ −
/*!+ −
\fn bool QTime::operator!=(const QTime &t) const+ −
+ −
Returns true if this time is different from \a t; otherwise returns false.+ −
*/+ −
+ −
/*!+ −
\fn bool QTime::operator<(const QTime &t) const+ −
+ −
Returns true if this time is earlier than \a t; otherwise returns false.+ −
*/+ −
+ −
/*!+ −
\fn bool QTime::operator<=(const QTime &t) const+ −
+ −
Returns true if this time is earlier than or equal to \a t;+ −
otherwise returns false.+ −
*/+ −
+ −
/*!+ −
\fn bool QTime::operator>(const QTime &t) const+ −
+ −
Returns true if this time is later than \a t; otherwise returns false.+ −
*/+ −
+ −
/*!+ −
\fn bool QTime::operator>=(const QTime &t) const+ −
+ −
Returns true if this time is later than or equal to \a t;+ −
otherwise returns false.+ −
*/+ −
+ −
/*!+ −
\fn QTime::currentTime()+ −
+ −
Returns the current time as reported by the system clock.+ −
+ −
Note that the accuracy depends on the accuracy of the underlying+ −
operating system; not all systems provide 1-millisecond accuracy.+ −
*/+ −
+ −
#ifndef QT_NO_DATESTRING+ −
/*!+ −
\fn QTime QTime::fromString(const QString &string, Qt::DateFormat format)+ −
+ −
Returns the time represented in the \a string as a QTime using the+ −
\a format given, or an invalid time if this is not possible.+ −
+ −
Note that fromString() uses a "C" locale encoded string to convert+ −
milliseconds to a float value. If the default locale is not "C",+ −
this may result in two conversion attempts (if the conversion+ −
fails for the default locale). This should be considered an+ −
implementation detail.+ −
*/+ −
QTime QTime::fromString(const QString& s, Qt::DateFormat f)+ −
{+ −
if (s.isEmpty()) {+ −
QTime t;+ −
t.mds = NullTime;+ −
return t;+ −
}+ −
+ −
switch (f) {+ −
case Qt::SystemLocaleDate:+ −
case Qt::SystemLocaleShortDate:+ −
case Qt::SystemLocaleLongDate:+ −
return fromString(s, QLocale::system().timeFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat+ −
: QLocale::ShortFormat));+ −
case Qt::LocaleDate:+ −
case Qt::DefaultLocaleShortDate:+ −
case Qt::DefaultLocaleLongDate:+ −
return fromString(s, QLocale().timeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat+ −
: QLocale::ShortFormat));+ −
default:+ −
{+ −
bool ok = true;+ −
const int hour(s.mid(0, 2).toInt(&ok));+ −
if (!ok)+ −
return QTime();+ −
const int minute(s.mid(3, 2).toInt(&ok));+ −
if (!ok)+ −
return QTime();+ −
const int second(s.mid(6, 2).toInt(&ok));+ −
if (!ok)+ −
return QTime();+ −
const QString msec_s(QLatin1String("0.") + s.mid(9, 4));+ −
const float msec(msec_s.toFloat(&ok));+ −
if (!ok)+ −
return QTime(hour, minute, second, 0);+ −
return QTime(hour, minute, second, qMin(qRound(msec * 1000.0), 999));+ −
}+ −
}+ −
}+ −
+ −
/*!+ −
\fn QTime::fromString(const QString &string, const QString &format)+ −
+ −
Returns the QTime represented by the \a string, using the \a+ −
format given, or an invalid time if the string cannot be parsed.+ −
+ −
These expressions may be used for the format:+ −
+ −
\table+ −
\header \i Expression \i Output+ −
\row \i h+ −
\i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)+ −
\row \i hh+ −
\i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)+ −
\row \i m \i the minute without a leading zero (0 to 59)+ −
\row \i mm \i the minute with a leading zero (00 to 59)+ −
\row \i s \i the second without a leading zero (0 to 59)+ −
\row \i ss \i the second with a leading zero (00 to 59)+ −
\row \i z \i the milliseconds without leading zeroes (0 to 999)+ −
\row \i zzz \i the milliseconds with leading zeroes (000 to 999)+ −
\row \i AP+ −
\i interpret as an AM/PM time. \e AP must be either "AM" or "PM".+ −
\row \i ap+ −
\i Interpret as an AM/PM time. \e ap must be either "am" or "pm".+ −
\endtable+ −
+ −
All other input characters will be treated as text. Any sequence+ −
of characters that are enclosed in single quotes will also be+ −
treated as text and not be used as an expression.+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 6+ −
+ −
If the format is not satisfied an invalid QTime is returned.+ −
Expressions that do not expect leading zeroes to be given (h, m, s+ −
and z) are greedy. This means that they will use two digits even if+ −
this puts them outside the range of accepted values and leaves too+ −
few digits for other sections. For example, the following string+ −
could have meant 00:07:10, but the m will grab two digits, resulting+ −
in an invalid time:+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 7+ −
+ −
Any field that is not represented in the format will be set to zero.+ −
For example:+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 8+ −
+ −
\sa QDateTime::fromString() QDate::fromString() QDate::toString()+ −
QDateTime::toString() QTime::toString()+ −
*/+ −
+ −
QTime QTime::fromString(const QString &string, const QString &format)+ −
{+ −
QTime time;+ −
#ifndef QT_BOOTSTRAPPED+ −
QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);+ −
if (dt.parseFormat(format))+ −
dt.fromString(string, 0, &time);+ −
#else+ −
Q_UNUSED(string);+ −
Q_UNUSED(format);+ −
#endif+ −
return time;+ −
}+ −
+ −
#endif // QT_NO_DATESTRING+ −
+ −
+ −
/*!+ −
\overload+ −
+ −
Returns true if the specified time is valid; otherwise returns+ −
false.+ −
+ −
The time is valid if \a h is in the range 0 to 23, \a m and+ −
\a s are in the range 0 to 59, and \a ms is in the range 0 to 999.+ −
+ −
Example:+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 9+ −
*/+ −
+ −
bool QTime::isValid(int h, int m, int s, int ms)+ −
{+ −
return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;+ −
}+ −
+ −
+ −
/*!+ −
Sets this time to the current time. This is practical for timing:+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 10+ −
+ −
\sa restart(), elapsed(), currentTime()+ −
*/+ −
+ −
void QTime::start()+ −
{+ −
*this = currentTime();+ −
}+ −
+ −
/*!+ −
Sets this time to the current time and returns the number of+ −
milliseconds that have elapsed since the last time start() or+ −
restart() was called.+ −
+ −
This function is guaranteed to be atomic and is thus very handy+ −
for repeated measurements. Call start() to start the first+ −
measurement, and restart() for each later measurement.+ −
+ −
Note that the counter wraps to zero 24 hours after the last call+ −
to start() or restart().+ −
+ −
\warning If the system's clock setting has been changed since the+ −
last time start() or restart() was called, the result is+ −
undefined. This can happen when daylight savings time is turned on+ −
or off.+ −
+ −
\sa start(), elapsed(), currentTime()+ −
*/+ −
+ −
int QTime::restart()+ −
{+ −
QTime t = currentTime();+ −
int n = msecsTo(t);+ −
if (n < 0) // passed midnight+ −
n += 86400*1000;+ −
*this = t;+ −
return n;+ −
}+ −
+ −
/*!+ −
Returns the number of milliseconds that have elapsed since the+ −
last time start() or restart() was called.+ −
+ −
Note that the counter wraps to zero 24 hours after the last call+ −
to start() or restart.+ −
+ −
Note that the accuracy depends on the accuracy of the underlying+ −
operating system; not all systems provide 1-millisecond accuracy.+ −
+ −
\warning If the system's clock setting has been changed since the+ −
last time start() or restart() was called, the result is+ −
undefined. This can happen when daylight savings time is turned on+ −
or off.+ −
+ −
\sa start(), restart()+ −
*/+ −
+ −
int QTime::elapsed() const+ −
{+ −
int n = msecsTo(currentTime());+ −
if (n < 0) // passed midnight+ −
n += 86400 * 1000;+ −
return n;+ −
}+ −
+ −
+ −
/*****************************************************************************+ −
QDateTime member functions+ −
*****************************************************************************/+ −
+ −
/*!+ −
\class QDateTime+ −
\reentrant+ −
\brief The QDateTime class provides date and time functions.+ −
+ −
+ −
A QDateTime object contains a calendar date and a clock time (a+ −
"datetime"). It is a combination of the QDate and QTime classes.+ −
It can read the current datetime from the system clock. It+ −
provides functions for comparing datetimes and for manipulating a+ −
datetime by adding a number of seconds, days, months, or years.+ −
+ −
A QDateTime object is typically created either by giving a date+ −
and time explicitly in the constructor, or by using the static+ −
function currentDateTime() that returns a QDateTime object set+ −
to the system clock's time. The date and time can be changed with+ −
setDate() and setTime(). A datetime can also be set using the+ −
setTime_t() function that takes a POSIX-standard "number of+ −
seconds since 00:00:00 on January 1, 1970" value. The fromString()+ −
function returns a QDateTime, given a string and a date format+ −
used to interpret the date within the string.+ −
+ −
The date() and time() functions provide access to the date and+ −
time parts of the datetime. The same information is provided in+ −
textual format by the toString() function.+ −
+ −
QDateTime provides a full set of operators to compare two+ −
QDateTime objects where smaller means earlier and larger means+ −
later.+ −
+ −
You can increment (or decrement) a datetime by a given number of+ −
milliseconds using addMSecs(), seconds using addSecs(), or days+ −
using addDays(). Similarly you can use addMonths() and addYears().+ −
The daysTo() function returns the number of days between two datetimes,+ −
secsTo() returns the number of seconds between two datetimes, and+ −
msecsTo() returns the number of milliseconds between two datetimes.+ −
+ −
QDateTime can store datetimes as \l{Qt::LocalTime}{local time} or+ −
as \l{Qt::UTC}{UTC}. QDateTime::currentDateTime() returns a+ −
QDateTime expressed as local time; use toUTC() to convert it to+ −
UTC. You can also use timeSpec() to find out if a QDateTime+ −
object stores a UTC time or a local time. Operations such as+ −
addSecs() and secsTo() are aware of daylight saving time (DST).+ −
+ −
\note QDateTime does not account for leap seconds.+ −
+ −
\section1+ −
+ −
\target QDateTime G and J+ −
\section2 Use of Gregorian and Julian Calendars+ −
+ −
QDate uses the Gregorian calendar in all locales, beginning+ −
on the date 15 October 1582. For dates up to and including 4+ −
October 1582, the Julian calendar is used. This means there is a+ −
10-day gap in the internal calendar between the 4th and the 15th+ −
of October 1582. When you use QDateTime for dates in that epoch,+ −
the day after 4 October 1582 is 15 October 1582, and the dates in+ −
the gap are invalid.+ −
+ −
The Julian to Gregorian changeover date used here is the date when+ −
the Gregorian calendar was first introduced, by Pope Gregory+ −
XIII. That change was not universally accepted and some localities+ −
only executed it at a later date (if at all). QDateTime+ −
doesn't take any of these historical facts into account. If an+ −
application must support a locale-specific dating system, it must+ −
do so on its own, remembering to convert the dates using the+ −
Julian day.+ −
+ −
\section2 No Year 0+ −
+ −
There is no year 0. Dates in that year are considered invalid. The+ −
year -1 is the year "1 before Christ" or "1 before current era."+ −
The day before 0001-01-01 is December 31st, 1 BCE.+ −
+ −
\section2 Range of Valid Dates+ −
+ −
The range of valid dates is from January 2nd, 4713 BCE, to+ −
sometime in the year 11 million CE. The Julian Day returned by+ −
QDate::toJulianDay() is a number in the contiguous range from 1 to+ −
\e{overflow}, even across QDateTime's "date holes". It is suitable+ −
for use in applications that must convert a QDateTime to a date in+ −
another calendar system, e.g., Hebrew, Islamic or Chinese.+ −
+ −
The Gregorian calendar was introduced in different places around+ −
the world on different dates. QDateTime uses QDate to store the+ −
date, so it uses the Gregorian calendar for all locales, beginning+ −
on the date 15 October 1582. For dates up to and including 4+ −
October 1582, QDateTime uses the Julian calendar. This means+ −
there is a 10-day gap in the QDateTime calendar between the 4th+ −
and the 15th of October 1582. When you use QDateTime for dates in+ −
that epoch, the day after 4 October 1582 is 15 October 1582, and+ −
the dates in the gap are invalid.+ −
+ −
\section2+ −
Use of System Timezone+ −
+ −
QDateTime uses the system's time zone information to determine the+ −
offset of local time from UTC. If the system is not configured+ −
correctly or not up-to-date, QDateTime will give wrong results as+ −
well.+ −
+ −
\section2 Daylight Savings Time (DST)+ −
+ −
QDateTime takes into account the system's time zone information+ −
when dealing with DST. On modern Unix systems, this means it+ −
applies the correct historical DST data whenever possible. On+ −
Windows and Windows CE, where the system doesn't support+ −
historical DST data, historical accuracy is not maintained with+ −
respect to DST.+ −
+ −
The range of valid dates taking DST into account is 1970-01-01 to+ −
the present, and rules are in place for handling DST correctly+ −
until 2037-12-31, but these could change. For dates falling+ −
outside that range, QDateTime makes a \e{best guess} using the+ −
rules for year 1970 or 2037, but we can't guarantee accuracy. This+ −
means QDateTime doesn't take into account changes in a locale's+ −
time zone before 1970, even if the system's time zone database+ −
supports that information.+ −
+ −
\sa QDate QTime QDateTimeEdit+ −
*/+ −
+ −
/*!+ −
Constructs a null datetime (i.e. null date and null time). A null+ −
datetime is invalid, since the date is invalid.+ −
+ −
\sa isValid()+ −
*/+ −
QDateTime::QDateTime()+ −
: d(new QDateTimePrivate)+ −
{+ −
}+ −
+ −
+ −
/*!+ −
Constructs a datetime with the given \a date, a valid+ −
time(00:00:00.000), and sets the timeSpec() to Qt::LocalTime.+ −
*/+ −
+ −
QDateTime::QDateTime(const QDate &date)+ −
: d(new QDateTimePrivate)+ −
{+ −
d->date = date;+ −
d->time = QTime(0, 0, 0);+ −
}+ −
+ −
/*!+ −
Constructs a datetime with the given \a date and \a time, using+ −
the time specification defined by \a spec.+ −
+ −
If \a date is valid and \a time is not, the time will be set to midnight.+ −
*/+ −
+ −
QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec)+ −
: d(new QDateTimePrivate)+ −
{+ −
d->date = date;+ −
d->time = date.isValid() && !time.isValid() ? QTime(0, 0, 0) : time;+ −
d->spec = (spec == Qt::UTC) ? QDateTimePrivate::UTC : QDateTimePrivate::LocalUnknown;+ −
}+ −
+ −
/*!+ −
Constructs a copy of the \a other datetime.+ −
*/+ −
+ −
QDateTime::QDateTime(const QDateTime &other)+ −
: d(other.d)+ −
{+ −
}+ −
+ −
/*!+ −
Destroys the datetime.+ −
*/+ −
QDateTime::~QDateTime()+ −
{+ −
}+ −
+ −
/*!+ −
Makes a copy of the \a other datetime and returns a reference to the+ −
copy.+ −
*/+ −
+ −
QDateTime &QDateTime::operator=(const QDateTime &other)+ −
{+ −
d = other.d;+ −
return *this;+ −
}+ −
+ −
/*!+ −
Returns true if both the date and the time are null; otherwise+ −
returns false. A null datetime is invalid.+ −
+ −
\sa QDate::isNull(), QTime::isNull(), isValid()+ −
*/+ −
+ −
bool QDateTime::isNull() const+ −
{+ −
return d->date.isNull() && d->time.isNull();+ −
}+ −
+ −
/*!+ −
Returns true if both the date and the time are valid; otherwise+ −
returns false.+ −
+ −
\sa QDate::isValid(), QTime::isValid()+ −
*/+ −
+ −
bool QDateTime::isValid() const+ −
{+ −
return d->date.isValid() && d->time.isValid();+ −
}+ −
+ −
/*!+ −
Returns the date part of the datetime.+ −
+ −
\sa setDate(), time(), timeSpec()+ −
*/+ −
+ −
QDate QDateTime::date() const+ −
{+ −
return d->date;+ −
}+ −
+ −
/*!+ −
Returns the time part of the datetime.+ −
+ −
\sa setTime(), date(), timeSpec()+ −
*/+ −
+ −
QTime QDateTime::time() const+ −
{+ −
return d->time;+ −
}+ −
+ −
/*!+ −
Returns the time specification of the datetime.+ −
+ −
\sa setTimeSpec(), date(), time(), Qt::TimeSpec+ −
*/+ −
+ −
Qt::TimeSpec QDateTime::timeSpec() const+ −
{+ −
switch(d->spec)+ −
{+ −
case QDateTimePrivate::UTC:+ −
return Qt::UTC;+ −
case QDateTimePrivate::OffsetFromUTC:+ −
return Qt::OffsetFromUTC;+ −
default:+ −
return Qt::LocalTime;+ −
}+ −
}+ −
+ −
/*!+ −
Sets the date part of this datetime to \a date.+ −
If no time is set, it is set to midnight.+ −
+ −
\sa date(), setTime(), setTimeSpec()+ −
*/+ −
+ −
void QDateTime::setDate(const QDate &date)+ −
{+ −
detach();+ −
d->date = date;+ −
if (d->spec == QDateTimePrivate::LocalStandard+ −
|| d->spec == QDateTimePrivate::LocalDST)+ −
d->spec = QDateTimePrivate::LocalUnknown;+ −
if (date.isValid() && !d->time.isValid())+ −
d->time = QTime(0, 0, 0);+ −
}+ −
+ −
/*!+ −
Sets the time part of this datetime to \a time.+ −
+ −
\sa time(), setDate(), setTimeSpec()+ −
*/+ −
+ −
void QDateTime::setTime(const QTime &time)+ −
{+ −
detach();+ −
if (d->spec == QDateTimePrivate::LocalStandard+ −
|| d->spec == QDateTimePrivate::LocalDST)+ −
d->spec = QDateTimePrivate::LocalUnknown;+ −
d->time = time;+ −
}+ −
+ −
/*!+ −
Sets the time specification used in this datetime to \a spec.+ −
+ −
\sa timeSpec(), setDate(), setTime(), Qt::TimeSpec+ −
*/+ −
+ −
void QDateTime::setTimeSpec(Qt::TimeSpec spec)+ −
{+ −
detach();+ −
+ −
switch(spec)+ −
{+ −
case Qt::UTC:+ −
d->spec = QDateTimePrivate::UTC;+ −
break;+ −
case Qt::OffsetFromUTC:+ −
d->spec = QDateTimePrivate::OffsetFromUTC;+ −
break;+ −
default:+ −
d->spec = QDateTimePrivate::LocalUnknown;+ −
break;+ −
}+ −
}+ −
+ −
qint64 toMSecsSinceEpoch_helper(qint64 jd, int msecs)+ −
{+ −
qint64 days = jd - JULIAN_DAY_FOR_EPOCH;+ −
qint64 retval = (days * MSECS_PER_DAY) + msecs;+ −
return retval;+ −
}+ −
+ −
/*!+ −
\since 4.7+ −
+ −
Returns the datetime as the number of milliseconds that have passed+ −
since 1970-01-01T00:00:00.000, Coordinated Universal Time (Qt::UTC).+ −
+ −
On systems that do not support time zones, this function will+ −
behave as if local time were Qt::UTC.+ −
+ −
The behavior for this function is undefined if the datetime stored in+ −
this object is not valid. However, for all valid dates, this function+ −
returns a unique value.+ −
+ −
\sa toTime_t(), setMSecsSinceEpoch()+ −
*/+ −
qint64 QDateTime::toMSecsSinceEpoch() const+ −
{+ −
QDate utcDate;+ −
QTime utcTime;+ −
d->getUTC(utcDate, utcTime);+ −
+ −
return toMSecsSinceEpoch_helper(utcDate.jd, utcTime.ds());+ −
}+ −
+ −
/*!+ −
Returns the datetime as the number of seconds that have passed+ −
since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC).+ −
+ −
On systems that do not support time zones, this function will+ −
behave as if local time were Qt::UTC.+ −
+ −
\note This function returns a 32-bit unsigned integer, so it does not+ −
support dates before 1970, but it does support dates after+ −
2038-01-19T03:14:06, which may not be valid time_t values. Be careful+ −
when passing those time_t values to system functions, which could+ −
interpret them as negative dates.+ −
+ −
If the date is outside the range 1970-01-01T00:00:00 to+ −
2106-02-07T06:28:14, this function returns -1 cast to an unsigned integer+ −
(i.e., 0xFFFFFFFF).+ −
+ −
To get an extended range, use toMSecsSinceEpoch().+ −
+ −
\sa toMSecsSinceEpoch(), setTime_t()+ −
*/+ −
+ −
uint QDateTime::toTime_t() const+ −
{+ −
qint64 retval = toMSecsSinceEpoch() / 1000;+ −
if (quint64(retval) >= Q_UINT64_C(0xFFFFFFFF))+ −
return uint(-1);+ −
return uint(retval);+ −
}+ −
+ −
/*!+ −
\since 4.7+ −
+ −
Sets the date and time given the number of milliseconds,\a msecs, that have+ −
passed since 1970-01-01T00:00:00.000, Coordinated Universal Time+ −
(Qt::UTC). On systems that do not support time zones this function+ −
will behave as if local time were Qt::UTC.+ −
+ −
Note that there are possible values for \a msecs that lie outside the+ −
valid range of QDateTime, both negative and positive. The behavior of+ −
this function is undefined for those values.+ −
+ −
\sa toMSecsSinceEpoch(), setTime_t()+ −
*/+ −
void QDateTime::setMSecsSinceEpoch(qint64 msecs)+ −
{+ −
detach();+ −
+ −
QDateTimePrivate::Spec oldSpec = d->spec;+ −
+ −
int ddays = msecs / MSECS_PER_DAY;+ −
msecs %= MSECS_PER_DAY;+ −
if (msecs < 0) {+ −
// negative+ −
--ddays;+ −
msecs += MSECS_PER_DAY;+ −
}+ −
+ −
d->date = QDate(1970, 1, 1).addDays(ddays);+ −
d->time = QTime().addMSecs(msecs);+ −
d->spec = QDateTimePrivate::UTC;+ −
+ −
if (oldSpec != QDateTimePrivate::UTC)+ −
d->spec = d->getLocal(d->date, d->time);+ −
}+ −
+ −
/*!+ −
\fn void QDateTime::setTime_t(uint seconds)+ −
+ −
Sets the date and time given the number of \a seconds that have+ −
passed since 1970-01-01T00:00:00, Coordinated Universal Time+ −
(Qt::UTC). On systems that do not support time zones this function+ −
will behave as if local time were Qt::UTC.+ −
+ −
\sa toTime_t()+ −
*/+ −
+ −
void QDateTime::setTime_t(uint secsSince1Jan1970UTC)+ −
{+ −
detach();+ −
+ −
QDateTimePrivate::Spec oldSpec = d->spec;+ −
+ −
d->date = QDate(1970, 1, 1).addDays(secsSince1Jan1970UTC / SECS_PER_DAY);+ −
d->time = QTime().addSecs(secsSince1Jan1970UTC % SECS_PER_DAY);+ −
d->spec = QDateTimePrivate::UTC;+ −
+ −
if (oldSpec != QDateTimePrivate::UTC)+ −
d->spec = d->getLocal(d->date, d->time);+ −
}+ −
+ −
#ifndef QT_NO_DATESTRING+ −
/*!+ −
\fn QString QDateTime::toString(Qt::DateFormat format) const+ −
+ −
\overload+ −
+ −
Returns the datetime as a string in the \a format given.+ −
+ −
If the \a format is Qt::TextDate, the string is formatted in+ −
the default way. QDate::shortDayName(), QDate::shortMonthName(),+ −
and QTime::toString() are used to generate the string, so the+ −
day and month names will be localized names. An example of this+ −
formatting is "Wed May 20 03:40:13 1998".+ −
+ −
If the \a format is Qt::ISODate, the string format corresponds+ −
to the ISO 8601 extended specification for representations of+ −
dates and times, taking the form YYYY-MM-DDTHH:MM:SS.+ −
+ −
If the \a format is Qt::SystemLocaleShortDate or+ −
Qt::SystemLocaleLongDate, the string format depends on the locale+ −
settings of the system. Identical to calling+ −
QLocale::system().toString(datetime, QLocale::ShortFormat) or+ −
QLocale::system().toString(datetime, QLocale::LongFormat).+ −
+ −
If the \a format is Qt::DefaultLocaleShortDate or+ −
Qt::DefaultLocaleLongDate, the string format depends on the+ −
default application locale. This is the locale set with+ −
QLocale::setDefault(), or the system locale if no default locale+ −
has been set. Identical to calling QLocale().toString(datetime,+ −
QLocale::ShortFormat) or QLocale().toString(datetime,+ −
QLocale::LongFormat).+ −
+ −
If the datetime is invalid, an empty string will be returned.+ −
+ −
\warning The Qt::ISODate format is only valid for years in the+ −
range 0 to 9999. This restriction may apply to locale-aware+ −
formats as well, depending on the locale settings.+ −
+ −
\sa QDate::toString() QTime::toString() Qt::DateFormat+ −
*/+ −
+ −
QString QDateTime::toString(Qt::DateFormat f) const+ −
{+ −
QString buf;+ −
if (!isValid())+ −
return buf;+ −
+ −
if (f == Qt::ISODate) {+ −
buf = d->date.toString(Qt::ISODate);+ −
if (buf.isEmpty())+ −
return QString(); // failed to convert+ −
buf += QLatin1Char('T');+ −
buf += d->time.toString(Qt::ISODate);+ −
}+ −
#ifndef QT_NO_TEXTDATE+ −
else if (f == Qt::TextDate) {+ −
#ifndef Q_WS_WIN+ −
buf = d->date.shortDayName(d->date.dayOfWeek());+ −
buf += QLatin1Char(' ');+ −
buf += d->date.shortMonthName(d->date.month());+ −
buf += QLatin1Char(' ');+ −
buf += QString::number(d->date.day());+ −
#else+ −
wchar_t out[255];+ −
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255);+ −
QString winstr = QString::fromWCharArray(out);+ −
switch (winstr.toInt()) {+ −
case 1:+ −
buf = d->date.shortDayName(d->date.dayOfWeek());+ −
buf += QLatin1Char(' ');+ −
buf += QString::number(d->date.day());+ −
buf += QLatin1String(". ");+ −
buf += d->date.shortMonthName(d->date.month());+ −
break;+ −
default:+ −
buf = d->date.shortDayName(d->date.dayOfWeek());+ −
buf += QLatin1Char(' ');+ −
buf += d->date.shortMonthName(d->date.month());+ −
buf += QLatin1Char(' ');+ −
buf += QString::number(d->date.day());+ −
}+ −
#endif+ −
buf += QLatin1Char(' ');+ −
buf += d->time.toString();+ −
buf += QLatin1Char(' ');+ −
buf += QString::number(d->date.year());+ −
}+ −
#endif+ −
else {+ −
buf = d->date.toString(f);+ −
if (buf.isEmpty())+ −
return QString(); // failed to convert+ −
buf += QLatin1Char(' ');+ −
buf += d->time.toString(f);+ −
}+ −
+ −
return buf;+ −
}+ −
+ −
/*!+ −
Returns the datetime as a string. The \a format parameter+ −
determines the format of the result string.+ −
+ −
These expressions may be used for the date:+ −
+ −
\table+ −
\header \i Expression \i Output+ −
\row \i d \i the day as number without a leading zero (1 to 31)+ −
\row \i dd \i the day as number with a leading zero (01 to 31)+ −
\row \i ddd+ −
\i the abbreviated localized day name (e.g. 'Mon' to 'Sun').+ −
Uses QDate::shortDayName().+ −
\row \i dddd+ −
\i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').+ −
Uses QDate::longDayName().+ −
\row \i M \i the month as number without a leading zero (1-12)+ −
\row \i MM \i the month as number with a leading zero (01-12)+ −
\row \i MMM+ −
\i the abbreviated localized month name (e.g. 'Jan' to 'Dec').+ −
Uses QDate::shortMonthName().+ −
\row \i MMMM+ −
\i the long localized month name (e.g. 'January' to 'December').+ −
Uses QDate::longMonthName().+ −
\row \i yy \i the year as two digit number (00-99)+ −
\row \i yyyy \i the year as four digit number+ −
\endtable+ −
+ −
These expressions may be used for the time:+ −
+ −
\table+ −
\header \i Expression \i Output+ −
\row \i h+ −
\i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)+ −
\row \i hh+ −
\i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)+ −
\row \i m \i the minute without a leading zero (0 to 59)+ −
\row \i mm \i the minute with a leading zero (00 to 59)+ −
\row \i s \i the second without a leading zero (0 to 59)+ −
\row \i ss \i the second with a leading zero (00 to 59)+ −
\row \i z \i the milliseconds without leading zeroes (0 to 999)+ −
\row \i zzz \i the milliseconds with leading zeroes (000 to 999)+ −
\row \i AP+ −
\i use AM/PM display. \e AP will be replaced by either "AM" or "PM".+ −
\row \i ap+ −
\i use am/pm display. \e ap will be replaced by either "am" or "pm".+ −
\endtable+ −
+ −
All other input characters will be ignored. Any sequence of characters that+ −
are enclosed in singlequotes will be treated as text and not be used as an+ −
expression. Two consecutive singlequotes ("''") are replaced by a singlequote+ −
in the output.+ −
+ −
Example format strings (assumed that the QDateTime is 21 May 2001+ −
14:13:09):+ −
+ −
\table+ −
\header \i Format \i Result+ −
\row \i dd.MM.yyyy \i 21.05.2001+ −
\row \i ddd MMMM d yy \i Tue May 21 01+ −
\row \i hh:mm:ss.zzz \i 14:13:09.042+ −
\row \i h:m:s ap \i 2:13:9 pm+ −
\endtable+ −
+ −
If the datetime is invalid, an empty string will be returned.+ −
+ −
\sa QDate::toString() QTime::toString()+ −
*/+ −
QString QDateTime::toString(const QString& format) const+ −
{+ −
return fmtDateTime(format, &d->time, &d->date);+ −
}+ −
#endif //QT_NO_DATESTRING+ −
+ −
/*!+ −
Returns a QDateTime object containing a datetime \a ndays days+ −
later than the datetime of this object (or earlier if \a ndays is+ −
negative).+ −
+ −
\sa daysTo(), addMonths(), addYears(), addSecs()+ −
*/+ −
+ −
QDateTime QDateTime::addDays(int ndays) const+ −
{+ −
return QDateTime(d->date.addDays(ndays), d->time, timeSpec());+ −
}+ −
+ −
/*!+ −
Returns a QDateTime object containing a datetime \a nmonths months+ −
later than the datetime of this object (or earlier if \a nmonths+ −
is negative).+ −
+ −
\sa daysTo(), addDays(), addYears(), addSecs()+ −
*/+ −
+ −
QDateTime QDateTime::addMonths(int nmonths) const+ −
{+ −
return QDateTime(d->date.addMonths(nmonths), d->time, timeSpec());+ −
}+ −
+ −
/*!+ −
Returns a QDateTime object containing a datetime \a nyears years+ −
later than the datetime of this object (or earlier if \a nyears is+ −
negative).+ −
+ −
\sa daysTo(), addDays(), addMonths(), addSecs()+ −
*/+ −
+ −
QDateTime QDateTime::addYears(int nyears) const+ −
{+ −
return QDateTime(d->date.addYears(nyears), d->time, timeSpec());+ −
}+ −
+ −
QDateTime QDateTimePrivate::addMSecs(const QDateTime &dt, qint64 msecs)+ −
{+ −
QDate utcDate;+ −
QTime utcTime;+ −
dt.d->getUTC(utcDate, utcTime);+ −
+ −
addMSecs(utcDate, utcTime, msecs);+ −
+ −
return QDateTime(utcDate, utcTime, Qt::UTC).toTimeSpec(dt.timeSpec());+ −
}+ −
+ −
/*!+ −
Adds \a msecs to utcDate and \a utcTime as appropriate. It is assumed that+ −
utcDate and utcTime are adjusted to UTC.+ −
+ −
\since 4.5+ −
\internal+ −
*/+ −
void QDateTimePrivate::addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs)+ −
{+ −
uint dd = utcDate.jd;+ −
int tt = utcTime.ds();+ −
int sign = 1;+ −
if (msecs < 0) {+ −
msecs = -msecs;+ −
sign = -1;+ −
}+ −
if (msecs >= int(MSECS_PER_DAY)) {+ −
dd += sign * (msecs / MSECS_PER_DAY);+ −
msecs %= MSECS_PER_DAY;+ −
}+ −
+ −
tt += sign * msecs;+ −
if (tt < 0) {+ −
tt = MSECS_PER_DAY - tt - 1;+ −
dd -= tt / MSECS_PER_DAY;+ −
tt = tt % MSECS_PER_DAY;+ −
tt = MSECS_PER_DAY - tt - 1;+ −
} else if (tt >= int(MSECS_PER_DAY)) {+ −
dd += tt / MSECS_PER_DAY;+ −
tt = tt % MSECS_PER_DAY;+ −
}+ −
+ −
utcDate.jd = dd;+ −
utcTime.mds = tt;+ −
}+ −
+ −
/*!+ −
Returns a QDateTime object containing a datetime \a s seconds+ −
later than the datetime of this object (or earlier if \a s is+ −
negative).+ −
+ −
\sa addMSecs(), secsTo(), addDays(), addMonths(), addYears()+ −
*/+ −
+ −
QDateTime QDateTime::addSecs(int s) const+ −
{+ −
return d->addMSecs(*this, qint64(s) * 1000);+ −
}+ −
+ −
/*!+ −
Returns a QDateTime object containing a datetime \a msecs miliseconds+ −
later than the datetime of this object (or earlier if \a msecs is+ −
negative).+ −
+ −
\sa addSecs(), msecsTo(), addDays(), addMonths(), addYears()+ −
*/+ −
QDateTime QDateTime::addMSecs(qint64 msecs) const+ −
{+ −
return d->addMSecs(*this, msecs);+ −
}+ −
+ −
/*!+ −
Returns the number of days from this datetime to the \a other+ −
datetime. If the \a other datetime is earlier than this datetime,+ −
the value returned is negative.+ −
+ −
\sa addDays(), secsTo(), msecsTo()+ −
*/+ −
+ −
int QDateTime::daysTo(const QDateTime &other) const+ −
{+ −
return d->date.daysTo(other.d->date);+ −
}+ −
+ −
/*!+ −
Returns the number of seconds from this datetime to the \a other+ −
datetime. If the \a other datetime is earlier than this datetime,+ −
the value returned is negative.+ −
+ −
Before performing the comparison, the two datetimes are converted+ −
to Qt::UTC to ensure that the result is correct if one of the two+ −
datetimes has daylight saving time (DST) and the other doesn't.+ −
+ −
Example:+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 11+ −
+ −
\sa addSecs(), daysTo(), QTime::secsTo()+ −
*/+ −
+ −
int QDateTime::secsTo(const QDateTime &other) const+ −
{+ −
QDate date1, date2;+ −
QTime time1, time2;+ −
+ −
d->getUTC(date1, time1);+ −
other.d->getUTC(date2, time2);+ −
+ −
return (date1.daysTo(date2) * SECS_PER_DAY) + time1.secsTo(time2);+ −
}+ −
+ −
/*!+ −
Returns the number of milliseconds from this datetime to the \a other+ −
datetime. If the \a other datetime is earlier than this datetime,+ −
the value returned is negative.+ −
+ −
Before performing the comparison, the two datetimes are converted+ −
to Qt::UTC to ensure that the result is correct if one of the two+ −
datetimes has daylight saving time (DST) and the other doesn't.+ −
+ −
\sa addMSecs(), daysTo(), QTime::msecsTo()+ −
*/+ −
+ −
qint64 QDateTime::msecsTo(const QDateTime &other) const+ −
{+ −
QDate selfDate;+ −
QDate otherDate;+ −
QTime selfTime;+ −
QTime otherTime;+ −
+ −
d->getUTC(selfDate, selfTime);+ −
other.d->getUTC(otherDate, otherTime);+ −
+ −
return (static_cast<qint64>(selfDate.daysTo(otherDate)) * static_cast<qint64>(MSECS_PER_DAY))+ −
+ static_cast<qint64>(selfTime.msecsTo(otherTime));+ −
}+ −
+ −
+ −
/*!+ −
\fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec specification) const+ −
+ −
Returns a copy of this datetime configured to use the given time+ −
\a specification.+ −
+ −
\sa timeSpec(), toUTC(), toLocalTime()+ −
*/+ −
+ −
QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const+ −
{+ −
if ((d->spec == QDateTimePrivate::UTC) == (spec == Qt::UTC))+ −
return *this;+ −
+ −
QDateTime ret;+ −
if (spec == Qt::UTC) {+ −
d->getUTC(ret.d->date, ret.d->time);+ −
ret.d->spec = QDateTimePrivate::UTC;+ −
} else {+ −
ret.d->spec = d->getLocal(ret.d->date, ret.d->time);+ −
}+ −
return ret;+ −
}+ −
+ −
/*!+ −
Returns true if this datetime is equal to the \a other datetime;+ −
otherwise returns false.+ −
+ −
\sa operator!=()+ −
*/+ −
+ −
bool QDateTime::operator==(const QDateTime &other) const+ −
{+ −
if (d->spec == other.d->spec && d->utcOffset == other.d->utcOffset)+ −
return d->time == other.d->time && d->date == other.d->date;+ −
else {+ −
QDate date1, date2;+ −
QTime time1, time2;+ −
+ −
d->getUTC(date1, time1);+ −
other.d->getUTC(date2, time2);+ −
return time1 == time2 && date1 == date2;+ −
}+ −
}+ −
+ −
/*!+ −
\fn bool QDateTime::operator!=(const QDateTime &other) const+ −
+ −
Returns true if this datetime is different from the \a other+ −
datetime; otherwise returns false.+ −
+ −
Two datetimes are different if either the date, the time, or the+ −
time zone components are different.+ −
+ −
\sa operator==()+ −
*/+ −
+ −
/*!+ −
Returns true if this datetime is earlier than the \a other+ −
datetime; otherwise returns false.+ −
*/+ −
+ −
bool QDateTime::operator<(const QDateTime &other) const+ −
{+ −
if (d->spec == other.d->spec && d->spec != QDateTimePrivate::OffsetFromUTC) {+ −
if (d->date != other.d->date)+ −
return d->date < other.d->date;+ −
return d->time < other.d->time;+ −
} else {+ −
QDate date1, date2;+ −
QTime time1, time2;+ −
d->getUTC(date1, time1);+ −
other.d->getUTC(date2, time2);+ −
if (date1 != date2)+ −
return date1 < date2;+ −
return time1 < time2;+ −
}+ −
}+ −
+ −
/*!+ −
\fn bool QDateTime::operator<=(const QDateTime &other) const+ −
+ −
Returns true if this datetime is earlier than or equal to the+ −
\a other datetime; otherwise returns false.+ −
*/+ −
+ −
/*!+ −
\fn bool QDateTime::operator>(const QDateTime &other) const+ −
+ −
Returns true if this datetime is later than the \a other datetime;+ −
otherwise returns false.+ −
*/+ −
+ −
/*!+ −
\fn bool QDateTime::operator>=(const QDateTime &other) const+ −
+ −
Returns true if this datetime is later than or equal to the+ −
\a other datetime; otherwise returns false.+ −
*/+ −
+ −
/*!+ −
\fn QDateTime QDateTime::currentDateTime()+ −
Returns the current datetime, as reported by the system clock, in+ −
the local time zone.+ −
+ −
\sa currentDateTimeUtc(), QDate::currentDate(), QTime::currentTime(), toTimeSpec()+ −
*/+ −
+ −
/*!+ −
\fn QDateTime QDateTime::currentDateTimeUtc()+ −
\since 4.7+ −
Returns the current datetime, as reported by the system clock, in+ −
UTC.+ −
+ −
\sa currentDateTime(), QDate::currentDate(), QTime::currentTime(), toTimeSpec()+ −
*/+ −
+ −
/*!+ −
\fn qint64 QDateTime::currentMSecsSinceEpoch()+ −
\since 4.7+ −
+ −
Returns the number of milliseconds since 1970-01-01T00:00:00 Universal+ −
Coordinated Time. This number is like the POSIX time_t variable, but+ −
expressed in milliseconds instead.+ −
+ −
\sa currentDateTime(), currentDateTimeUtc(), toTime_t(), toTimeSpec()+ −
*/+ −
+ −
static inline uint msecsFromDecomposed(int hour, int minute, int sec, int msec = 0)+ −
{+ −
return MSECS_PER_HOUR * hour + MSECS_PER_MIN * minute + 1000 * sec + msec;+ −
}+ −
+ −
#if defined(Q_OS_WIN)+ −
QDate QDate::currentDate()+ −
{+ −
QDate d;+ −
SYSTEMTIME st;+ −
memset(&st, 0, sizeof(SYSTEMTIME));+ −
GetLocalTime(&st);+ −
d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);+ −
return d;+ −
}+ −
+ −
QTime QTime::currentTime()+ −
{+ −
QTime ct;+ −
SYSTEMTIME st;+ −
memset(&st, 0, sizeof(SYSTEMTIME));+ −
GetLocalTime(&st);+ −
ct.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);+ −
#if defined(Q_OS_WINCE)+ −
ct.startTick = GetTickCount() % MSECS_PER_DAY;+ −
#endif+ −
return ct;+ −
}+ −
+ −
QDateTime QDateTime::currentDateTime()+ −
{+ −
QDate d;+ −
QTime t;+ −
SYSTEMTIME st;+ −
memset(&st, 0, sizeof(SYSTEMTIME));+ −
GetLocalTime(&st);+ −
d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);+ −
t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);+ −
return QDateTime(d, t);+ −
}+ −
+ −
QDateTime QDateTime::currentDateTimeUtc()+ −
{+ −
QDate d;+ −
QTime t;+ −
SYSTEMTIME st;+ −
memset(&st, 0, sizeof(SYSTEMTIME));+ −
GetSystemTime(&st);+ −
d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);+ −
t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);+ −
return QDateTime(d, t, Qt::UTC);+ −
}+ −
+ −
qint64 QDateTime::currentMSecsSinceEpoch()+ −
{+ −
QDate d;+ −
QTime t;+ −
SYSTEMTIME st;+ −
memset(&st, 0, sizeof(SYSTEMTIME));+ −
GetSystemTime(&st);+ −
+ −
return msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds) ++ −
qint64(julianDayFromGregorianDate(st.wYear, st.wMonth, st.wDay)+ −
- julianDayFromGregorianDate(1970, 1, 1)) * Q_INT64_C(86400000);+ −
}+ −
+ −
#elif defined(Q_OS_SYMBIAN)+ −
QDate QDate::currentDate()+ −
{+ −
QDate d;+ −
TTime localTime;+ −
localTime.HomeTime();+ −
TDateTime localDateTime = localTime.DateTime();+ −
// months and days are zero indexed+ −
d.jd = julianDayFromDate(localDateTime.Year(), localDateTime.Month() + 1, localDateTime.Day() + 1 );+ −
return d;+ −
}+ −
+ −
QTime QTime::currentTime()+ −
{+ −
QTime ct;+ −
TTime localTime;+ −
localTime.HomeTime();+ −
TDateTime localDateTime = localTime.DateTime();+ −
ct.mds = msecsFromDecomposed(localDateTime.Hour(), localDateTime.Minute(),+ −
localDateTime.Second(), localDateTime.MicroSecond() / 1000);+ −
return ct;+ −
}+ −
+ −
QDateTime QDateTime::currentDateTime()+ −
{+ −
QDate d;+ −
QTime ct;+ −
TTime localTime;+ −
localTime.HomeTime();+ −
TDateTime localDateTime = localTime.DateTime();+ −
// months and days are zero indexed+ −
d.jd = julianDayFromDate(localDateTime.Year(), localDateTime.Month() + 1, localDateTime.Day() + 1);+ −
ct.mds = msecsFromDecomposed(localDateTime.Hour(), localDateTime.Minute(),+ −
localDateTime.Second(), localDateTime.MicroSecond() / 1000);+ −
return QDateTime(d, ct);+ −
}+ −
+ −
QDateTime QDateTime::currentDateTimeUtc()+ −
{+ −
QDate d;+ −
QTime ct;+ −
TTime gmTime;+ −
gmTime.UniversalTime();+ −
TDateTime gmtDateTime = gmTime.DateTime();+ −
// months and days are zero indexed+ −
d.jd = julianDayFromDate(gmtDateTime.Year(), gmtDateTime.Month() + 1, gmtDateTime.Day() + 1);+ −
ct.mds = msecsFromDecomposed(gmtDateTime.Hour(), gmtDateTime.Minute(),+ −
gmtDateTime.Second(), gmtDateTime.MicroSecond() / 1000);+ −
return QDateTime(d, ct, Qt::UTC);+ −
}+ −
+ −
qint64 QDateTime::currentMSecsSinceEpoch()+ −
{+ −
QDate d;+ −
QTime ct;+ −
TTime gmTime;+ −
gmTime.UniversalTime();+ −
TDateTime gmtDateTime = gmTime.DateTime();+ −
+ −
// according to the documentation, the value is:+ −
// "a date and time as a number of microseconds since midnight, January 1st, 0 AD nominal Gregorian"+ −
qint64 value = gmTime.Int64();+ −
+ −
// whereas 1970-01-01T00:00:00 is (in the same representation):+ −
// ((1970 * 365) + (1970 / 4) - (1970 / 100) + (1970 / 400) - 13) * 86400 * 1000000+ −
static const qint64 unixEpoch = Q_INT64_C(0xdcddb30f2f8000);+ −
+ −
return (value - unixEpoch) / 1000;+ −
}+ −
+ −
#elif defined(Q_OS_UNIX)+ −
QDate QDate::currentDate()+ −
{+ −
QDate d;+ −
// posix compliant system+ −
time_t ltime;+ −
time(<ime);+ −
struct tm *t = 0;+ −
+ −
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)+ −
// use the reentrant version of localtime() where available+ −
tzset();+ −
struct tm res;+ −
t = localtime_r(<ime, &res);+ −
#else+ −
t = localtime(<ime);+ −
#endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS+ −
+ −
d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);+ −
return d;+ −
}+ −
+ −
QTime QTime::currentTime()+ −
{+ −
QTime ct;+ −
// posix compliant system+ −
struct timeval tv;+ −
gettimeofday(&tv, 0);+ −
time_t ltime = tv.tv_sec;+ −
struct tm *t = 0;+ −
+ −
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)+ −
// use the reentrant version of localtime() where available+ −
tzset();+ −
struct tm res;+ −
t = localtime_r(<ime, &res);+ −
#else+ −
t = localtime(<ime);+ −
#endif+ −
Q_CHECK_PTR(t);+ −
+ −
ct.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);+ −
return ct;+ −
}+ −
+ −
QDateTime QDateTime::currentDateTime()+ −
{+ −
// posix compliant system+ −
// we have milliseconds+ −
struct timeval tv;+ −
gettimeofday(&tv, 0);+ −
time_t ltime = tv.tv_sec;+ −
struct tm *t = 0;+ −
+ −
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)+ −
// use the reentrant version of localtime() where available+ −
tzset();+ −
struct tm res;+ −
t = localtime_r(<ime, &res);+ −
#else+ −
t = localtime(<ime);+ −
#endif+ −
+ −
QDateTime dt;+ −
dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);+ −
+ −
dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);+ −
dt.d->spec = t->tm_isdst > 0 ? QDateTimePrivate::LocalDST :+ −
t->tm_isdst == 0 ? QDateTimePrivate::LocalStandard :+ −
QDateTimePrivate::LocalUnknown;+ −
return dt;+ −
}+ −
+ −
QDateTime QDateTime::currentDateTimeUtc()+ −
{+ −
// posix compliant system+ −
// we have milliseconds+ −
struct timeval tv;+ −
gettimeofday(&tv, 0);+ −
time_t ltime = tv.tv_sec;+ −
struct tm *t = 0;+ −
+ −
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)+ −
// use the reentrant version of localtime() where available+ −
struct tm res;+ −
t = gmtime_r(<ime, &res);+ −
#else+ −
t = gmtime(<ime);+ −
#endif+ −
+ −
QDateTime dt;+ −
dt.d->time.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000);+ −
+ −
dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);+ −
dt.d->spec = QDateTimePrivate::UTC;+ −
return dt;+ −
}+ −
+ −
qint64 QDateTime::currentMSecsSinceEpoch()+ −
{+ −
// posix compliant system+ −
// we have milliseconds+ −
struct timeval tv;+ −
gettimeofday(&tv, 0);+ −
return qint64(tv.tv_sec) * Q_INT64_C(1000) + tv.tv_usec / 1000;+ −
}+ −
+ −
#else+ −
#error "What system is this?"+ −
#endif+ −
+ −
/*!+ −
\since 4.2+ −
+ −
Returns a datetime whose date and time are the number of \a seconds+ −
that have passed since 1970-01-01T00:00:00, Coordinated Universal+ −
Time (Qt::UTC). On systems that do not support time zones, the time+ −
will be set as if local time were Qt::UTC.+ −
+ −
\sa toTime_t(), setTime_t()+ −
*/+ −
QDateTime QDateTime::fromTime_t(uint seconds)+ −
{+ −
QDateTime d;+ −
d.setTime_t(seconds);+ −
return d;+ −
}+ −
+ −
/*!+ −
\since 4.7+ −
+ −
Returns a datetime whose date and time are the number of milliseconds, \a msecs,+ −
that have passed since 1970-01-01T00:00:00.000, Coordinated Universal+ −
Time (Qt::UTC). On systems that do not support time zones, the time+ −
will be set as if local time were Qt::UTC.+ −
+ −
Note that there are possible values for \a msecs that lie outside the valid+ −
range of QDateTime, both negative and positive. The behavior of this+ −
function is undefined for those values.+ −
+ −
\sa toTime_t(), setTime_t()+ −
*/+ −
QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs)+ −
{+ −
QDateTime d;+ −
d.setMSecsSinceEpoch(msecs);+ −
return d;+ −
}+ −
+ −
/*!+ −
\since 4.4+ −
\internal+ −
+ −
Sets the offset from UTC to \a seconds, and also sets timeSpec() to+ −
Qt::OffsetFromUTC.+ −
+ −
The maximum and minimum offset is 14 positive or negative hours. If+ −
\a seconds is larger or smaller than that, the result is undefined.+ −
+ −
0 as offset is identical to UTC. Therefore, if \a seconds is 0, the+ −
timeSpec() will be set to Qt::UTC. Hence the UTC offset always+ −
relates to UTC, and can never relate to local time.+ −
+ −
\sa isValid(), utcOffset()+ −
*/+ −
void QDateTime::setUtcOffset(int seconds)+ −
{+ −
detach();+ −
+ −
/* The motivation to also setting d->spec is to ensure that the QDateTime+ −
* instance stay in well-defined states all the time, instead of that+ −
* we instruct the user to ensure it. */+ −
if(seconds == 0)+ −
d->spec = QDateTimePrivate::UTC;+ −
else+ −
d->spec = QDateTimePrivate::OffsetFromUTC;+ −
+ −
/* Even if seconds is 0 we assign it to utcOffset. */+ −
d->utcOffset = seconds;+ −
}+ −
+ −
/*!+ −
\since 4.4+ −
\internal+ −
+ −
Returns the UTC offset in seconds. If the timeSpec() isn't+ −
Qt::OffsetFromUTC, 0 is returned. However, since 0 is a valid UTC+ −
offset the return value of this function cannot be used to determine+ −
whether a utcOffset() is used or is valid, timeSpec() must be+ −
checked.+ −
+ −
Likewise, if this QDateTime() is invalid or if timeSpec() isn't+ −
Qt::OffsetFromUTC, 0 is returned.+ −
+ −
The UTC offset only applies if the timeSpec() is Qt::OffsetFromUTC.+ −
+ −
\sa isValid(), setUtcOffset()+ −
*/+ −
int QDateTime::utcOffset() const+ −
{+ −
if(isValid() && d->spec == QDateTimePrivate::OffsetFromUTC)+ −
return d->utcOffset;+ −
else+ −
return 0;+ −
}+ −
+ −
#ifndef QT_NO_DATESTRING+ −
+ −
static int fromShortMonthName(const QString &monthName)+ −
{+ −
// Assume that English monthnames are the default+ −
for (int i = 0; i < 12; ++i) {+ −
if (monthName == QLatin1String(qt_shortMonthNames[i]))+ −
return i + 1;+ −
}+ −
// If English names can't be found, search the localized ones+ −
for (int i = 1; i <= 12; ++i) {+ −
if (monthName == QDate::shortMonthName(i))+ −
return i;+ −
}+ −
return -1;+ −
}+ −
+ −
/*!+ −
\fn QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)+ −
+ −
Returns the QDateTime represented by the \a string, using the+ −
\a format given, or an invalid datetime if this is not possible.+ −
+ −
Note for Qt::TextDate: It is recommended that you use the+ −
English short month names (e.g. "Jan"). Although localized month+ −
names can also be used, they depend on the user's locale settings.+ −
*/+ −
QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)+ −
{+ −
if (s.isEmpty()) {+ −
return QDateTime();+ −
}+ −
+ −
switch (f) {+ −
case Qt::ISODate: {+ −
QString tmp = s;+ −
Qt::TimeSpec ts = Qt::LocalTime;+ −
const QDate date = QDate::fromString(tmp.left(10), Qt::ISODate);+ −
if (tmp.size() == 10)+ −
return QDateTime(date);+ −
+ −
tmp = tmp.mid(11);+ −
+ −
// Recognize UTC specifications+ −
if (tmp.endsWith(QLatin1Char('Z'))) {+ −
ts = Qt::UTC;+ −
tmp.chop(1);+ −
}+ −
+ −
// Recognize timezone specifications+ −
QRegExp rx(QLatin1String("[+-]"));+ −
if (tmp.contains(rx)) {+ −
int idx = tmp.indexOf(rx);+ −
QString tmp2 = tmp.mid(idx);+ −
tmp = tmp.left(idx);+ −
bool ok = true;+ −
int ntzhour = 1;+ −
int ntzminute = 3;+ −
if ( tmp2.indexOf(QLatin1Char(':')) == 3 )+ −
ntzminute = 4;+ −
const int tzhour(tmp2.mid(ntzhour, 2).toInt(&ok));+ −
const int tzminute(tmp2.mid(ntzminute, 2).toInt(&ok));+ −
QTime tzt(tzhour, tzminute);+ −
int utcOffset = (tzt.hour() * 60 + tzt.minute()) * 60;+ −
if ( utcOffset != 0 ) {+ −
ts = Qt::OffsetFromUTC;+ −
QDateTime dt(date, QTime::fromString(tmp, Qt::ISODate), ts);+ −
dt.setUtcOffset( utcOffset * (tmp2.startsWith(QLatin1Char('-')) ? -1 : 1) );+ −
return dt;+ −
}+ −
}+ −
return QDateTime(date, QTime::fromString(tmp, Qt::ISODate), ts);+ −
}+ −
case Qt::SystemLocaleDate:+ −
case Qt::SystemLocaleShortDate:+ −
case Qt::SystemLocaleLongDate:+ −
return fromString(s, QLocale::system().dateTimeFormat(f == Qt::SystemLocaleLongDate ? QLocale::LongFormat+ −
: QLocale::ShortFormat));+ −
case Qt::LocaleDate:+ −
case Qt::DefaultLocaleShortDate:+ −
case Qt::DefaultLocaleLongDate:+ −
return fromString(s, QLocale().dateTimeFormat(f == Qt::DefaultLocaleLongDate ? QLocale::LongFormat+ −
: QLocale::ShortFormat));+ −
#if !defined(QT_NO_TEXTDATE)+ −
case Qt::TextDate: {+ −
QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts);+ −
+ −
if ((parts.count() < 5) || (parts.count() > 6)) {+ −
return QDateTime();+ −
}+ −
+ −
// Accept "Sun Dec 1 13:02:00 1974" and "Sun 1. Dec 13:02:00 1974"+ −
int month = -1, day = -1;+ −
bool ok;+ −
+ −
month = fromShortMonthName(parts.at(1));+ −
if (month != -1) {+ −
day = parts.at(2).toInt(&ok);+ −
if (!ok)+ −
day = -1;+ −
}+ −
+ −
if (month == -1 || day == -1) {+ −
// first variant failed, lets try the other+ −
month = fromShortMonthName(parts.at(2));+ −
if (month != -1) {+ −
QString dayStr = parts.at(1);+ −
if (dayStr.endsWith(QLatin1Char('.'))) {+ −
dayStr.chop(1);+ −
day = dayStr.toInt(&ok);+ −
if (!ok)+ −
day = -1;+ −
} else {+ −
day = -1;+ −
}+ −
}+ −
}+ −
+ −
if (month == -1 || day == -1) {+ −
// both variants failed, give up+ −
return QDateTime();+ −
}+ −
+ −
int year;+ −
QStringList timeParts = parts.at(3).split(QLatin1Char(':'));+ −
if ((timeParts.count() == 3) || (timeParts.count() == 2)) {+ −
year = parts.at(4).toInt(&ok);+ −
if (!ok)+ −
return QDateTime();+ −
} else {+ −
timeParts = parts.at(4).split(QLatin1Char(':'));+ −
if ((timeParts.count() != 3) && (timeParts.count() != 2))+ −
return QDateTime();+ −
year = parts.at(3).toInt(&ok);+ −
if (!ok)+ −
return QDateTime();+ −
}+ −
+ −
int hour = timeParts.at(0).toInt(&ok);+ −
if (!ok) {+ −
return QDateTime();+ −
}+ −
+ −
int minute = timeParts.at(1).toInt(&ok);+ −
if (!ok) {+ −
return QDateTime();+ −
}+ −
+ −
int second = (timeParts.count() > 2) ? timeParts.at(2).toInt(&ok) : 0;+ −
if (!ok) {+ −
return QDateTime();+ −
}+ −
+ −
QDate date(year, month, day);+ −
QTime time(hour, minute, second);+ −
+ −
if (parts.count() == 5)+ −
return QDateTime(date, time, Qt::LocalTime);+ −
+ −
QString tz = parts.at(5);+ −
if (!tz.startsWith(QLatin1String("GMT"), Qt::CaseInsensitive))+ −
return QDateTime();+ −
int tzoffset = 0;+ −
if (tz.length() > 3) {+ −
QChar sign = tz.at(3);+ −
if ((sign != QLatin1Char('+'))+ −
&& (sign != QLatin1Char('-'))) {+ −
return QDateTime();+ −
}+ −
int tzhour = tz.mid(4, 2).toInt(&ok);+ −
if (!ok)+ −
return QDateTime();+ −
int tzminute = tz.mid(6).toInt(&ok);+ −
if (!ok)+ −
return QDateTime();+ −
tzoffset = (tzhour*60 + tzminute) * 60;+ −
if (sign == QLatin1Char('-'))+ −
tzoffset = -tzoffset;+ −
}+ −
return QDateTime(date, time, Qt::UTC).addSecs(-tzoffset).toLocalTime();+ −
}+ −
#endif //QT_NO_TEXTDATE+ −
}+ −
+ −
return QDateTime();+ −
}+ −
+ −
/*!+ −
\fn QDateTime::fromString(const QString &string, const QString &format)+ −
+ −
Returns the QDateTime represented by the \a string, using the \a+ −
format given, or an invalid datetime if the string cannot be parsed.+ −
+ −
These expressions may be used for the date part of the format string:+ −
+ −
\table+ −
\header \i Expression \i Output+ −
\row \i d \i the day as number without a leading zero (1 to 31)+ −
\row \i dd \i the day as number with a leading zero (01 to 31)+ −
\row \i ddd+ −
\i the abbreviated localized day name (e.g. 'Mon' to 'Sun').+ −
Uses QDate::shortDayName().+ −
\row \i dddd+ −
\i the long localized day name (e.g. 'Monday' to 'Sunday').+ −
Uses QDate::longDayName().+ −
\row \i M \i the month as number without a leading zero (1-12)+ −
\row \i MM \i the month as number with a leading zero (01-12)+ −
\row \i MMM+ −
\i the abbreviated localized month name (e.g. 'Jan' to 'Dec').+ −
Uses QDate::shortMonthName().+ −
\row \i MMMM+ −
\i the long localized month name (e.g. 'January' to 'December').+ −
Uses QDate::longMonthName().+ −
\row \i yy \i the year as two digit number (00-99)+ −
\row \i yyyy \i the year as four digit number+ −
\endtable+ −
+ −
\note Unlike the other version of this function, day and month names must+ −
be given in the user's local language. It is only possible to use the English+ −
names if the user's language is English.+ −
+ −
These expressions may be used for the time part of the format string:+ −
+ −
\table+ −
\header \i Expression \i Output+ −
\row \i h+ −
\i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)+ −
\row \i hh+ −
\i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)+ −
\row \i H+ −
\i the hour without a leading zero (0 to 23, even with AM/PM display)+ −
\row \i HH+ −
\i the hour with a leading zero (00 to 23, even with AM/PM display)+ −
\row \i m \i the minute without a leading zero (0 to 59)+ −
\row \i mm \i the minute with a leading zero (00 to 59)+ −
\row \i s \i the second without a leading zero (0 to 59)+ −
\row \i ss \i the second with a leading zero (00 to 59)+ −
\row \i z \i the milliseconds without leading zeroes (0 to 999)+ −
\row \i zzz \i the milliseconds with leading zeroes (000 to 999)+ −
\row \i AP or A+ −
\i interpret as an AM/PM time. \e AP must be either "AM" or "PM".+ −
\row \i ap or a+ −
\i Interpret as an AM/PM time. \e ap must be either "am" or "pm".+ −
\endtable+ −
+ −
All other input characters will be treated as text. Any sequence+ −
of characters that are enclosed in singlequotes will also be+ −
treated as text and not be used as an expression.+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 12+ −
+ −
If the format is not satisfied an invalid QDateTime is returned.+ −
The expressions that don't have leading zeroes (d, M, h, m, s, z) will be+ −
greedy. This means that they will use two digits even if this will+ −
put them outside the range and/or leave too few digits for other+ −
sections.+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 13+ −
+ −
This could have meant 1 January 00:30.00 but the M will grab+ −
two digits.+ −
+ −
For any field that is not represented in the format the following+ −
defaults are used:+ −
+ −
\table+ −
\header \i Field \i Default value+ −
\row \i Year \i 1900+ −
\row \i Month \i 1 (January)+ −
\row \i Day \i 1+ −
\row \i Hour \i 0+ −
\row \i Minute \i 0+ −
\row \i Second \i 0+ −
\endtable+ −
+ −
For example:+ −
+ −
\snippet doc/src/snippets/code/src_corelib_tools_qdatetime.cpp 14+ −
+ −
\sa QDate::fromString() QTime::fromString() QDate::toString()+ −
QDateTime::toString() QTime::toString()+ −
*/+ −
+ −
QDateTime QDateTime::fromString(const QString &string, const QString &format)+ −
{+ −
#ifndef QT_BOOTSTRAPPED+ −
QTime time;+ −
QDate date;+ −
+ −
QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString);+ −
if (dt.parseFormat(format) && dt.fromString(string, &date, &time))+ −
return QDateTime(date, time);+ −
#else+ −
Q_UNUSED(string);+ −
Q_UNUSED(format);+ −
#endif+ −
return QDateTime(QDate(), QTime(-1, -1, -1));+ −
}+ −
+ −
#endif // QT_NO_DATESTRING+ −
/*!+ −
\fn QDateTime QDateTime::toLocalTime() const+ −
+ −
Returns a datetime containing the date and time information in+ −
this datetime, but specified using the Qt::LocalTime definition.+ −
+ −
\sa toTimeSpec()+ −
*/+ −
+ −
/*!+ −
\fn QDateTime QDateTime::toUTC() const+ −
+ −
Returns a datetime containing the date and time information in+ −
this datetime, but specified using the Qt::UTC definition.+ −
+ −
\sa toTimeSpec()+ −
*/+ −
+ −
/*! \internal+ −
*/+ −
void QDateTime::detach()+ −
{+ −
d.detach();+ −
}+ −
+ −
/*****************************************************************************+ −
Date/time stream functions+ −
*****************************************************************************/+ −
+ −
#ifndef QT_NO_DATASTREAM+ −
/*!+ −
\relates QDate+ −
+ −
Writes the \a date to stream \a out.+ −
+ −
\sa {Serializing Qt Data Types}+ −
*/+ −
+ −
QDataStream &operator<<(QDataStream &out, const QDate &date)+ −
{+ −
return out << (quint32)(date.jd);+ −
}+ −
+ −
/*!+ −
\relates QDate+ −
+ −
Reads a date from stream \a in into the \a date.+ −
+ −
\sa {Serializing Qt Data Types}+ −
*/+ −
+ −
QDataStream &operator>>(QDataStream &in, QDate &date)+ −
{+ −
quint32 jd;+ −
in >> jd;+ −
date.jd = jd;+ −
return in;+ −
}+ −
+ −
/*!+ −
\relates QTime+ −
+ −
Writes \a time to stream \a out.+ −
+ −
\sa {Serializing Qt Data Types}+ −
*/+ −
+ −
QDataStream &operator<<(QDataStream &out, const QTime &time)+ −
{+ −
return out << quint32(time.mds);+ −
}+ −
+ −
/*!+ −
\relates QTime+ −
+ −
Reads a time from stream \a in into the given \a time.+ −
+ −
\sa {Serializing Qt Data Types}+ −
*/+ −
+ −
QDataStream &operator>>(QDataStream &in, QTime &time)+ −
{+ −
quint32 ds;+ −
in >> ds;+ −
time.mds = int(ds);+ −
return in;+ −
}+ −
+ −
/*!+ −
\relates QDateTime+ −
+ −
Writes \a dateTime to the \a out stream.+ −
+ −
\sa {Serializing Qt Data Types}+ −
*/+ −
QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime)+ −
{+ −
out << dateTime.d->date << dateTime.d->time;+ −
if (out.version() >= 7)+ −
out << (qint8)dateTime.d->spec;+ −
return out;+ −
}+ −
+ −
/*!+ −
\relates QDateTime+ −
+ −
Reads a datetime from the stream \a in into \a dateTime.+ −
+ −
\sa {Serializing Qt Data Types}+ −
*/+ −
+ −
QDataStream &operator>>(QDataStream &in, QDateTime &dateTime)+ −
{+ −
dateTime.detach();+ −
+ −
qint8 ts = (qint8)QDateTimePrivate::LocalUnknown;+ −
in >> dateTime.d->date >> dateTime.d->time;+ −
if (in.version() >= 7)+ −
in >> ts;+ −
dateTime.d->spec = (QDateTimePrivate::Spec)ts;+ −
return in;+ −
}+ −
#endif // QT_NO_DATASTREAM+ −
+ −
+ −
/*!+ −
\fn QString QDate::monthName(int month)+ −
+ −
Use shortMonthName() instead.+ −
*/+ −
+ −
/*!+ −
\fn QString QDate::dayName(int weekday)+ −
+ −
Use shortDayName() instead.+ −
*/+ −
+ −
/*!+ −
\fn bool QDate::leapYear(int year)+ −
+ −
Use isLeapYear() instead.+ −
*/+ −
+ −
/*!+ −
\fn QDate QDate::currentDate(Qt::TimeSpec spec)+ −
+ −
If \a spec is Qt::LocalTime, use the currentDate() overload that+ −
takes no parameters instead; otherwise, use+ −
QDateTime::currentDateTime().+ −
+ −
\oldcode+ −
QDate localDate = QDate::currentDate(Qt::LocalTime);+ −
QDate utcDate = QDate::currentDate(Qt::UTC);+ −
\newcode+ −
QDate localDate = QDate::currentDate();+ −
QDate utcDate = QDateTime::currentDateTime().toUTC().date();+ −
\endcode+ −
+ −
\sa QDateTime::toUTC()+ −
*/+ −
+ −
/*!+ −
\fn QTime QTime::currentTime(Qt::TimeSpec specification)+ −
+ −
Returns the current time for the given \a specification.+ −
+ −
To replace uses of this function where the \a specification is Qt::LocalTime,+ −
use the currentDate() overload that takes no parameters instead; otherwise,+ −
use QDateTime::currentDateTime() and convert the result to a UTC measurement.+ −
+ −
\oldcode+ −
QTime localTime = QTime::currentTime(Qt::LocalTime);+ −
QTime utcTime = QTime::currentTime(Qt::UTC);+ −
\newcode+ −
QTime localTime = QTime::currentTime();+ −
QTime utcTime = QTimeTime::currentDateTime().toUTC().time();+ −
\endcode+ −
+ −
\sa QDateTime::toUTC()+ −
*/+ −
+ −
/*!+ −
\fn void QDateTime::setTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec)+ −
+ −
Use the single-argument overload of setTime_t() instead.+ −
*/+ −
+ −
/*!+ −
\fn QDateTime QDateTime::currentDateTime(Qt::TimeSpec spec)+ −
+ −
Use the currentDateTime() overload that takes no parameters+ −
instead.+ −
*/+ −
+ −
// checks if there is an unqoted 'AP' or 'ap' in the string+ −
static bool hasUnquotedAP(const QString &f)+ −
{+ −
const QLatin1Char quote('\'');+ −
bool inquote = false;+ −
const int max = f.size();+ −
for (int i=0; i<max; ++i) {+ −
if (f.at(i) == quote) {+ −
inquote = !inquote;+ −
} else if (!inquote && f.at(i).toUpper() == QLatin1Char('A')) {+ −
return true;+ −
}+ −
}+ −
return false;+ −
}+ −
+ −
#ifndef QT_NO_DATESTRING+ −
/*****************************************************************************+ −
Some static function used by QDate, QTime and QDateTime+ −
*****************************************************************************/+ −
+ −
// Replaces tokens by their value. See QDateTime::toString() for a list of valid tokens+ −
static QString getFmtString(const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = false)+ −
{+ −
if (f.isEmpty())+ −
return QString();+ −
+ −
QString buf = f;+ −
int removed = 0;+ −
+ −
if (dt) {+ −
if (f.startsWith(QLatin1String("hh")) || f.startsWith(QLatin1String("HH"))) {+ −
const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;+ −
if (hour12 && dt->hour() > 12)+ −
buf = QString::number(dt->hour() - 12).rightJustified(2, QLatin1Char('0'), true);+ −
else if (hour12 && dt->hour() == 0)+ −
buf = QLatin1String("12");+ −
else+ −
buf = QString::number(dt->hour()).rightJustified(2, QLatin1Char('0'), true);+ −
removed = 2;+ −
} else if (f.at(0) == QLatin1Char('h') || f.at(0) == QLatin1Char('H')) {+ −
const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;+ −
if (hour12 && dt->hour() > 12)+ −
buf = QString::number(dt->hour() - 12);+ −
else if (hour12 && dt->hour() == 0)+ −
buf = QLatin1String("12");+ −
else+ −
buf = QString::number(dt->hour());+ −
removed = 1;+ −
} else if (f.startsWith(QLatin1String("mm"))) {+ −
buf = QString::number(dt->minute()).rightJustified(2, QLatin1Char('0'), true);+ −
removed = 2;+ −
} else if (f.at(0) == (QLatin1Char('m'))) {+ −
buf = QString::number(dt->minute());+ −
removed = 1;+ −
} else if (f.startsWith(QLatin1String("ss"))) {+ −
buf = QString::number(dt->second()).rightJustified(2, QLatin1Char('0'), true);+ −
removed = 2;+ −
} else if (f.at(0) == QLatin1Char('s')) {+ −
buf = QString::number(dt->second());+ −
} else if (f.startsWith(QLatin1String("zzz"))) {+ −
buf = QString::number(dt->msec()).rightJustified(3, QLatin1Char('0'), true);+ −
removed = 3;+ −
} else if (f.at(0) == QLatin1Char('z')) {+ −
buf = QString::number(dt->msec());+ −
removed = 1;+ −
} else if (f.at(0).toUpper() == QLatin1Char('A')) {+ −
const bool upper = f.at(0) == QLatin1Char('A');+ −
buf = dt->hour() < 12 ? QLatin1String("am") : QLatin1String("pm");+ −
if (upper)+ −
buf = buf.toUpper();+ −
if (f.size() > 1 && f.at(1).toUpper() == QLatin1Char('P') &&+ −
f.at(0).isUpper() == f.at(1).isUpper()) {+ −
removed = 2;+ −
} else {+ −
removed = 1;+ −
}+ −
}+ −
}+ −
+ −
if (dd) {+ −
if (f.startsWith(QLatin1String("dddd"))) {+ −
buf = dd->longDayName(dd->dayOfWeek());+ −
removed = 4;+ −
} else if (f.startsWith(QLatin1String("ddd"))) {+ −
buf = dd->shortDayName(dd->dayOfWeek());+ −
removed = 3;+ −
} else if (f.startsWith(QLatin1String("dd"))) {+ −
buf = QString::number(dd->day()).rightJustified(2, QLatin1Char('0'), true);+ −
removed = 2;+ −
} else if (f.at(0) == QLatin1Char('d')) {+ −
buf = QString::number(dd->day());+ −
removed = 1;+ −
} else if (f.startsWith(QLatin1String("MMMM"))) {+ −
buf = dd->longMonthName(dd->month());+ −
removed = 4;+ −
} else if (f.startsWith(QLatin1String("MMM"))) {+ −
buf = dd->shortMonthName(dd->month());+ −
removed = 3;+ −
} else if (f.startsWith(QLatin1String("MM"))) {+ −
buf = QString::number(dd->month()).rightJustified(2, QLatin1Char('0'), true);+ −
removed = 2;+ −
} else if (f.at(0) == QLatin1Char('M')) {+ −
buf = QString::number(dd->month());+ −
removed = 1;+ −
} else if (f.startsWith(QLatin1String("yyyy"))) {+ −
const int year = dd->year();+ −
buf = QString::number(qAbs(year)).rightJustified(4, QLatin1Char('0'));+ −
if(year > 0)+ −
removed = 4;+ −
else+ −
{+ −
buf.prepend(QLatin1Char('-'));+ −
removed = 5;+ −
}+ −
+ −
} else if (f.startsWith(QLatin1String("yy"))) {+ −
buf = QString::number(dd->year()).right(2).rightJustified(2, QLatin1Char('0'));+ −
removed = 2;+ −
}+ −
}+ −
if (removed == 0 || removed >= f.size()) {+ −
return buf;+ −
}+ −
+ −
return buf + getFmtString(f.mid(removed), dt, dd, am_pm);+ −
}+ −
+ −
// Parses the format string and uses getFmtString to get the values for the tokens. Ret+ −
static QString fmtDateTime(const QString& f, const QTime* dt, const QDate* dd)+ −
{+ −
const QLatin1Char quote('\'');+ −
if (f.isEmpty())+ −
return QString();+ −
if (dt && !dt->isValid())+ −
return QString();+ −
if (dd && !dd->isValid())+ −
return QString();+ −
+ −
const bool ap = hasUnquotedAP(f);+ −
+ −
QString buf;+ −
QString frm;+ −
QChar status(QLatin1Char('0'));+ −
+ −
for (int i = 0; i < (int)f.length(); ++i) {+ −
if (f.at(i) == quote) {+ −
if (status == quote) {+ −
if (i > 0 && f.at(i - 1) == quote)+ −
buf += QLatin1Char('\'');+ −
status = QLatin1Char('0');+ −
} else {+ −
if (!frm.isEmpty()) {+ −
buf += getFmtString(frm, dt, dd, ap);+ −
frm.clear();+ −
}+ −
status = quote;+ −
}+ −
} else if (status == quote) {+ −
buf += f.at(i);+ −
} else if (f.at(i) == status) {+ −
if ((ap) && ((f.at(i) == QLatin1Char('P')) || (f.at(i) == QLatin1Char('p'))))+ −
status = QLatin1Char('0');+ −
frm += f.at(i);+ −
} else {+ −
buf += getFmtString(frm, dt, dd, ap);+ −
frm.clear();+ −
if ((f.at(i) == QLatin1Char('h')) || (f.at(i) == QLatin1Char('m'))+ −
|| (f.at(i) == QLatin1Char('H'))+ −
|| (f.at(i) == QLatin1Char('s')) || (f.at(i) == QLatin1Char('z'))) {+ −
status = f.at(i);+ −
frm += f.at(i);+ −
} else if ((f.at(i) == QLatin1Char('d')) || (f.at(i) == QLatin1Char('M')) || (f.at(i) == QLatin1Char('y'))) {+ −
status = f.at(i);+ −
frm += f.at(i);+ −
} else if ((ap) && (f.at(i) == QLatin1Char('A'))) {+ −
status = QLatin1Char('P');+ −
frm += f.at(i);+ −
} else if((ap) && (f.at(i) == QLatin1Char('a'))) {+ −
status = QLatin1Char('p');+ −
frm += f.at(i);+ −
} else {+ −
buf += f.at(i);+ −
status = QLatin1Char('0');+ −
}+ −
}+ −
}+ −
+ −
buf += getFmtString(frm, dt, dd, ap);+ −
+ −
return buf;+ −
}+ −
#endif // QT_NO_DATESTRING+ −
+ −
#ifdef Q_OS_WIN+ −
static const int LowerYear = 1980;+ −
#else+ −
static const int LowerYear = 1970;+ −
#endif+ −
static const int UpperYear = 2037;+ −
+ −
static QDate adjustDate(QDate date)+ −
{+ −
QDate lowerLimit(LowerYear, 1, 2);+ −
QDate upperLimit(UpperYear, 12, 30);+ −
+ −
if (date > lowerLimit && date < upperLimit)+ −
return date;+ −
+ −
int month = date.month();+ −
int day = date.day();+ −
+ −
// neither 1970 nor 2037 are leap years, so make sure date isn't Feb 29+ −
if (month == 2 && day == 29)+ −
--day;+ −
+ −
if (date < lowerLimit)+ −
date.setDate(LowerYear, month, day);+ −
else+ −
date.setDate(UpperYear, month, day);+ −
+ −
return date;+ −
}+ −
+ −
static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time)+ −
{+ −
QDate fakeDate = adjustDate(date);+ −
+ −
// won't overflow because of fakeDate+ −
time_t secsSince1Jan1970UTC = toMSecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime().msecsTo(time)) / 1000;+ −
tm *brokenDown = 0;+ −
+ −
#if defined(Q_OS_WINCE)+ −
tm res;+ −
FILETIME utcTime = time_tToFt(secsSince1Jan1970UTC);+ −
FILETIME resultTime;+ −
FileTimeToLocalFileTime(&utcTime , &resultTime);+ −
SYSTEMTIME sysTime;+ −
FileTimeToSystemTime(&resultTime , &sysTime);+ −
+ −
res.tm_sec = sysTime.wSecond;+ −
res.tm_min = sysTime.wMinute;+ −
res.tm_hour = sysTime.wHour;+ −
res.tm_mday = sysTime.wDay;+ −
res.tm_mon = sysTime.wMonth - 1;+ −
res.tm_year = sysTime.wYear - 1900;+ −
brokenDown = &res;+ −
#elif defined(Q_OS_SYMBIAN)+ −
// months and days are zero index based+ −
_LIT(KUnixEpoch, "19700000:000000.000000");+ −
TTimeIntervalSeconds utcOffset = User::UTCOffset();+ −
TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC);+ −
TTime epochTTime;+ −
TInt err = epochTTime.Set(KUnixEpoch);+ −
tm res;+ −
if(err == KErrNone) {+ −
TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC;+ −
utcTTime = utcTTime + utcOffset;+ −
TDateTime utcDateTime = utcTTime.DateTime();+ −
res.tm_sec = utcDateTime.Second();+ −
res.tm_min = utcDateTime.Minute();+ −
res.tm_hour = utcDateTime.Hour();+ −
res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct+ −
res.tm_mon = utcDateTime.Month();+ −
res.tm_year = utcDateTime.Year() - 1900;+ −
res.tm_isdst = 0;+ −
brokenDown = &res;+ −
}+ −
#elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)+ −
// use the reentrant version of localtime() where available+ −
tzset();+ −
tm res;+ −
brokenDown = localtime_r(&secsSince1Jan1970UTC, &res);+ −
#elif defined(_MSC_VER) && _MSC_VER >= 1400+ −
tm res;+ −
if (!_localtime64_s(&res, &secsSince1Jan1970UTC))+ −
brokenDown = &res;+ −
#else+ −
brokenDown = localtime(&secsSince1Jan1970UTC);+ −
#endif+ −
if (!brokenDown) {+ −
date = QDate(1970, 1, 1);+ −
time = QTime();+ −
return QDateTimePrivate::LocalUnknown;+ −
} else {+ −
int deltaDays = fakeDate.daysTo(date);+ −
date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);+ −
time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());+ −
date = date.addDays(deltaDays);+ −
if (brokenDown->tm_isdst > 0)+ −
return QDateTimePrivate::LocalDST;+ −
else if (brokenDown->tm_isdst < 0)+ −
return QDateTimePrivate::LocalUnknown;+ −
else+ −
return QDateTimePrivate::LocalStandard;+ −
}+ −
}+ −
+ −
static void localToUtc(QDate &date, QTime &time, int isdst)+ −
{+ −
if (!date.isValid())+ −
return;+ −
+ −
QDate fakeDate = adjustDate(date);+ −
+ −
tm localTM;+ −
localTM.tm_sec = time.second();+ −
localTM.tm_min = time.minute();+ −
localTM.tm_hour = time.hour();+ −
localTM.tm_mday = fakeDate.day();+ −
localTM.tm_mon = fakeDate.month() - 1;+ −
localTM.tm_year = fakeDate.year() - 1900;+ −
localTM.tm_isdst = (int)isdst;+ −
#if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)+ −
time_t secsSince1Jan1970UTC = (toMSecsSinceEpoch_helper(fakeDate.toJulianDay(), QTime().msecsTo(time)) / 1000);+ −
#else+ −
#if defined(Q_OS_WIN)+ −
_tzset();+ −
#endif+ −
time_t secsSince1Jan1970UTC = mktime(&localTM);+ −
#endif+ −
tm *brokenDown = 0;+ −
#if defined(Q_OS_WINCE)+ −
tm res;+ −
FILETIME localTime = time_tToFt(secsSince1Jan1970UTC);+ −
SYSTEMTIME sysTime;+ −
FileTimeToSystemTime(&localTime, &sysTime);+ −
FILETIME resultTime;+ −
LocalFileTimeToFileTime(&localTime , &resultTime);+ −
FileTimeToSystemTime(&resultTime , &sysTime);+ −
res.tm_sec = sysTime.wSecond;+ −
res.tm_min = sysTime.wMinute;+ −
res.tm_hour = sysTime.wHour;+ −
res.tm_mday = sysTime.wDay;+ −
res.tm_mon = sysTime.wMonth - 1;+ −
res.tm_year = sysTime.wYear - 1900;+ −
res.tm_isdst = (int)isdst;+ −
brokenDown = &res;+ −
#elif defined(Q_OS_SYMBIAN)+ −
// months and days are zero index based+ −
_LIT(KUnixEpoch, "19700000:000000.000000");+ −
TTimeIntervalSeconds utcOffset = TTimeIntervalSeconds(0 - User::UTCOffset().Int());+ −
TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC);+ −
TTime epochTTime;+ −
TInt err = epochTTime.Set(KUnixEpoch);+ −
tm res;+ −
if(err == KErrNone) {+ −
TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC;+ −
utcTTime = utcTTime + utcOffset;+ −
TDateTime utcDateTime = utcTTime.DateTime();+ −
res.tm_sec = utcDateTime.Second();+ −
res.tm_min = utcDateTime.Minute();+ −
res.tm_hour = utcDateTime.Hour();+ −
res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct+ −
res.tm_mon = utcDateTime.Month();+ −
res.tm_year = utcDateTime.Year() - 1900;+ −
res.tm_isdst = (int)isdst;+ −
brokenDown = &res;+ −
}+ −
#elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)+ −
// use the reentrant version of gmtime() where available+ −
tm res;+ −
brokenDown = gmtime_r(&secsSince1Jan1970UTC, &res);+ −
#elif defined(_MSC_VER) && _MSC_VER >= 1400+ −
tm res;+ −
if (!_gmtime64_s(&res, &secsSince1Jan1970UTC))+ −
brokenDown = &res;+ −
#else+ −
brokenDown = gmtime(&secsSince1Jan1970UTC);+ −
#endif // !QT_NO_THREAD && _POSIX_THREAD_SAFE_FUNCTIONS+ −
if (!brokenDown) {+ −
date = QDate(1970, 1, 1);+ −
time = QTime();+ −
} else {+ −
int deltaDays = fakeDate.daysTo(date);+ −
date = QDate(brokenDown->tm_year + 1900, brokenDown->tm_mon + 1, brokenDown->tm_mday);+ −
time = QTime(brokenDown->tm_hour, brokenDown->tm_min, brokenDown->tm_sec, time.msec());+ −
date = date.addDays(deltaDays);+ −
}+ −
}+ −
+ −
QDateTimePrivate::Spec QDateTimePrivate::getLocal(QDate &outDate, QTime &outTime) const+ −
{+ −
outDate = date;+ −
outTime = time;+ −
if (spec == QDateTimePrivate::UTC)+ −
return utcToLocal(outDate, outTime);+ −
return spec;+ −
}+ −
+ −
void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const+ −
{+ −
outDate = date;+ −
outTime = time;+ −
const bool isOffset = spec == QDateTimePrivate::OffsetFromUTC;+ −
+ −
if (spec != QDateTimePrivate::UTC && !isOffset)+ −
localToUtc(outDate, outTime, (int)spec);+ −
+ −
if (isOffset)+ −
addMSecs(outDate, outTime, -(qint64(utcOffset) * 1000));+ −
}+ −
+ −
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_NO_DATESTRING)+ −
QDebug operator<<(QDebug dbg, const QDate &date)+ −
{+ −
dbg.nospace() << "QDate(" << date.toString() << ')';+ −
return dbg.space();+ −
}+ −
+ −
QDebug operator<<(QDebug dbg, const QTime &time)+ −
{+ −
dbg.nospace() << "QTime(" << time.toString() << ')';+ −
return dbg.space();+ −
}+ −
+ −
QDebug operator<<(QDebug dbg, const QDateTime &date)+ −
{+ −
dbg.nospace() << "QDateTime(" << date.toString() << ')';+ −
return dbg.space();+ −
}+ −
#endif+ −
+ −
#ifndef QT_BOOTSTRAPPED+ −
+ −
/*!+ −
\internal+ −
Gets the digit from a datetime. E.g.+ −
+ −
QDateTime var(QDate(2004, 02, 02));+ −
int digit = getDigit(var, Year);+ −
// digit = 2004+ −
*/+ −
+ −
int QDateTimeParser::getDigit(const QDateTime &t, int index) const+ −
{+ −
if (index < 0 || index >= sectionNodes.size()) {+ −
#ifndef QT_NO_DATESTRING+ −
qWarning("QDateTimeParser::getDigit() Internal error (%s %d)",+ −
qPrintable(t.toString()), index);+ −
#else+ −
qWarning("QDateTimeParser::getDigit() Internal error (%d)", index);+ −
#endif+ −
return -1;+ −
}+ −
const SectionNode &node = sectionNodes.at(index);+ −
switch (node.type) {+ −
case Hour24Section: case Hour12Section: return t.time().hour();+ −
case MinuteSection: return t.time().minute();+ −
case SecondSection: return t.time().second();+ −
case MSecSection: return t.time().msec();+ −
case YearSection2Digits:+ −
case YearSection: return t.date().year();+ −
case MonthSection: return t.date().month();+ −
case DaySection: return t.date().day();+ −
case DayOfWeekSection: return t.date().day();+ −
case AmPmSection: return t.time().hour() > 11 ? 1 : 0;+ −
+ −
default: break;+ −
}+ −
+ −
#ifndef QT_NO_DATESTRING+ −
qWarning("QDateTimeParser::getDigit() Internal error 2 (%s %d)",+ −
qPrintable(t.toString()), index);+ −
#else+ −
qWarning("QDateTimeParser::getDigit() Internal error 2 (%d)", index);+ −
#endif+ −
return -1;+ −
}+ −
+ −
/*!+ −
\internal+ −
Sets a digit in a datetime. E.g.+ −
+ −
QDateTime var(QDate(2004, 02, 02));+ −
int digit = getDigit(var, Year);+ −
// digit = 2004+ −
setDigit(&var, Year, 2005);+ −
digit = getDigit(var, Year);+ −
// digit = 2005+ −
*/+ −
+ −
bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const+ −
{+ −
if (index < 0 || index >= sectionNodes.size()) {+ −
#ifndef QT_NO_DATESTRING+ −
qWarning("QDateTimeParser::setDigit() Internal error (%s %d %d)",+ −
qPrintable(v.toString()), index, newVal);+ −
#else+ −
qWarning("QDateTimeParser::setDigit() Internal error (%d %d)", index, newVal);+ −
#endif+ −
return false;+ −
}+ −
const SectionNode &node = sectionNodes.at(index);+ −
+ −
int year, month, day, hour, minute, second, msec;+ −
year = v.date().year();+ −
month = v.date().month();+ −
day = v.date().day();+ −
hour = v.time().hour();+ −
minute = v.time().minute();+ −
second = v.time().second();+ −
msec = v.time().msec();+ −
+ −
switch (node.type) {+ −
case Hour24Section: case Hour12Section: hour = newVal; break;+ −
case MinuteSection: minute = newVal; break;+ −
case SecondSection: second = newVal; break;+ −
case MSecSection: msec = newVal; break;+ −
case YearSection2Digits:+ −
case YearSection: year = newVal; break;+ −
case MonthSection: month = newVal; break;+ −
case DaySection:+ −
case DayOfWeekSection:+ −
if (newVal > 31) {+ −
// have to keep legacy behavior. setting the+ −
// date to 32 should return false. Setting it+ −
// to 31 for february should return true+ −
return false;+ −
}+ −
day = newVal;+ −
break;+ −
case AmPmSection: hour = (newVal == 0 ? hour % 12 : (hour % 12) + 12); break;+ −
default:+ −
qWarning("QDateTimeParser::setDigit() Internal error (%s)",+ −
qPrintable(sectionName(node.type)));+ −
break;+ −
}+ −
+ −
if (!(node.type & (DaySection|DayOfWeekSection))) {+ −
if (day < cachedDay)+ −
day = cachedDay;+ −
const int max = QDate(year, month, 1).daysInMonth();+ −
if (day > max) {+ −
day = max;+ −
}+ −
}+ −
if (QDate::isValid(year, month, day) && QTime::isValid(hour, minute, second, msec)) {+ −
v = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);+ −
return true;+ −
}+ −
return false;+ −
}+ −
+ −
+ −
+ −
/*!+ −
\+ −
+ −
Returns the absolute maximum for a section+ −
*/+ −
+ −
int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const+ −
{+ −
const SectionNode &sn = sectionNode(s);+ −
switch (sn.type) {+ −
case Hour24Section:+ −
case Hour12Section: return 23; // this is special-cased in+ −
// parseSection. We want it to be+ −
// 23 for the stepBy case.+ −
case MinuteSection:+ −
case SecondSection: return 59;+ −
case MSecSection: return 999;+ −
case YearSection2Digits:+ −
case YearSection: return 9999; // sectionMaxSize will prevent+ −
// people from typing in a larger+ −
// number in count == 2 sections.+ −
// stepBy() will work on real years anyway+ −
case MonthSection: return 12;+ −
case DaySection:+ −
case DayOfWeekSection: return cur.isValid() ? cur.date().daysInMonth() : 31;+ −
case AmPmSection: return 1;+ −
default: break;+ −
}+ −
qWarning("QDateTimeParser::absoluteMax() Internal error (%s)",+ −
qPrintable(sectionName(sn.type)));+ −
return -1;+ −
}+ −
+ −
/*!+ −
\internal+ −
+ −
Returns the absolute minimum for a section+ −
*/+ −
+ −
int QDateTimeParser::absoluteMin(int s) const+ −
{+ −
const SectionNode &sn = sectionNode(s);+ −
switch (sn.type) {+ −
case Hour24Section:+ −
case Hour12Section:+ −
case MinuteSection:+ −
case SecondSection:+ −
case MSecSection:+ −
case YearSection2Digits:+ −
case YearSection: return 0;+ −
case MonthSection:+ −
case DaySection:+ −
case DayOfWeekSection: return 1;+ −
case AmPmSection: return 0;+ −
default: break;+ −
}+ −
qWarning("QDateTimeParser::absoluteMin() Internal error (%s, %0x)",+ −
qPrintable(sectionName(sn.type)), sn.type);+ −
return -1;+ −
}+ −
+ −
/*!+ −
\internal+ −
+ −
Returns the sectionNode for the Section \a s.+ −
*/+ −
+ −
const QDateTimeParser::SectionNode &QDateTimeParser::sectionNode(int sectionIndex) const+ −
{+ −
if (sectionIndex < 0) {+ −
switch (sectionIndex) {+ −
case FirstSectionIndex:+ −
return first;+ −
case LastSectionIndex:+ −
return last;+ −
case NoSectionIndex:+ −
return none;+ −
}+ −
} else if (sectionIndex < sectionNodes.size()) {+ −
return sectionNodes.at(sectionIndex);+ −
}+ −
+ −
qWarning("QDateTimeParser::sectionNode() Internal error (%d)",+ −
sectionIndex);+ −
return none;+ −
}+ −
+ −
QDateTimeParser::Section QDateTimeParser::sectionType(int sectionIndex) const+ −
{+ −
return sectionNode(sectionIndex).type;+ −
}+ −
+ −
+ −
/*!+ −
\internal+ −
+ −
Returns the starting position for section \a s.+ −
*/+ −
+ −
int QDateTimeParser::sectionPos(int sectionIndex) const+ −
{+ −
return sectionPos(sectionNode(sectionIndex));+ −
}+ −
+ −
int QDateTimeParser::sectionPos(const SectionNode &sn) const+ −
{+ −
switch (sn.type) {+ −
case FirstSection: return 0;+ −
case LastSection: return displayText().size() - 1;+ −
default: break;+ −
}+ −
if (sn.pos == -1) {+ −
qWarning("QDateTimeParser::sectionPos Internal error (%s)", qPrintable(sectionName(sn.type)));+ −
return -1;+ −
}+ −
return sn.pos;+ −
}+ −
+ −
+ −
/*!+ −
\internal helper function for parseFormat. removes quotes that are+ −
not escaped and removes the escaping on those that are escaped+ −
+ −
*/+ −
+ −
static QString unquote(const QString &str)+ −
{+ −
const QChar quote(QLatin1Char('\''));+ −
const QChar slash(QLatin1Char('\\'));+ −
const QChar zero(QLatin1Char('0'));+ −
QString ret;+ −
QChar status(zero);+ −
const int max = str.size();+ −
for (int i=0; i<max; ++i) {+ −
if (str.at(i) == quote) {+ −
if (status != quote) {+ −
status = quote;+ −
} else if (!ret.isEmpty() && str.at(i - 1) == slash) {+ −
ret[ret.size() - 1] = quote;+ −
} else {+ −
status = zero;+ −
}+ −
} else {+ −
ret += str.at(i);+ −
}+ −
}+ −
return ret;+ −
}+ −
/*!+ −
\internal+ −
+ −
Parses the format \a newFormat. If successful, returns true and+ −
sets up the format. Else keeps the old format and returns false.+ −
+ −
*/+ −
+ −
static inline int countRepeat(const QString &str, int index, int maxCount)+ −
{+ −
int count = 1;+ −
const QChar ch(str.at(index));+ −
const int max = qMin(index + maxCount, str.size());+ −
while (index + count < max && str.at(index + count) == ch) {+ −
++count;+ −
}+ −
return count;+ −
}+ −
+ −
static inline void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote)+ −
{+ −
QString str(string.mid(from, size));+ −
if (lastQuote >= from)+ −
str = unquote(str);+ −
list->append(str);+ −
}+ −
+ −
+ −
bool QDateTimeParser::parseFormat(const QString &newFormat)+ −
{+ −
const QLatin1Char quote('\'');+ −
const QLatin1Char slash('\\');+ −
const QLatin1Char zero('0');+ −
if (newFormat == displayFormat && !newFormat.isEmpty()) {+ −
return true;+ −
}+ −
+ −
QDTPDEBUGN("parseFormat: %s", newFormat.toLatin1().constData());+ −
+ −
QVector<SectionNode> newSectionNodes;+ −
Sections newDisplay = 0;+ −
QStringList newSeparators;+ −
int i, index = 0;+ −
int add = 0;+ −
QChar status(zero);+ −
const int max = newFormat.size();+ −
int lastQuote = -1;+ −
for (i = 0; i<max; ++i) {+ −
if (newFormat.at(i) == quote) {+ −
lastQuote = i;+ −
++add;+ −
if (status != quote) {+ −
status = quote;+ −
} else if (newFormat.at(i - 1) != slash) {+ −
status = zero;+ −
}+ −
} else if (status != quote) {+ −
const char sect = newFormat.at(i).toLatin1();+ −
switch (sect) {+ −
case 'H':+ −
case 'h':+ −
if (parserType != QVariant::Date) {+ −
const Section hour = (sect == 'h') ? Hour12Section : Hour24Section;+ −
const SectionNode sn = { hour, i - add, countRepeat(newFormat, i, 2) };+ −
newSectionNodes.append(sn);+ −
appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);+ −
i += sn.count - 1;+ −
index = i + 1;+ −
newDisplay |= hour;+ −
}+ −
break;+ −
case 'm':+ −
if (parserType != QVariant::Date) {+ −
const SectionNode sn = { MinuteSection, i - add, countRepeat(newFormat, i, 2) };+ −
newSectionNodes.append(sn);+ −
appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);+ −
i += sn.count - 1;+ −
index = i + 1;+ −
newDisplay |= MinuteSection;+ −
}+ −
break;+ −
case 's':+ −
if (parserType != QVariant::Date) {+ −
const SectionNode sn = { SecondSection, i - add, countRepeat(newFormat, i, 2) };+ −
newSectionNodes.append(sn);+ −
appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);+ −
i += sn.count - 1;+ −
index = i + 1;+ −
newDisplay |= SecondSection;+ −
}+ −
break;+ −
+ −
case 'z':+ −
if (parserType != QVariant::Date) {+ −
const SectionNode sn = { MSecSection, i - add, countRepeat(newFormat, i, 3) < 3 ? 1 : 3 };+ −
newSectionNodes.append(sn);+ −
appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);+ −
i += sn.count - 1;+ −
index = i + 1;+ −
newDisplay |= MSecSection;+ −
}+ −
break;+ −
case 'A':+ −
case 'a':+ −
if (parserType != QVariant::Date) {+ −
const bool cap = (sect == 'A');+ −
const SectionNode sn = { AmPmSection, i - add, (cap ? 1 : 0) };+ −
newSectionNodes.append(sn);+ −
appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);+ −
newDisplay |= AmPmSection;+ −
if (i + 1 < newFormat.size()+ −
&& newFormat.at(i+1) == (cap ? QLatin1Char('P') : QLatin1Char('p'))) {+ −
++i;+ −
}+ −
index = i + 1;+ −
}+ −
break;+ −
case 'y':+ −
if (parserType != QVariant::Time) {+ −
const int repeat = countRepeat(newFormat, i, 4);+ −
if (repeat >= 2) {+ −
const SectionNode sn = { repeat == 4 ? YearSection : YearSection2Digits,+ −
i - add, repeat == 4 ? 4 : 2 };+ −
newSectionNodes.append(sn);+ −
appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);+ −
i += sn.count - 1;+ −
index = i + 1;+ −
newDisplay |= sn.type;+ −
}+ −
}+ −
break;+ −
case 'M':+ −
if (parserType != QVariant::Time) {+ −
const SectionNode sn = { MonthSection, i - add, countRepeat(newFormat, i, 4) };+ −
newSectionNodes.append(sn);+ −
newSeparators.append(unquote(newFormat.mid(index, i - index)));+ −
i += sn.count - 1;+ −
index = i + 1;+ −
newDisplay |= MonthSection;+ −
}+ −
break;+ −
case 'd':+ −
if (parserType != QVariant::Time) {+ −
const int repeat = countRepeat(newFormat, i, 4);+ −
const SectionNode sn = { repeat >= 3 ? DayOfWeekSection : DaySection, i - add, repeat };+ −
newSectionNodes.append(sn);+ −
appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);+ −
i += sn.count - 1;+ −
index = i + 1;+ −
newDisplay |= sn.type;+ −
}+ −
break;+ −
+ −
default:+ −
break;+ −
}+ −
}+ −
}+ −
if (newSectionNodes.isEmpty() && context == DateTimeEdit) {+ −
return false;+ −
}+ −
+ −
if ((newDisplay & (AmPmSection|Hour12Section)) == Hour12Section) {+ −
const int max = newSectionNodes.size();+ −
for (int i=0; i<max; ++i) {+ −
SectionNode &node = newSectionNodes[i];+ −
if (node.type == Hour12Section)+ −
node.type = Hour24Section;+ −
}+ −
}+ −
+ −
if (index < newFormat.size()) {+ −
appendSeparator(&newSeparators, newFormat, index, index - max, lastQuote);+ −
} else {+ −
newSeparators.append(QString());+ −
}+ −
+ −
displayFormat = newFormat;+ −
separators = newSeparators;+ −
sectionNodes = newSectionNodes;+ −
display = newDisplay;+ −
last.pos = -1;+ −
+ −
// for (int i=0; i<sectionNodes.size(); ++i) {+ −
// QDTPDEBUG << sectionName(sectionNodes.at(i).type) << sectionNodes.at(i).count;+ −
// }+ −
+ −
QDTPDEBUG << newFormat << displayFormat;+ −
QDTPDEBUGN("separators:\n'%s'", separators.join(QLatin1String("\n")).toLatin1().constData());+ −
+ −
return true;+ −
}+ −
+ −
/*!+ −
\internal+ −
+ −
Returns the size of section \a s.+ −
*/+ −
+ −
int QDateTimeParser::sectionSize(int sectionIndex) const+ −
{+ −
if (sectionIndex < 0)+ −
return 0;+ −
+ −
if (sectionIndex >= sectionNodes.size()) {+ −
qWarning("QDateTimeParser::sectionSize Internal error (%d)", sectionIndex);+ −
return -1;+ −
}+ −
if (sectionIndex == sectionNodes.size() - 1) {+ −
return displayText().size() - sectionPos(sectionIndex) - separators.last().size();+ −
} else {+ −
return sectionPos(sectionIndex + 1) - sectionPos(sectionIndex)+ −
- separators.at(sectionIndex + 1).size();+ −
}+ −
}+ −
+ −
+ −
int QDateTimeParser::sectionMaxSize(Section s, int count) const+ −
{+ −
#ifndef QT_NO_TEXTDATE+ −
int mcount = 12;+ −
#endif+ −
+ −
switch (s) {+ −
case FirstSection:+ −
case NoSection:+ −
case LastSection: return 0;+ −
+ −
case AmPmSection: {+ −
const int lowerMax = qMin(getAmPmText(AmText, LowerCase).size(),+ −
getAmPmText(PmText, LowerCase).size());+ −
const int upperMax = qMin(getAmPmText(AmText, UpperCase).size(),+ −
getAmPmText(PmText, UpperCase).size());+ −
return qMin(4, qMin(lowerMax, upperMax));+ −
}+ −
+ −
case Hour24Section:+ −
case Hour12Section:+ −
case MinuteSection:+ −
case SecondSection:+ −
case DaySection: return 2;+ −
case DayOfWeekSection:+ −
#ifdef QT_NO_TEXTDATE+ −
return 2;+ −
#else+ −
mcount = 7;+ −
// fall through+ −
#endif+ −
case MonthSection:+ −
if (count <= 2)+ −
return 2;+ −
+ −
#ifdef QT_NO_TEXTDATE+ −
return 2;+ −
#else+ −
{+ −
int ret = 0;+ −
const QLocale l = locale();+ −
for (int i=1; i<=mcount; ++i) {+ −
const QString str = (s == MonthSection+ −
? l.monthName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat)+ −
: l.dayName(i, count == 4 ? QLocale::LongFormat : QLocale::ShortFormat));+ −
ret = qMax(str.size(), ret);+ −
}+ −
return ret;+ −
}+ −
#endif+ −
case MSecSection: return 3;+ −
case YearSection: return 4;+ −
case YearSection2Digits: return 2;+ −
+ −
case CalendarPopupSection:+ −
case Internal:+ −
case TimeSectionMask:+ −
case DateSectionMask:+ −
qWarning("QDateTimeParser::sectionMaxSize: Invalid section %s",+ −
sectionName(s).toLatin1().constData());+ −
+ −
case NoSectionIndex:+ −
case FirstSectionIndex:+ −
case LastSectionIndex:+ −
case CalendarPopupIndex:+ −
// these cases can't happen+ −
break;+ −
}+ −
return -1;+ −
}+ −
+ −
+ −
int QDateTimeParser::sectionMaxSize(int index) const+ −
{+ −
const SectionNode &sn = sectionNode(index);+ −
return sectionMaxSize(sn.type, sn.count);+ −
}+ −
+ −
/*!+ −
\internal+ −
+ −
Returns the text of section \a s. This function operates on the+ −
arg text rather than edit->text().+ −
*/+ −
+ −
+ −
QString QDateTimeParser::sectionText(const QString &text, int sectionIndex, int index) const+ −
{+ −
const SectionNode &sn = sectionNode(sectionIndex);+ −
switch (sn.type) {+ −
case NoSectionIndex:+ −
case FirstSectionIndex:+ −
case LastSectionIndex:+ −
return QString();+ −
default: break;+ −
}+ −
+ −
return text.mid(index, sectionSize(sectionIndex));+ −
}+ −
+ −
QString QDateTimeParser::sectionText(int sectionIndex) const+ −
{+ −
const SectionNode &sn = sectionNode(sectionIndex);+ −
switch (sn.type) {+ −
case NoSectionIndex:+ −
case FirstSectionIndex:+ −
case LastSectionIndex:+ −
return QString();+ −
default: break;+ −
}+ −
+ −
return displayText().mid(sn.pos, sectionSize(sectionIndex));+ −
}+ −
+ −
+ −
#ifndef QT_NO_TEXTDATE+ −
/*!+ −
\internal:skipToNextSection+ −
+ −
Parses the part of \a text that corresponds to \a s and returns+ −
the value of that field. Sets *stateptr to the right state if+ −
stateptr != 0.+ −
*/+ −
+ −
int QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex,+ −
QString &text, int &cursorPosition, int index,+ −
State &state, int *usedptr) const+ −
{+ −
state = Invalid;+ −
int num = 0;+ −
const SectionNode &sn = sectionNode(sectionIndex);+ −
if ((sn.type & Internal) == Internal) {+ −
qWarning("QDateTimeParser::parseSection Internal error (%s %d)",+ −
qPrintable(sectionName(sn.type)), sectionIndex);+ −
return -1;+ −
}+ −
+ −
const int sectionmaxsize = sectionMaxSize(sectionIndex);+ −
QString sectiontext = text.mid(index, sectionmaxsize);+ −
int sectiontextSize = sectiontext.size();+ −
+ −
QDTPDEBUG << "sectionValue for" << sectionName(sn.type)+ −
<< "with text" << text << "and st" << sectiontext+ −
<< text.mid(index, sectionmaxsize)+ −
<< index;+ −
+ −
int used = 0;+ −
switch (sn.type) {+ −
case AmPmSection: {+ −
const int ampm = findAmPm(sectiontext, sectionIndex, &used);+ −
switch (ampm) {+ −
case AM: // sectiontext == AM+ −
case PM: // sectiontext == PM+ −
num = ampm;+ −
state = Acceptable;+ −
break;+ −
case PossibleAM: // sectiontext => AM+ −
case PossiblePM: // sectiontext => PM+ −
num = ampm - 2;+ −
state = Intermediate;+ −
break;+ −
case PossibleBoth: // sectiontext => AM|PM+ −
num = 0;+ −
state = Intermediate;+ −
break;+ −
case Neither:+ −
state = Invalid;+ −
QDTPDEBUG << "invalid because findAmPm(" << sectiontext << ") returned -1";+ −
break;+ −
default:+ −
QDTPDEBUGN("This should never happen (findAmPm returned %d)", ampm);+ −
break;+ −
}+ −
if (state != Invalid) {+ −
QString str = text;+ −
text.replace(index, used, sectiontext.left(used));+ −
}+ −
break; }+ −
case MonthSection:+ −
case DayOfWeekSection:+ −
if (sn.count >= 3) {+ −
if (sn.type == MonthSection) {+ −
int min = 1;+ −
const QDate minDate = getMinimum().date();+ −
if (currentValue.date().year() == minDate.year()) {+ −
min = minDate.month();+ −
}+ −
num = findMonth(sectiontext.toLower(), min, sectionIndex, §iontext, &used);+ −
} else {+ −
num = findDay(sectiontext.toLower(), 1, sectionIndex, §iontext, &used);+ −
}+ −
+ −
if (num != -1) {+ −
state = (used == sectiontext.size() ? Acceptable : Intermediate);+ −
QString str = text;+ −
text.replace(index, used, sectiontext.left(used));+ −
} else {+ −
state = Intermediate;+ −
}+ −
break; }+ −
// fall through+ −
case DaySection:+ −
case YearSection:+ −
case YearSection2Digits:+ −
case Hour12Section:+ −
case Hour24Section:+ −
case MinuteSection:+ −
case SecondSection:+ −
case MSecSection: {+ −
if (sectiontextSize == 0) {+ −
num = 0;+ −
used = 0;+ −
state = Intermediate;+ −
} else {+ −
const int absMax = absoluteMax(sectionIndex);+ −
QLocale loc;+ −
bool ok = true;+ −
int last = -1;+ −
used = -1;+ −
+ −
QString digitsStr(sectiontext);+ −
for (int i = 0; i < sectiontextSize; ++i) {+ −
if (digitsStr.at(i).isSpace()) {+ −
sectiontextSize = i;+ −
break;+ −
}+ −
}+ −
+ −
const int max = qMin(sectionmaxsize, sectiontextSize);+ −
for (int digits = max; digits >= 1; --digits) {+ −
digitsStr.truncate(digits);+ −
int tmp = (int)loc.toUInt(digitsStr, &ok, 10);+ −
if (ok && sn.type == Hour12Section) {+ −
if (tmp > 12) {+ −
tmp = -1;+ −
ok = false;+ −
} else if (tmp == 12) {+ −
tmp = 0;+ −
}+ −
}+ −
if (ok && tmp <= absMax) {+ −
QDTPDEBUG << sectiontext.left(digits) << tmp << digits;+ −
last = tmp;+ −
used = digits;+ −
break;+ −
}+ −
}+ −
+ −
if (last == -1) {+ −
QChar first(sectiontext.at(0));+ −
if (separators.at(sectionIndex + 1).startsWith(first)) {+ −
used = 0;+ −
state = Intermediate;+ −
} else {+ −
state = Invalid;+ −
QDTPDEBUG << "invalid because" << sectiontext << "can't become a uint" << last << ok;+ −
}+ −
} else {+ −
num += last;+ −
const FieldInfo fi = fieldInfo(sectionIndex);+ −
const bool done = (used == sectionmaxsize);+ −
if (!done && fi & Fraction) { // typing 2 in a zzz field should be .200, not .002+ −
for (int i=used; i<sectionmaxsize; ++i) {+ −
num *= 10;+ −
}+ −
}+ −
const int absMin = absoluteMin(sectionIndex);+ −
if (num < absMin) {+ −
state = done ? Invalid : Intermediate;+ −
if (done)+ −
QDTPDEBUG << "invalid because" << num << "is less than absoluteMin" << absMin;+ −
} else if (num > absMax) {+ −
state = Intermediate;+ −
} else if (!done && (fi & (FixedWidth|Numeric)) == (FixedWidth|Numeric)) {+ −
if (skipToNextSection(sectionIndex, currentValue, digitsStr)) {+ −
state = Acceptable;+ −
const int missingZeroes = sectionmaxsize - digitsStr.size();+ −
text.insert(index, QString().fill(QLatin1Char('0'), missingZeroes));+ −
used = sectionmaxsize;+ −
cursorPosition += missingZeroes;+ −
} else {+ −
state = Intermediate;;+ −
}+ −
} else {+ −
state = Acceptable;+ −
}+ −
}+ −
}+ −
break; }+ −
default:+ −
qWarning("QDateTimeParser::parseSection Internal error (%s %d)",+ −
qPrintable(sectionName(sn.type)), sectionIndex);+ −
return -1;+ −
}+ −
+ −
if (usedptr)+ −
*usedptr = used;+ −
+ −
return (state != Invalid ? num : -1);+ −
}+ −
#endif // QT_NO_TEXTDATE+ −
+ −
#ifndef QT_NO_DATESTRING+ −
/*!+ −
\internal+ −
*/+ −
+ −
QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPosition,+ −
const QDateTime ¤tValue, bool fixup) const+ −
{+ −
const QDateTime minimum = getMinimum();+ −
const QDateTime maximum = getMaximum();+ −
+ −
State state = Acceptable;+ −
+ −
QDateTime newCurrentValue;+ −
int pos = 0;+ −
bool conflicts = false;+ −
const int sectionNodesCount = sectionNodes.size();+ −
+ −
QDTPDEBUG << "parse" << input;+ −
{+ −
int year, month, day, hour12, hour, minute, second, msec, ampm, dayofweek, year2digits;+ −
getDateFromJulianDay(currentValue.date().toJulianDay(), &year, &month, &day);+ −
year2digits = year % 100;+ −
hour = currentValue.time().hour();+ −
hour12 = -1;+ −
minute = currentValue.time().minute();+ −
second = currentValue.time().second();+ −
msec = currentValue.time().msec();+ −
dayofweek = currentValue.date().dayOfWeek();+ −
+ −
ampm = -1;+ −
Sections isSet = NoSection;+ −
int num;+ −
State tmpstate;+ −
+ −
for (int index=0; state != Invalid && index<sectionNodesCount; ++index) {+ −
if (QStringRef(&input, pos, separators.at(index).size()) != separators.at(index)) {+ −
QDTPDEBUG << "invalid because" << input.mid(pos, separators.at(index).size())+ −
<< "!=" << separators.at(index)+ −
<< index << pos << currentSectionIndex;+ −
state = Invalid;+ −
goto end;+ −
}+ −
pos += separators.at(index).size();+ −
sectionNodes[index].pos = pos;+ −
int *current = 0;+ −
const SectionNode sn = sectionNodes.at(index);+ −
int used;+ −
+ −
num = parseSection(currentValue, index, input, cursorPosition, pos, tmpstate, &used);+ −
QDTPDEBUG << "sectionValue" << sectionName(sectionType(index)) << input+ −
<< "pos" << pos << "used" << used << stateName(tmpstate);+ −
if (fixup && tmpstate == Intermediate && used < sn.count) {+ −
const FieldInfo fi = fieldInfo(index);+ −
if ((fi & (Numeric|FixedWidth)) == (Numeric|FixedWidth)) {+ −
const QString newText = QString::fromLatin1("%1").arg(num, sn.count, 10, QLatin1Char('0'));+ −
input.replace(pos, used, newText);+ −
used = sn.count;+ −
}+ −
}+ −
pos += qMax(0, used);+ −
+ −
state = qMin<State>(state, tmpstate);+ −
if (state == Intermediate && context == FromString) {+ −
state = Invalid;+ −
break;+ −
}+ −
+ −
QDTPDEBUG << index << sectionName(sectionType(index)) << "is set to"+ −
<< pos << "state is" << stateName(state);+ −
+ −
+ −
if (state != Invalid) {+ −
switch (sn.type) {+ −
case Hour24Section: current = &hour; break;+ −
case Hour12Section: current = &hour12; break;+ −
case MinuteSection: current = &minute; break;+ −
case SecondSection: current = &second; break;+ −
case MSecSection: current = &msec; break;+ −
case YearSection: current = &year; break;+ −
case YearSection2Digits: current = &year2digits; break;+ −
case MonthSection: current = &month; break;+ −
case DayOfWeekSection: current = &dayofweek; break;+ −
case DaySection: current = &day; num = qMax<int>(1, num); break;+ −
case AmPmSection: current = &m; break;+ −
default:+ −
qWarning("QDateTimeParser::parse Internal error (%s)",+ −
qPrintable(sectionName(sn.type)));+ −
break;+ −
}+ −
if (!current) {+ −
qWarning("QDateTimeParser::parse Internal error 2");+ −
return StateNode();+ −
}+ −
if (isSet & sn.type && *current != num) {+ −
QDTPDEBUG << "CONFLICT " << sectionName(sn.type) << *current << num;+ −
conflicts = true;+ −
if (index != currentSectionIndex || num == -1) {+ −
continue;+ −
}+ −
}+ −
if (num != -1)+ −
*current = num;+ −
isSet |= sn.type;+ −
}+ −
}+ −
+ −
if (state != Invalid && QStringRef(&input, pos, input.size() - pos) != separators.last()) {+ −
QDTPDEBUG << "invalid because" << input.mid(pos)+ −
<< "!=" << separators.last() << pos;+ −
state = Invalid;+ −
}+ −
+ −
if (state != Invalid) {+ −
if (parserType != QVariant::Time) {+ −
if (year % 100 != year2digits) {+ −
switch (isSet & (YearSection2Digits|YearSection)) {+ −
case YearSection2Digits:+ −
year = (year / 100) * 100;+ −
year += year2digits;+ −
break;+ −
case ((uint)YearSection2Digits|(uint)YearSection): {+ −
conflicts = true;+ −
const SectionNode &sn = sectionNode(currentSectionIndex);+ −
if (sn.type == YearSection2Digits) {+ −
year = (year / 100) * 100;+ −
year += year2digits;+ −
}+ −
break; }+ −
default:+ −
break;+ −
}+ −
}+ −
+ −
const QDate date(year, month, day);+ −
const int diff = dayofweek - date.dayOfWeek();+ −
if (diff != 0 && state == Acceptable && isSet & DayOfWeekSection) {+ −
conflicts = isSet & DaySection;+ −
const SectionNode &sn = sectionNode(currentSectionIndex);+ −
if (sn.type == DayOfWeekSection || currentSectionIndex == -1) {+ −
// dayofweek should be preferred+ −
day += diff;+ −
if (day <= 0) {+ −
day += 7;+ −
} else if (day > date.daysInMonth()) {+ −
day -= 7;+ −
}+ −
QDTPDEBUG << year << month << day << dayofweek+ −
<< diff << QDate(year, month, day).dayOfWeek();+ −
}+ −
}+ −
bool needfixday = false;+ −
if (sectionType(currentSectionIndex) & (DaySection|DayOfWeekSection)) {+ −
cachedDay = day;+ −
} else if (cachedDay > day) {+ −
day = cachedDay;+ −
needfixday = true;+ −
}+ −
+ −
if (!QDate::isValid(year, month, day)) {+ −
if (day < 32) {+ −
cachedDay = day;+ −
}+ −
if (day > 28 && QDate::isValid(year, month, 1)) {+ −
needfixday = true;+ −
}+ −
}+ −
if (needfixday) {+ −
if (context == FromString) {+ −
state = Invalid;+ −
goto end;+ −
}+ −
if (state == Acceptable && fixday) {+ −
day = qMin<int>(day, QDate(year, month, 1).daysInMonth());+ −
+ −
const QLocale loc = locale();+ −
for (int i=0; i<sectionNodesCount; ++i) {+ −
if (sectionType(i) & (DaySection|DayOfWeekSection)) {+ −
input.replace(sectionPos(i), sectionSize(i), loc.toString(day));+ −
}+ −
}+ −
} else {+ −
state = qMin(Intermediate, state);+ −
}+ −
}+ −
}+ −
+ −
if (parserType != QVariant::Date) {+ −
if (isSet & Hour12Section) {+ −
const bool hasHour = isSet & Hour24Section;+ −
if (ampm == -1) {+ −
if (hasHour) {+ −
ampm = (hour < 12 ? 0 : 1);+ −
} else {+ −
ampm = 0; // no way to tell if this is am or pm so I assume am+ −
}+ −
}+ −
hour12 = (ampm == 0 ? hour12 % 12 : (hour12 % 12) + 12);+ −
if (!hasHour) {+ −
hour = hour12;+ −
} else if (hour != hour12) {+ −
conflicts = true;+ −
}+ −
} else if (ampm != -1) {+ −
if (!(isSet & (Hour24Section))) {+ −
hour = (12 * ampm); // special case. Only ap section+ −
} else if ((ampm == 0) != (hour < 12)) {+ −
conflicts = true;+ −
}+ −
}+ −
+ −
}+ −
+ −
newCurrentValue = QDateTime(QDate(year, month, day), QTime(hour, minute, second, msec), spec);+ −
QDTPDEBUG << year << month << day << hour << minute << second << msec;+ −
}+ −
QDTPDEBUGN("'%s' => '%s'(%s)", input.toLatin1().constData(),+ −
newCurrentValue.toString(QLatin1String("yyyy/MM/dd hh:mm:ss.zzz")).toLatin1().constData(),+ −
stateName(state).toLatin1().constData());+ −
}+ −
end:+ −
if (newCurrentValue.isValid()) {+ −
if (context != FromString && state != Invalid && newCurrentValue < minimum) {+ −
const QLatin1Char space(' ');+ −
if (newCurrentValue >= minimum)+ −
qWarning("QDateTimeParser::parse Internal error 3 (%s %s)",+ −
qPrintable(newCurrentValue.toString()), qPrintable(minimum.toString()));+ −
+ −
bool done = false;+ −
state = Invalid;+ −
for (int i=0; i<sectionNodesCount && !done; ++i) {+ −
const SectionNode &sn = sectionNodes.at(i);+ −
QString t = sectionText(input, i, sn.pos).toLower();+ −
if ((t.size() < sectionMaxSize(i) && (((int)fieldInfo(i) & (FixedWidth|Numeric)) != Numeric))+ −
|| t.contains(space)) {+ −
switch (sn.type) {+ −
case AmPmSection:+ −
switch (findAmPm(t, i)) {+ −
case AM:+ −
case PM:+ −
state = Acceptable;+ −
done = true;+ −
break;+ −
case Neither:+ −
state = Invalid;+ −
done = true;+ −
break;+ −
case PossibleAM:+ −
case PossiblePM:+ −
case PossibleBoth: {+ −
const QDateTime copy(newCurrentValue.addSecs(12 * 60 * 60));+ −
if (copy >= minimum && copy <= maximum) {+ −
state = Intermediate;+ −
done = true;+ −
}+ −
break; }+ −
}+ −
case MonthSection:+ −
if (sn.count >= 3) {+ −
int tmp = newCurrentValue.date().month();+ −
// I know the first possible month makes the date too early+ −
while ((tmp = findMonth(t, tmp + 1, i)) != -1) {+ −
const QDateTime copy(newCurrentValue.addMonths(tmp - newCurrentValue.date().month()));+ −
if (copy >= minimum && copy <= maximum)+ −
break; // break out of while+ −
}+ −
if (tmp == -1) {+ −
break;+ −
}+ −
state = Intermediate;+ −
done = true;+ −
break;+ −
}+ −
// fallthrough+ −
default: {+ −
int toMin;+ −
int toMax;+ −
+ −
if (sn.type & TimeSectionMask) {+ −
if (newCurrentValue.daysTo(minimum) != 0) {+ −
break;+ −
}+ −
toMin = newCurrentValue.time().msecsTo(minimum.time());+ −
if (newCurrentValue.daysTo(maximum) > 0) {+ −
toMax = -1; // can't get to max+ −
} else {+ −
toMax = newCurrentValue.time().msecsTo(maximum.time());+ −
}+ −
} else {+ −
toMin = newCurrentValue.daysTo(minimum);+ −
toMax = newCurrentValue.daysTo(maximum);+ −
}+ −
const int maxChange = QDateTimeParser::maxChange(i);+ −
if (toMin > maxChange) {+ −
QDTPDEBUG << "invalid because toMin > maxChange" << toMin+ −
<< maxChange << t << newCurrentValue << minimum;+ −
state = Invalid;+ −
done = true;+ −
break;+ −
} else if (toMax > maxChange) {+ −
toMax = -1; // can't get to max+ −
}+ −
+ −
const int min = getDigit(minimum, i);+ −
if (min == -1) {+ −
qWarning("QDateTimeParser::parse Internal error 4 (%s)",+ −
qPrintable(sectionName(sn.type)));+ −
state = Invalid;+ −
done = true;+ −
break;+ −
}+ −
+ −
int max = toMax != -1 ? getDigit(maximum, i) : absoluteMax(i, newCurrentValue);+ −
int pos = cursorPosition - sn.pos;+ −
if (pos < 0 || pos >= t.size())+ −
pos = -1;+ −
if (!potentialValue(t.simplified(), min, max, i, newCurrentValue, pos)) {+ −
QDTPDEBUG << "invalid because potentialValue(" << t.simplified() << min << max+ −
<< sectionName(sn.type) << "returned" << toMax << toMin << pos;+ −
state = Invalid;+ −
done = true;+ −
break;+ −
}+ −
state = Intermediate;+ −
done = true;+ −
break; }+ −
}+ −
}+ −
}+ −
} else {+ −
if (context == FromString) {+ −
// optimization+ −
Q_ASSERT(getMaximum().date().toJulianDay() == 4642999);+ −
if (newCurrentValue.date().toJulianDay() > 4642999)+ −
state = Invalid;+ −
} else {+ −
if (newCurrentValue > getMaximum())+ −
state = Invalid;+ −
}+ −
+ −
QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << getMinimum() << getMaximum();+ −
}+ −
}+ −
StateNode node;+ −
node.input = input;+ −
node.state = state;+ −
node.conflicts = conflicts;+ −
node.value = newCurrentValue.toTimeSpec(spec);+ −
text = input;+ −
return node;+ −
}+ −
#endif // QT_NO_DATESTRING+ −
+ −
#ifndef QT_NO_TEXTDATE+ −
/*!+ −
\internal finds the first possible monthname that \a str1 can+ −
match. Starting from \a index; str should already by lowered+ −
*/+ −
+ −
int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionIndex,+ −
QString *usedMonth, int *used) const+ −
{+ −
int bestMatch = -1;+ −
int bestCount = 0;+ −
if (!str1.isEmpty()) {+ −
const SectionNode &sn = sectionNode(sectionIndex);+ −
if (sn.type != MonthSection) {+ −
qWarning("QDateTimeParser::findMonth Internal error");+ −
return -1;+ −
}+ −
+ −
QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat;+ −
QLocale l = locale();+ −
+ −
for (int month=startMonth; month<=12; ++month) {+ −
QString str2 = l.monthName(month, type).toLower();+ −
+ −
if (str1.startsWith(str2)) {+ −
if (used) {+ −
QDTPDEBUG << "used is set to" << str2.size();+ −
*used = str2.size();+ −
}+ −
if (usedMonth)+ −
*usedMonth = l.monthName(month, type);+ −
+ −
return month;+ −
}+ −
if (context == FromString)+ −
continue;+ −
+ −
const int limit = qMin(str1.size(), str2.size());+ −
+ −
QDTPDEBUG << "limit is" << limit << str1 << str2;+ −
bool equal = true;+ −
for (int i=0; i<limit; ++i) {+ −
if (str1.at(i) != str2.at(i)) {+ −
equal = false;+ −
if (i > bestCount) {+ −
bestCount = i;+ −
bestMatch = month;+ −
}+ −
break;+ −
}+ −
}+ −
if (equal) {+ −
if (used)+ −
*used = limit;+ −
if (usedMonth)+ −
*usedMonth = l.monthName(month, type);+ −
return month;+ −
}+ −
}+ −
if (usedMonth && bestMatch != -1)+ −
*usedMonth = l.monthName(bestMatch, type);+ −
}+ −
if (used) {+ −
QDTPDEBUG << "used is set to" << bestCount;+ −
*used = bestCount;+ −
}+ −
return bestMatch;+ −
}+ −
+ −
int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex, QString *usedDay, int *used) const+ −
{+ −
int bestMatch = -1;+ −
int bestCount = 0;+ −
if (!str1.isEmpty()) {+ −
const SectionNode &sn = sectionNode(sectionIndex);+ −
if (!(sn.type & (DaySection|DayOfWeekSection))) {+ −
qWarning("QDateTimeParser::findDay Internal error");+ −
return -1;+ −
}+ −
const QLocale l = locale();+ −
for (int day=startDay; day<=7; ++day) {+ −
const QString str2 = l.dayName(day, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);+ −
+ −
if (str1.startsWith(str2.toLower())) {+ −
if (used)+ −
*used = str2.size();+ −
if (usedDay) {+ −
*usedDay = str2;+ −
}+ −
return day;+ −
}+ −
if (context == FromString)+ −
continue;+ −
+ −
const int limit = qMin(str1.size(), str2.size());+ −
bool found = true;+ −
for (int i=0; i<limit; ++i) {+ −
if (str1.at(i) != str2.at(i) && !str1.at(i).isSpace()) {+ −
if (i > bestCount) {+ −
bestCount = i;+ −
bestMatch = day;+ −
}+ −
found = false;+ −
break;+ −
}+ −
+ −
}+ −
if (found) {+ −
if (used)+ −
*used = limit;+ −
if (usedDay)+ −
*usedDay = str2;+ −
+ −
return day;+ −
}+ −
}+ −
if (usedDay && bestMatch != -1) {+ −
*usedDay = l.dayName(bestMatch, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);+ −
}+ −
}+ −
if (used)+ −
*used = bestCount;+ −
+ −
return bestMatch;+ −
}+ −
#endif // QT_NO_TEXTDATE+ −
+ −
/*!+ −
\internal+ −
+ −
returns+ −
0 if str == QDateTimeEdit::tr("AM")+ −
1 if str == QDateTimeEdit::tr("PM")+ −
2 if str can become QDateTimeEdit::tr("AM")+ −
3 if str can become QDateTimeEdit::tr("PM")+ −
4 if str can become QDateTimeEdit::tr("PM") and can become QDateTimeEdit::tr("AM")+ −
-1 can't become anything sensible+ −
+ −
*/+ −
+ −
int QDateTimeParser::findAmPm(QString &str, int index, int *used) const+ −
{+ −
const SectionNode &s = sectionNode(index);+ −
if (s.type != AmPmSection) {+ −
qWarning("QDateTimeParser::findAmPm Internal error");+ −
return -1;+ −
}+ −
if (used)+ −
*used = str.size();+ −
if (str.trimmed().isEmpty()) {+ −
return PossibleBoth;+ −
}+ −
const QLatin1Char space(' ');+ −
int size = sectionMaxSize(index);+ −
+ −
enum {+ −
amindex = 0,+ −
pmindex = 1+ −
};+ −
QString ampm[2];+ −
ampm[amindex] = getAmPmText(AmText, s.count == 1 ? UpperCase : LowerCase);+ −
ampm[pmindex] = getAmPmText(PmText, s.count == 1 ? UpperCase : LowerCase);+ −
for (int i=0; i<2; ++i)+ −
ampm[i].truncate(size);+ −
+ −
QDTPDEBUG << "findAmPm" << str << ampm[0] << ampm[1];+ −
+ −
if (str.indexOf(ampm[amindex], 0, Qt::CaseInsensitive) == 0) {+ −
str = ampm[amindex];+ −
return AM;+ −
} else if (str.indexOf(ampm[pmindex], 0, Qt::CaseInsensitive) == 0) {+ −
str = ampm[pmindex];+ −
return PM;+ −
} else if (context == FromString || (str.count(space) == 0 && str.size() >= size)) {+ −
return Neither;+ −
}+ −
size = qMin(size, str.size());+ −
+ −
bool broken[2] = {false, false};+ −
for (int i=0; i<size; ++i) {+ −
if (str.at(i) != space) {+ −
for (int j=0; j<2; ++j) {+ −
if (!broken[j]) {+ −
int index = ampm[j].indexOf(str.at(i));+ −
QDTPDEBUG << "looking for" << str.at(i)+ −
<< "in" << ampm[j] << "and got" << index;+ −
if (index == -1) {+ −
if (str.at(i).category() == QChar::Letter_Uppercase) {+ −
index = ampm[j].indexOf(str.at(i).toLower());+ −
QDTPDEBUG << "trying with" << str.at(i).toLower()+ −
<< "in" << ampm[j] << "and got" << index;+ −
} else if (str.at(i).category() == QChar::Letter_Lowercase) {+ −
index = ampm[j].indexOf(str.at(i).toUpper());+ −
QDTPDEBUG << "trying with" << str.at(i).toUpper()+ −
<< "in" << ampm[j] << "and got" << index;+ −
}+ −
if (index == -1) {+ −
broken[j] = true;+ −
if (broken[amindex] && broken[pmindex]) {+ −
QDTPDEBUG << str << "didn't make it";+ −
return Neither;+ −
}+ −
continue;+ −
} else {+ −
str[i] = ampm[j].at(index); // fix case+ −
}+ −
}+ −
ampm[j].remove(index, 1);+ −
}+ −
}+ −
}+ −
}+ −
if (!broken[pmindex] && !broken[amindex])+ −
return PossibleBoth;+ −
return (!broken[amindex] ? PossibleAM : PossiblePM);+ −
}+ −
+ −
/*!+ −
\internal+ −
Max number of units that can be changed by this section.+ −
*/+ −
+ −
int QDateTimeParser::maxChange(int index) const+ −
{+ −
const SectionNode &sn = sectionNode(index);+ −
switch (sn.type) {+ −
// Time. unit is msec+ −
case MSecSection: return 999;+ −
case SecondSection: return 59 * 1000;+ −
case MinuteSection: return 59 * 60 * 1000;+ −
case Hour24Section: case Hour12Section: return 59 * 60 * 60 * 1000;+ −
+ −
// Date. unit is day+ −
case DayOfWeekSection: return 7;+ −
case DaySection: return 30;+ −
case MonthSection: return 365 - 31;+ −
case YearSection: return 9999 * 365;+ −
case YearSection2Digits: return 100 * 365;+ −
default:+ −
qWarning("QDateTimeParser::maxChange() Internal error (%s)",+ −
qPrintable(sectionName(sectionType(index))));+ −
}+ −
+ −
return -1;+ −
}+ −
+ −
QDateTimeParser::FieldInfo QDateTimeParser::fieldInfo(int index) const+ −
{+ −
FieldInfo ret = 0;+ −
const SectionNode &sn = sectionNode(index);+ −
const Section s = sn.type;+ −
switch (s) {+ −
case MSecSection:+ −
ret |= Fraction;+ −
// fallthrough+ −
case SecondSection:+ −
case MinuteSection:+ −
case Hour24Section:+ −
case Hour12Section:+ −
case YearSection:+ −
case YearSection2Digits:+ −
ret |= Numeric;+ −
if (s != YearSection) {+ −
ret |= AllowPartial;+ −
}+ −
if (sn.count != 1) {+ −
ret |= FixedWidth;+ −
}+ −
break;+ −
case MonthSection:+ −
case DaySection:+ −
switch (sn.count) {+ −
case 2:+ −
ret |= FixedWidth;+ −
// fallthrough+ −
case 1:+ −
ret |= (Numeric|AllowPartial);+ −
break;+ −
}+ −
break;+ −
case DayOfWeekSection:+ −
if (sn.count == 3)+ −
ret |= FixedWidth;+ −
break;+ −
case AmPmSection:+ −
ret |= FixedWidth;+ −
break;+ −
default:+ −
qWarning("QDateTimeParser::fieldInfo Internal error 2 (%d %s %d)",+ −
index, qPrintable(sectionName(sn.type)), sn.count);+ −
break;+ −
}+ −
return ret;+ −
}+ −
+ −
/*!+ −
\internal Get a number that str can become which is between min+ −
and max or -1 if this is not possible.+ −
*/+ −
+ −
+ −
QString QDateTimeParser::sectionFormat(int index) const+ −
{+ −
const SectionNode &sn = sectionNode(index);+ −
return sectionFormat(sn.type, sn.count);+ −
}+ −
+ −
QString QDateTimeParser::sectionFormat(Section s, int count) const+ −
{+ −
QChar fillChar;+ −
switch (s) {+ −
case AmPmSection: return count == 1 ? QLatin1String("AP") : QLatin1String("ap");+ −
case MSecSection: fillChar = QLatin1Char('z'); break;+ −
case SecondSection: fillChar = QLatin1Char('s'); break;+ −
case MinuteSection: fillChar = QLatin1Char('m'); break;+ −
case Hour24Section: fillChar = QLatin1Char('H'); break;+ −
case Hour12Section: fillChar = QLatin1Char('h'); break;+ −
case DayOfWeekSection:+ −
case DaySection: fillChar = QLatin1Char('d'); break;+ −
case MonthSection: fillChar = QLatin1Char('M'); break;+ −
case YearSection2Digits:+ −
case YearSection: fillChar = QLatin1Char('y'); break;+ −
default:+ −
qWarning("QDateTimeParser::sectionFormat Internal error (%s)",+ −
qPrintable(sectionName(s)));+ −
return QString();+ −
}+ −
if (fillChar.isNull()) {+ −
qWarning("QDateTimeParser::sectionFormat Internal error 2");+ −
return QString();+ −
}+ −
+ −
QString str;+ −
str.fill(fillChar, count);+ −
return str;+ −
}+ −
+ −
+ −
/*! \internal Returns true if str can be modified to represent a+ −
number that is within min and max.+ −
*/+ −
+ −
bool QDateTimeParser::potentialValue(const QString &str, int min, int max, int index,+ −
const QDateTime ¤tValue, int insert) const+ −
{+ −
if (str.isEmpty()) {+ −
return true;+ −
}+ −
const int size = sectionMaxSize(index);+ −
int val = (int)locale().toUInt(str);+ −
const SectionNode &sn = sectionNode(index);+ −
if (sn.type == YearSection2Digits) {+ −
val += currentValue.date().year() - (currentValue.date().year() % 100);+ −
}+ −
if (val >= min && val <= max && str.size() == size) {+ −
return true;+ −
} else if (val > max) {+ −
return false;+ −
} else if (str.size() == size && val < min) {+ −
return false;+ −
}+ −
+ −
const int len = size - str.size();+ −
for (int i=0; i<len; ++i) {+ −
for (int j=0; j<10; ++j) {+ −
if (potentialValue(str + QLatin1Char('0' + j), min, max, index, currentValue, insert)) {+ −
return true;+ −
} else if (insert >= 0) {+ −
QString tmp = str;+ −
tmp.insert(insert, QLatin1Char('0' + j));+ −
if (potentialValue(tmp, min, max, index, currentValue, insert))+ −
return true;+ −
}+ −
}+ −
}+ −
+ −
return false;+ −
}+ −
+ −
bool QDateTimeParser::skipToNextSection(int index, const QDateTime ¤t, const QString &text) const+ −
{+ −
Q_ASSERT(current >= getMinimum() && current <= getMaximum());+ −
+ −
const SectionNode &node = sectionNode(index);+ −
Q_ASSERT(text.size() < sectionMaxSize(index));+ −
+ −
const QDateTime maximum = getMaximum();+ −
const QDateTime minimum = getMinimum();+ −
QDateTime tmp = current;+ −
int min = absoluteMin(index);+ −
setDigit(tmp, index, min);+ −
if (tmp < minimum) {+ −
min = getDigit(minimum, index);+ −
}+ −
+ −
int max = absoluteMax(index, current);+ −
setDigit(tmp, index, max);+ −
if (tmp > maximum) {+ −
max = getDigit(maximum, index);+ −
}+ −
int pos = cursorPosition() - node.pos;+ −
if (pos < 0 || pos >= text.size())+ −
pos = -1;+ −
+ −
const bool potential = potentialValue(text, min, max, index, current, pos);+ −
return !potential;+ −
+ −
/* If the value potentially can become another valid entry we+ −
* don't want to skip to the next. E.g. In a M field (month+ −
* without leading 0 if you type 1 we don't want to autoskip but+ −
* if you type 3 we do+ −
*/+ −
}+ −
+ −
/*!+ −
\internal+ −
For debugging. Returns the name of the section \a s.+ −
*/+ −
+ −
QString QDateTimeParser::sectionName(int s) const+ −
{+ −
switch (s) {+ −
case QDateTimeParser::AmPmSection: return QLatin1String("AmPmSection");+ −
case QDateTimeParser::DaySection: return QLatin1String("DaySection");+ −
case QDateTimeParser::DayOfWeekSection: return QLatin1String("DayOfWeekSection");+ −
case QDateTimeParser::Hour24Section: return QLatin1String("Hour24Section");+ −
case QDateTimeParser::Hour12Section: return QLatin1String("Hour12Section");+ −
case QDateTimeParser::MSecSection: return QLatin1String("MSecSection");+ −
case QDateTimeParser::MinuteSection: return QLatin1String("MinuteSection");+ −
case QDateTimeParser::MonthSection: return QLatin1String("MonthSection");+ −
case QDateTimeParser::SecondSection: return QLatin1String("SecondSection");+ −
case QDateTimeParser::YearSection: return QLatin1String("YearSection");+ −
case QDateTimeParser::YearSection2Digits: return QLatin1String("YearSection2Digits");+ −
case QDateTimeParser::NoSection: return QLatin1String("NoSection");+ −
case QDateTimeParser::FirstSection: return QLatin1String("FirstSection");+ −
case QDateTimeParser::LastSection: return QLatin1String("LastSection");+ −
default: return QLatin1String("Unknown section ") + QString::number(s);+ −
}+ −
}+ −
+ −
/*!+ −
\internal+ −
For debugging. Returns the name of the state \a s.+ −
*/+ −
+ −
QString QDateTimeParser::stateName(int s) const+ −
{+ −
switch (s) {+ −
case Invalid: return QLatin1String("Invalid");+ −
case Intermediate: return QLatin1String("Intermediate");+ −
case Acceptable: return QLatin1String("Acceptable");+ −
default: return QLatin1String("Unknown state ") + QString::number(s);+ −
}+ −
}+ −
+ −
#ifndef QT_NO_DATESTRING+ −
bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) const+ −
{+ −
QDateTime val(QDate(1900, 1, 1), QDATETIMEEDIT_TIME_MIN);+ −
QString text = t;+ −
int copy = -1;+ −
const StateNode tmp = parse(text, copy, val, false);+ −
if (tmp.state != Acceptable || tmp.conflicts) {+ −
return false;+ −
}+ −
if (time) {+ −
const QTime t = tmp.value.time();+ −
if (!t.isValid()) {+ −
return false;+ −
}+ −
*time = t;+ −
}+ −
+ −
if (date) {+ −
const QDate d = tmp.value.date();+ −
if (!d.isValid()) {+ −
return false;+ −
}+ −
*date = d;+ −
}+ −
return true;+ −
}+ −
#endif // QT_NO_DATESTRING+ −
+ −
QDateTime QDateTimeParser::getMinimum() const+ −
{+ −
return QDateTime(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN, spec);+ −
}+ −
+ −
QDateTime QDateTimeParser::getMaximum() const+ −
{+ −
return QDateTime(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX, spec);+ −
}+ −
+ −
QString QDateTimeParser::getAmPmText(AmPm ap, Case cs) const+ −
{+ −
if (ap == AmText) {+ −
return (cs == UpperCase ? QLatin1String("AM") : QLatin1String("am"));+ −
} else {+ −
return (cs == UpperCase ? QLatin1String("PM") : QLatin1String("pm"));+ −
}+ −
}+ −
+ −
/*+ −
\internal+ −
+ −
I give arg2 preference because arg1 is always a QDateTime.+ −
*/+ −
+ −
bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::SectionNode &s2)+ −
{+ −
return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count);+ −
}+ −
+ −
+ −
#endif // QT_BOOTSTRAPPED+ −
+ −
QT_END_NAMESPACE+ −