📄 qdatetime.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtCore module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#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)#include <windows.h>#endif#ifndef Q_WS_WIN#include <locale.h>#endif#include <time.h>//#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>extern QString qt_mac_from_pascal_string(const Str255); // qglobal.cpp#endifenum { 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};static inline QDate strictDate(int y, int m, int d){ QDate result; result.setDate(y, m, d); return result;}static inline QDate fixedDate(int y, int m, int d){ QDate result(strictDate(y, m, 1)); result.setDate(y, m, qMin(d, result.daysInMonth())); return result;}static uint julianDayFromDate(int year, int month, int day){ if (year < 0) ++year; if (year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15)))) { // 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; } 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; } *year = y; *month = m; *day = d;}static const char monthDays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };#ifndef QT_NO_TEXTDATEstatic const char * const qt_shortMonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };#endif#ifndef QT_NO_DATESTRINGstatic QString fmtDateTime(const QString& f, const QTime* dt = 0, const QDate* dd = 0);#endif/***************************************************************************** QDate member functions *****************************************************************************//*! \class QDate \reentrant \brief The QDate class provides date functions. \ingroup time \mainclass A QDate object contains a calendar date, i.e. year, month, and day numbers, in the Gregorian calendar (Julian calendar for dates before 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, or by using the static function currentDate() that 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 this date is in a leap year. Note that the Gregorian calendar was introduced at different dates in different countries and regions. QDate uses the Gregorian calendar starting from 15 October 1582, and uses the Julian calendar for dates up to 4 October 1582. \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. Any date before 2 January 4713 B.C. is considered invalid. \warning Years 0 to 99 are interpreted as is. If you want to specify the year 2010, you must write 2010, not 10. \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. \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, m, d; getDateFromJulianDay(jd, &y, &m, &d); 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 y, m, d; getDateFromJulianDay(jd, &y, &m, &d); return m;}/*! Returns the day of the month (1 to 31) of this date. \sa year(), month(), dayOfWeek()*/int QDate::day() const{ int y, m, d; getDateFromJulianDay(jd, &y, &m, &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) 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 Qt::Monday and the first Qt::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/*! Returns the name of the \a month using the following convention: \list
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -