📄 qdatetime.cpp
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.** ** This program is free software; you can redistribute it and/or modify it** under the terms of the GNU General Public License as published by the** Free Software Foundation; either version 2 of the License, or (at your** option) any later version.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** This program is distributed in the hope that it will be useful, but** WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qplatformdefs.h"#include "qdatetime.h"#include "qdatastream.h"#include "qregexp.h"#include <stdio.h>#ifndef Q_OS_TEMP#include <time.h>#endif#if defined(Q_OS_WIN32)#include <windows.h>#endifstatic const uint FIRST_DAY = 2361222; // Julian day for 1752-09-14static const int FIRST_YEAR = 1752; // ### wrong for many countriesstatic const uint SECS_PER_DAY = 86400;static const uint MSECS_PER_DAY = 86400000;static const uint SECS_PER_HOUR = 3600;static const uint MSECS_PER_HOUR= 3600000;static const uint SECS_PER_MIN = 60;static const uint MSECS_PER_MIN = 60000;static const short monthDays[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };static const char * const qt_shortMonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };#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 tokensstatic QString getFmtString( const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = FALSE ){ if ( f.isEmpty() ) return QString::null; QString buf = f; if ( dt ) { if ( f == "h" ) { if ( ( am_pm ) && ( dt->hour() > 12 ) ) buf = QString::number( dt->hour() - 12 ); else if ( ( am_pm ) && ( dt->hour() == 0 ) ) buf = "12"; else buf = QString::number( dt->hour() ); } else if ( f == "hh" ) { if ( ( am_pm ) && ( dt->hour() > 12 ) ) buf = QString::number( dt->hour() - 12 ).rightJustify( 2, '0', TRUE ); else if ( ( am_pm ) && ( dt->hour() == 0 ) ) buf = "12"; else buf = QString::number( dt->hour() ).rightJustify( 2, '0', TRUE ); } else if ( f == "m" ) { buf = QString::number( dt->minute() ); } else if ( f == "mm" ) { buf = QString::number( dt->minute() ).rightJustify( 2, '0', TRUE ); } else if ( f == "s" ) { buf = QString::number( dt->second() ); } else if ( f == "ss" ) { buf = QString::number( dt->second() ).rightJustify( 2, '0', TRUE ); } else if ( f == "z" ) { buf = QString::number( dt->msec() ); } else if ( f == "zzz" ) { buf = QString::number( dt->msec() ).rightJustify( 3, '0', TRUE ); } else if ( f == "ap" ) { buf = dt->hour() < 12 ? "am" : "pm"; } else if ( f == "AP" ) { buf = dt->hour() < 12 ? "AM" : "PM"; } } if ( dd ) { if ( f == "d" ) { buf = QString::number( dd->day() ); } else if ( f == "dd" ) { buf = QString::number( dd->day() ).rightJustify( 2, '0', TRUE ); } else if ( f == "M" ) { buf = QString::number( dd->month() ); } else if ( f == "MM" ) { buf = QString::number( dd->month() ).rightJustify( 2, '0', TRUE );#ifndef QT_NO_TEXTDATE } else if ( f == "ddd" ) { buf = dd->shortDayName( dd->dayOfWeek() ); } else if ( f == "dddd" ) { buf = dd->longDayName( dd->dayOfWeek() ); } else if ( f == "MMM" ) { buf = dd->shortMonthName( dd->month() ); } else if ( f == "MMMM" ) { buf = dd->longMonthName( dd->month() );#endif } else if ( f == "yy" ) { buf = QString::number( dd->year() ).right( 2 ); } else if ( f == "yyyy" ) { buf = QString::number( dd->year() ); } } return buf;}// Parses the format string and uses getFmtString to get the values for the tokens. Retstatic QString fmtDateTime( const QString& f, const QTime* dt = 0, const QDate* dd = 0 ){ if ( f.isEmpty() ) { return QString::null; } if ( dt && !dt->isValid() ) return QString::null; if ( dd && !dd->isValid() ) return QString::null; bool ap = ( f.contains( "AP" ) || f.contains( "ap" ) ); QString buf; QString frm; QChar status = '0'; for ( int i = 0; i < (int)f.length(); ++i ) { if ( f[ i ] == status ) { if ( ( ap ) && ( ( f[ i ] == 'P' ) || ( f[ i ] == 'p' ) ) ) status = '0'; frm += f[ i ]; } else { buf += getFmtString( frm, dt, dd, ap ); frm = QString::null; if ( ( f[ i ] == 'h' ) || ( f[ i ] == 'm' ) || ( f[ i ] == 's' ) || ( f[ i ] == 'z' ) ) { status = f[ i ]; frm += f[ i ]; } else if ( ( f[ i ] == 'd' ) || ( f[ i ] == 'M' ) || ( f[ i ] == 'y' ) ) { status = f[ i ]; frm += f[ i ]; } else if ( ( ap ) && ( f[ i ] == 'A' ) ) { status = 'P'; frm += f[ i ]; } else if( ( ap ) && ( f[ i ] == 'a' ) ) { status = 'p'; frm += f[ i ]; } else { buf += f[ i ]; status = '0'; } } } buf += getFmtString( frm, dt, dd, ap ); return buf;}#endif // QT_NO_DATESTRING/***************************************************************************** QDate member functions *****************************************************************************//*! \class QDate qdatetime.h \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 modern Western (Gregorian) calendar. It can read the current date from the system clock. It provides functions for comparing dates and for manipulating dates, e.g. by adding a number of days or months or years. A QDate object is typically created either by giving the year, month and day numbers explicitly, or by using the static function currentDate(), which creates a QDate object containing the system clock's date. An explicit date can also be set using setYMD(). 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 leapYear() function indicates whether this date is in a leap year. Note that QDate should not be used for date calculations for dates prior to the introduction of the Gregorian calendar. This calendar was adopted by England from the 14<sup><small>th</small></sup> September 1752 (hence this is the earliest valid QDate), and subsequently by most other Western countries, until 1923. The end of time is reached around the year 8000, by which time we expect Qt to be obsolete. \sa QTime QDateTime QDateEdit QDateTimeEdit*//*! \enum Qt::DateFormat \value TextDate (default) Qt format \value ISODate ISO 8601 extended format (YYYY-MM-DD, or with time, YYYY-MM-DDTHH:MM:SS) \value LocalDate locale dependent format*//*! \enum Qt::TimeSpec \value LocalTime Locale dependent time (Timezones and Daylight Savings Time) \value UTC Coordinated Universal Time, replaces Greenwich Time*//*! \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. \a y must be in the range 1752..8000, \a m must be in the range 1..12, and \a d must be in the range 1..31. \warning If \a y is in the range 0..99, it is interpreted as 1900..1999. \sa isValid()*/QDate::QDate( int y, int m, int d ){ jd = 0; setYMD( 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 jd >= FIRST_DAY;}/*! Returns the year (1752..8000) of this date. \sa month(), day()*/int QDate::year() const{ int y, m, d; julianToGregorian( jd, y, m, d ); return y;}/*! Returns the month (January=1..December=12) of this date. \sa year(), day()*/int QDate::month() const{ int y, m, d; julianToGregorian( jd, y, m, d ); return m;}/*! Returns the day of the month (1..31) of this date. \sa year(), month(), dayOfWeek()*/int QDate::day() const{ int y, m, d; julianToGregorian( jd, y, m, d ); return d;}/*! Returns the weekday (Monday=1..Sunday=7) for this date. \sa day(), dayOfYear()*/int QDate::dayOfWeek() const{ return ( jd % 7 ) + 1;}/*! Returns the day of the year (1..365) for this date. \sa day(), dayOfWeek()*/int QDate::dayOfYear() const{ return jd - gregorianToJulian(year(), 1, 1) + 1;}/*! Returns the number of days in the month (28..31) for this date. \sa day(), daysInYear()*/int QDate::daysInMonth() const{ int y, m, d; julianToGregorian( jd, y, m, d ); if ( m == 2 && leapYear(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; julianToGregorian( jd, y, m, d ); return leapYear( 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. \sa isValid()*/int QDate::weekNumber( int *yearNumber ) const{ if ( !isValid() ) return 0; int dow = dayOfWeek(); int doy = dayOfYear(); int currYear = year(); int jan1WeekDay = QDate( currYear, 1, 1 ).dayOfWeek(); int yearNum; int weekNum; if ( doy <= (8 - jan1WeekDay) && jan1WeekDay > 4 ) { yearNum = currYear - 1; weekNum = 52; if ( jan1WeekDay == 5 || (jan1WeekDay == 6 && QDate::leapYear(yearNum)) ) weekNum++; } else { int totalDays = 365; if ( QDate::leapYear(currYear) ) totalDays++; if ( (totalDays - doy < 4 - dow) || (jan1WeekDay == 7 && totalDays - doy < 3) ) { yearNum = currYear + 1; weekNum = 1; } else { int j = doy + ( 7 - dow ) + ( jan1WeekDay - 1 ); yearNum = currYear; weekNum = j / 7; if ( jan1WeekDay > 4 ) weekNum--; } } if ( yearNumber ) *yearNumber = yearNum; return weekNum;}/*! \fn QString QDate::monthName( int month ) \obsolete Use shortMonthName() instead.*/#ifndef QT_NO_TEXTDATE/*! Returns the name of the \a month. 1 = "Jan", 2 = "Feb", ... 12 = "Dec" The month names will be localized according to the system's locale settings. \sa toString(), longMonthName(), shortDayName(), longDayName()*/QString QDate::shortMonthName( int month ){#if defined(QT_CHECK_RANGE) if ( month < 1 || month > 12 ) { qWarning( "QDate::shortMonthName: Parameter out ouf range" ); month = 1; }#endif#ifndef Q_WS_WIN char buffer[255]; tm tt; memset( &tt, 0, sizeof( tm ) ); tt.tm_mon = month - 1; if ( strftime( buffer, sizeof( buffer ), "%b", &tt ) ) return QString::fromLocal8Bit( buffer );#else SYSTEMTIME st; memset( &st, 0, sizeof(SYSTEMTIME) ); st.wYear = 2000; st.wMonth = month; st.wDay = 1; const wchar_t mmm_t[] = L"MMM"; // workaround for Borland QT_WA( { TCHAR buf[255]; if ( GetDateFormat( LOCALE_USER_DEFAULT, 0, &st, mmm_t, buf, 255 ) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -