添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
1 /**************************************************************************** 5 ** Contact: https://www.qt.io/licensing/ 7 ** This file is part of the QtCore module of the Qt Toolkit. 9 ** $QT_BEGIN_LICENSE:LGPL$ 10 ** Commercial License Usage 11 ** Licensees holding valid commercial Qt licenses may use this file in 12 ** accordance with the commercial license agreement provided with the 13 ** Software or, alternatively, in accordance with the terms contained in 14 ** a written agreement between you and The Qt Company. For licensing terms 15 ** and conditions see https://www.qt.io/terms-conditions . For further 16 ** information use the contact form at https://www.qt.io/contact-us . 17 ** 18 ** GNU Lesser General Public License Usage 19 ** Alternatively, this file may be used under the terms of the GNU Lesser 20 ** General Public License version 3 as published by the Free Software 21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 22 ** packaging of this file. Please review the following information to 23 ** ensure the GNU Lesser General Public License version 3 requirements 24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html . 25 ** 26 ** GNU General Public License Usage 27 ** Alternatively, this file may be used under the terms of the GNU 28 ** General Public License version 2.0 or (at your option) the GNU General 29 ** Public license version 3 or any later version approved by the KDE Free 30 ** Qt Foundation. The licenses are as published by the Free Software 31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 32 ** included in the packaging of this file. Please review the following 33 ** information to ensure the GNU General Public License requirements will 34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 35 ** https://www.gnu.org/licenses/gpl-3.0.html . 36 ** 37 ** $QT_END_LICENSE$ 38 ** 39 ****************************************************************************/ 41 #include "qplatformdefs.h" 42 #include "private/qdatetime_p.h" 43 # if QT_CONFIG (datetimeparser) 44 #include "private/qdatetimeparser_p.h" 45 # endif 47 #include "qdatastream.h" 48 #include "qset.h" 49 #include "qlocale.h" 50 #include "qdatetime.h" 51 # if QT_CONFIG (timezone) 52 #include "qtimezoneprivate_p.h" 53 # endif 54 #include "qregexp.h" 55 #include "qdebug.h" 56 # ifndef Q_OS_WIN 57 #include <locale.h> 58 # endif 60 #include <cmath> 61 # ifdef Q_CC_MINGW 62 # include <unistd.h> // Define _POSIX_THREAD_SAFE_FUNCTIONS to obtain localtime_r() 63 # endif 64 #include <time.h> 65 # ifdef Q_OS_WIN 66 # include <qt_windows.h> 67 # ifdef Q_OS_WINRT 68 # include "qfunctions_winrt.h" 69 # endif 70 # endif 72 # if defined( Q_OS_MAC ) 73 #include <private/qcore_mac_p.h> 74 # endif 76 #include "qcalendar.h" 77 #include "qgregoriancalendar_p.h" 79 QT_BEGIN_NAMESPACE 81 /***************************************************************************** 82 Date/Time Constants 83 *****************************************************************************/ 85 enum { 86 SECS_PER_DAY = 86400 , 87 MSECS_PER_DAY = 86400000 , 88 SECS_PER_HOUR = 3600 , 89 MSECS_PER_HOUR = 3600000 , 90 SECS_PER_MIN = 60 , 91 MSECS_PER_MIN = 60000 , 92 TIME_T_MAX = 2145916799 , // int maximum 2037-12-31T23:59:59 UTC 93 JULIAN_DAY_FOR_EPOCH = 2440588 // result of julianDayFromDate(1970, 1, 1) 94}; 96 /***************************************************************************** 97 QDate static helper functions 98 *****************************************************************************/ 100 static inline QDate fixedDate ( QCalendar :: YearMonthDay && parts , QCalendar cal ) 101{ 102 if (( parts . year < 0 && ! cal . isProleptic ()) || ( parts . year == 0 && ! cal . hasYearZero ())) 103 return QDate ( ); 105 parts . day = qMin ( a: parts . day , b: cal . daysInMonth ( month: parts . month , year: parts . year )); 106 return cal . dateFromParts ( parts ); 107} 109 static inline QDate fixedDate ( QCalendar :: YearMonthDay && parts ) 110{ 111 if ( parts . year ) { 112 parts . day = qMin ( a: parts . day , b: QGregorianCalendar :: monthLength ( month: parts . month , year: parts . year )); 113 qint64 jd ; 114 if ( QGregorianCalendar :: julianFromParts ( year: parts . year , month: parts . month , day: parts . day , jd: & jd )) 115 return QDate :: fromJulianDay ( jd_: jd ); 116 } 117 return QDate ( ); 118} 120 /***************************************************************************** 121 Date/Time formatting helper functions 122 *****************************************************************************/ 124 # if QT_CONFIG (textdate) 125 static const char qt_shortMonthNames [][ 4 ] = { 126 "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , 127 "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec" 128}; 130 static int qt_monthNumberFromShortName ( QStringView shortName ) 131{ 132 for ( unsigned int i = 0 ; i < sizeof ( qt_shortMonthNames ) / sizeof ( qt_shortMonthNames [ 0 ]); ++ i ) { 133 if ( shortName == QLatin1String ( qt_shortMonthNames [ i ], 3 )) 134 return i + 1 ; 135 } 136 return - 1 ; 137} 138 static int qt_monthNumberFromShortName ( const QString & shortName ) 139{ return qt_monthNumberFromShortName ( shortName: QStringView ( shortName )); } 141 static int fromShortMonthName ( QStringView monthName , int year ) 142{ 143 // Assume that English monthnames are the default 144 int month = qt_monthNumberFromShortName ( shortName: monthName ); 145 if ( month != - 1 ) 146 return month ; 147 // If English names can't be found, search the localized ones 148 for ( int i = 1 ; i <= 12 ; ++ i ) { 149 if ( monthName == QCalendar ( ). monthName ( locale: QLocale :: system (), month: i , year , format: QLocale :: ShortFormat )) 150 return i ; 151 } 152 return - 1 ; 153} 154 # endif // textdate 156 # if QT_CONFIG (datestring) 157 struct ParsedRfcDateTime { 158 QDate date ; 159 QTime time ; 160 int utcOffset ; 161}; 163 static ParsedRfcDateTime rfcDateImpl ( const QString & s ) 164{ 165 ParsedRfcDateTime result ; 167 // Matches "[ddd,] dd MMM yyyy[ hh:mm[:ss]] [±hhmm]" - correct RFC 822, 2822, 5322 format 168 QRegExp rex ( QStringLiteral ( "^[ \\t]*(?:[A-Z][a-z]+,)?[ \\t]*(\\d{1,2})[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d)(?::(\\d\\d))?)?[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?" )); 169 if ( s . indexOf ( rex ) == 0 ) { 170 const QStringList cap = rex . capturedTexts (); 171 result . date = QDate ( cap [ 3 ] . toInt (), qt_monthNumberFromShortName ( shortName: cap [ 2 ] ), cap [ 1 ] . toInt ()); 172 if (! cap [ 4 ] . isEmpty ()) 173 result . time = QTime ( cap [ 4 ] . toInt (), cap [ 5 ] . toInt (), cap [ 6 ] . toInt ()); 174 const bool positiveOffset = ( cap [ 7 ] == QLatin1String ( "+" )); 175 const int hourOffset = cap [ 8 ] . toInt (); 176 const int minOffset = cap [ 9 ] . toInt (); 177 result . utcOffset = (( hourOffset * 60 + minOffset ) * ( positiveOffset ? 60 : - 60 )); 178 } else { 179 // Matches "ddd MMM dd[ hh:mm:ss] yyyy [±hhmm]" - permissive RFC 850, 1036 (read only) 180 QRegExp rex ( QStringLiteral ( "^[ \\t]*[A-Z][a-z]+[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d):(\\d\\d))?[ \\t]+(\\d\\d\\d\\d)[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?" )); 181 if ( s . indexOf ( rex ) == 0 ) { 182 const QStringList cap = rex . capturedTexts (); 183 result . date = QDate ( cap [ 6 ] . toInt (), qt_monthNumberFromShortName ( shortName: cap [ 1 ] ), cap [ 2 ] . toInt ()); 184 if (! cap [ 3 ] . isEmpty ()) 185 result . time = QTime ( cap [ 3 ] . toInt (), cap [ 4 ] . toInt (), cap [ 5 ] . toInt ()); 186 const bool positiveOffset = ( cap [ 7 ] == QLatin1String ( "+" )); 187 const int hourOffset = cap [ 8 ] . toInt (); 188 const int minOffset = cap [ 9 ] . toInt (); 189 result . utcOffset = (( hourOffset * 60 + minOffset ) * ( positiveOffset ? 60 : - 60 )); 190 } 191 } 193 return result ; 194} 195 # endif // datestring 197 // Return offset in [+-]HH:mm format 198 static QString toOffsetString ( Qt:: DateFormat format , int offset ) 199{ 200 return QString :: asprintf ( format: "%c%02d%s%02d" , 201 offset >= 0 ? '+' : '-' , 202 qAbs ( t: offset ) / SECS_PER_HOUR , 203 // Qt::ISODate puts : between the hours and minutes, but Qt:TextDate does not: 204 format == Qt:: TextDate ? "" : ":" , 205 ( qAbs ( t: offset ) / 60 ) % 60 ); 206} 208 # if QT_CONFIG (datestring) 209 // Parse offset in [+-]HH[[:]mm] format 210 static int fromOffsetString ( QStringView offsetString , bool * valid ) noexcept 211{ 212 * valid = false ; 214 const int size = offsetString . size (); 215 if ( size < 2 || size > 6 ) 216 return 0 ; 218 // sign will be +1 for a positive and -1 for a negative offset 219 int sign ; 221 // First char must be + or - 222 const QChar signChar = offsetString . at ( n: 0 ); 223 if ( signChar == QLatin1Char ( '+' )) 224 sign = 1 ; 225 else if ( signChar == QLatin1Char ( '-' )) 226 sign = - 1 ; 227 else 228 return 0 ; 230 // Split the hour and minute parts 231 const QStringView time = offsetString . mid ( pos: 1 ); 232 qsizetype hhLen = time . indexOf ( c: QLatin1Char ( ':' )); 233 qsizetype mmIndex ; 234 if ( hhLen == - 1 ) 235 mmIndex = hhLen = 2 ; // [+-]HHmm or [+-]HH format 236 else 237 mmIndex = hhLen + 1 ; 239 const QLocale C = QLocale :: c (); 240 const QStringView hhRef = time . left ( n: qMin ( a: hhLen , b: time . size ())); 241 bool ok = false ; 242 const int hour = C . toInt ( s: hhRef , ok: & ok ); 243 if (! ok ) 244 return 0 ; 246 const QStringView mmRef = time . mid ( pos: qMin ( a: mmIndex , b: time . size ())); 247 const int minute = mmRef . isEmpty () ? 0 : C . toInt ( s: mmRef , ok: & ok ); 248 if (! ok || minute < 0 || minute > 59 ) 249 return 0 ; 251 * valid = true ; 252 return sign * (( hour * 60 ) + minute ) * 60 ; 253} 254 # endif // datestring 256 /***************************************************************************** 257 QDate member functions 258 *****************************************************************************/ 260 /*! 261 \since 4.5 263 \enum QDate::MonthNameType 265 This enum describes the types of the string representation used 266 for the month name. 268 \value DateFormat This type of name can be used for date-to-string formatting. 269 \value StandaloneFormat This type is used when you need to enumerate months or weekdays. 270 Usually standalone names are represented in singular forms with 271 capitalized first letter. 272 */ 274 /*! 275 \class QDate 276 \inmodule QtCore 277 \reentrant 278 \brief The QDate class provides date functions. 280 A QDate object represents a particular day, regardless of calendar, 281 locale or other settings used when creating it or supplied by the system. 282 It can report the year, month and day of the month that represent the 283 day with respect to the proleptic Gregorian calendar or any calendar supplied 284 as a QCalendar object. 286 A QDate object is typically created by giving the year, month, and day 287 numbers explicitly. Note that QDate interprets year numbers less than 100 as 288 presented, i.e., as years 1 through 99, without adding any offset. The 289 static function currentDate() creates a QDate object containing the date 290 read from the system clock. An explicit date can also be set using 291 setDate(). The fromString() function returns a QDate given a string and a 292 date format which is used to interpret the date within the string. 294 The year(), month(), and day() functions provide access to the year, month, 295 and day numbers. When more than one of these values is needed, it is more 296 efficient to call QCalendar::partsFromDate(), to save repeating (potentially 297 expensive) calendrical calculations. 299 Also, dayOfWeek() and dayOfYear() functions are provided. The same 300 information is provided in textual format by toString(). QLocale can map the 301 day numbers to names, QCalendar can map month numbers to names. 303 QDate provides a full set of operators to compare two QDate 304 objects where smaller means earlier, and larger means later. 306 You can increment (or decrement) a date by a given number of days 307 using addDays(). Similarly you can use addMonths() and addYears(). 308 The daysTo() function returns the number of days between two 309 dates. 311 The daysInMonth() and daysInYear() functions return how many days there are 312 in this date's month and year, respectively. The isLeapYear() function 313 indicates whether a date is in a leap year. QCalendar can also supply this 314 information, in some cases more conveniently. 316 \section 1 Remarks 318 \section 2 No Year 0 320 In the Gregorian calendar, there is no year 0. Dates in that year are 321 considered invalid. The year -1 is the year "1 before Christ" or "1 before 322 common era." The day before 1 January 1 CE, QDate(1, 1, 1), is 31 December 323 1 BCE, QDate(-1, 12, 31). Various other calendars behave similarly; see 324 QCalendar::hasYearZero(). 326 \section 2 Range of Valid Dates 328 Dates are stored internally as a Julian Day number, an integer count of 329 every day in a contiguous range, with 24 November 4714 BCE in the Gregorian 330 calendar being Julian Day 0 (1 January 4713 BCE in the Julian calendar). 331 As well as being an efficient and accurate way of storing an absolute date, 332 it is suitable for converting a date into other calendar systems such as 333 Hebrew, Islamic or Chinese. The Julian Day number can be obtained using 334 QDate::toJulianDay() and can be set using QDate::fromJulianDay(). 336 The range of Julian Day numbers that QDate can represent is, for technical 337 reasons, limited to between -784350574879 and 784354017364, which means from 338 before 2 billion BCE to after 2 billion CE. This is more than seven times as 339 wide as the range of dates a QDateTime can represent. 341 \sa QTime, QDateTime, QCalendar, QDateTime::YearRange, QDateEdit, QDateTimeEdit, QCalendarWidget 342 */ 344 /*! 345 \fn QDate::QDate() 347 Constructs a null date. Null dates are invalid. 349 \sa isNull(), isValid() 350 */ 352 /*! 353 Constructs a date with year \a y, month \a m and day \a d. 355 The date is understood in terms of the Gregorian calendar. If the specified 356 date is invalid, the date is not set and isValid() returns \c false. 358 \warning Years 1 to 99 are interpreted as is. Year 0 is invalid. 360 \sa isValid(), QCalendar::dateFromParts() 361 */ 363 QDate :: QDate ( int y , int m , int d ) 364{ 365 if (! QGregorianCalendar :: julianFromParts ( year: y , month: m , day: d , jd: & jd )) 366 jd = nullJd (); 367} 369 QDate :: QDate ( int y , int m , int d , QCalendar cal ) 370{ 371 * this = cal . dateFromParts ( year: y , month: m , day: d ); 372} 374 /*! 375 \fn bool QDate::isNull() const 377 Returns \c true if the date is null; otherwise returns \c false. A null 378 date is invalid. 380 \note The behavior of this function is equivalent to isValid(). 382 \sa isValid() 383 */ 385 /*! 386 \fn bool QDate::isValid() const 388 Returns \c true if this date is valid; otherwise returns \c false. 390 \sa isNull(), QCalendar::isDateValid() 391 */ 393 /*! 394 Returns the year of this date. 396 Uses \a cal as calendar, if supplied, else the Gregorian calendar. 398 Returns 0 if the date is invalid. For some calendars, dates before their 399 first year may all be invalid. 401 If using a calendar which has a year 0, check using isValid() if the return 402 is 0. Such calendars use negative year numbers in the obvious way, with 403 year 1 preceded by year 0, in turn preceded by year -1 and so on. 405 Some calendars, despite having no year 0, have a conventional numbering of 406 the years before their first year, counting backwards from 1. For example, 407 in the proleptic Gregorian calendar, successive years before 1 CE (the first 408 year) are identified as 1 BCE, 2 BCE, 3 BCE and so on. For such calendars, 409 negative year numbers are used to indicate these years before year 1, with 410 -1 indicating the year before 1. 412 \sa month(), day(), QCalendar::hasYearZero(), QCalendar::isProleptic(), QCalendar::partsFromDate() 413 */ 415 int QDate :: year ( QCalendar cal ) const 416{ 417 if ( isValid ()) { 418 const auto parts = cal . partsFromDate ( date: * this ); 419 if ( parts . isValid ()) 420 return parts . year ; 421 } 422 return 0 ; 423} 425 /*! 426 \overload 427 */ 429 int QDate :: year () const 430{ 431 if ( isValid ()) { 432 const auto parts = QGregorianCalendar :: partsFromJulian ( jd ); 433 if ( parts . isValid ()) 434 return parts . year ; 435 } 436 return 0 ; 437} 439 /*! 440 Returns the month-number for the date. 442 Numbers the months of the year starting with 1 for the first. Uses \a cal 443 as calendar if supplied, else the Gregorian calendar, for which the month 444 numbering is as follows: 446 \list 447 \li 1 = "January" 448 \li 2 = "February" 449 \li 3 = "March" 450 \li 4 = "April" 451 \li 5 = "May" 452 \li 6 = "June" 453 \li 7 = "July" 454 \li 8 = "August" 455 \li 9 = "September" 456 \li 10 = "October" 457 \li 11 = "November" 458 \li 12 = "December" 459 \endlist 461 Returns 0 if the date is invalid. Note that some calendars may have more 462 than 12 months in some years. 464 \sa year(), day(), QCalendar::partsFromDate() 465 */ 467 int QDate :: month ( QCalendar cal ) const 468{ 469 if ( isValid ()) { 470 const auto parts = cal . partsFromDate ( date: * this ); 471 if ( parts . isValid ()) 472 return parts . month ; 473 } 474 return 0 ; 475} 477 /*! 478 \overload 479 */ 481 int QDate :: month () const 482{ 483 if ( isValid ()) { 484 const auto parts = QGregorianCalendar :: partsFromJulian ( jd ); 485 if ( parts . isValid ()) 486 return parts . month ; 487 } 488 return 0 ; 489} 491 /*! 492 Returns the day of the month for this date. 494 Uses \a cal as calendar if supplied, else the Gregorian calendar (for which 495 the return ranges from 1 to 31). Returns 0 if the date is invalid. 497 \sa year(), month(), dayOfWeek(), QCalendar::partsFromDate() 498 */ 500 int QDate :: day ( QCalendar cal ) const 501{ 502 if ( isValid ()) { 503 const auto parts = cal . partsFromDate ( date: * this ); 504 if ( parts . isValid ()) 505 return parts . day ; 506 } 507 return 0 ; 508} 510 /*! 511 \overload 512 */ 514 int QDate :: day () const 515{ 516 if ( isValid ()) { 517 const auto parts = QGregorianCalendar :: partsFromJulian ( jd ); 518 if ( parts . isValid ()) 519 return parts . day ; 520 } 521 return 0 ; 522} 524 /*! 525 Returns the weekday (1 = Monday to 7 = Sunday) for this date. 527 Uses \a cal as calendar if supplied, else the Gregorian calendar. Returns 0 528 if the date is invalid. Some calendars may give special meaning 529 (e.g. intercallary days) to values greater than 7. 531 \sa day(), dayOfYear(), QCalendar::dayOfWeek(), Qt::DayOfWeek 532 */ 534 int QDate :: dayOfWeek ( QCalendar cal ) const 535{ 536 if ( isNull ()) 537 return 0 ; 539 return cal . dayOfWeek ( date: * this ); 540} 542 /*! 543 \overload 544 */ 546 int QDate :: dayOfWeek () const 547{ 548 return isValid () ? QGregorianCalendar :: weekDayOfJulian ( jd ) : 0 ; 549} 551 /*! 552 Returns the day of the year (1 for the first day) for this date. 554 Uses \a cal as calendar if supplied, else the Gregorian calendar. 555 Returns 0 if either the date or the first day of its year is invalid. 557 \sa day(), dayOfWeek(), QCalendar::daysInYear() 558 */ 560 int QDate :: dayOfYear ( QCalendar cal ) const 561{ 562 if ( isValid ()) { 563 QDate firstDay = cal . dateFromParts ( year: year ( cal ), month: 1 , day: 1 ); 564 if ( firstDay . isValid ()) 565 return firstDay . daysTo (* this ) + 1 ; 566 } 567 return 0 ; 568} 570 /*! 571 \overload 572 */ 574 int QDate :: dayOfYear () const 575{ 576 if ( isValid ()) { 577 qint64 first ; 578 if ( QGregorianCalendar :: julianFromParts ( year: year (), month: 1 , day: 1 , jd: & first )) 579 return jd - first + 1 ; 580 } 581 return 0 ; 582} 584 /*! 585 Returns the number of days in the month for this date. 587 Uses \a cal as calendar if supplied, else the Gregorian calendar (for which 588 the result ranges from 28 to 31). Returns 0 if the date is invalid. 590 \sa day(), daysInYear(), QCalendar::daysInMonth(), 591 QCalendar::maximumDaysInMonth(), QCalendar::minimumDaysInMonth() 592 */ 594 int QDate :: daysInMonth ( QCalendar cal ) const 595{ 596 if ( isValid ()) { 597 const auto parts = cal . partsFromDate ( date: * this ); 598 if ( parts . isValid ()) 599 return cal . daysInMonth ( month: parts . month , year: parts . year ); 600 } 601 return 0 ; 602} 604 /*! 605 \overload 606 */ 608 int QDate :: daysInMonth () const 609{ 610 if ( isValid ()) { 611 const auto parts = QGregorianCalendar :: partsFromJulian ( jd ); 612 if ( parts . isValid ()) 613 return QGregorianCalendar :: monthLength ( month: parts . month , year: parts . year ); 614 } 615 return 0 ; 616} 618 /*! 619 Returns the number of days in the year for this date. 621 Uses \a cal as calendar if supplied, else the Gregorian calendar (for which 622 the result is 365 or 366). Returns 0 if the date is invalid. 624 \sa day(), daysInMonth(), QCalendar::daysInYear(), QCalendar::maximumMonthsInYear() 625 */ 627 int QDate :: daysInYear ( QCalendar cal ) const 628{ 629 if ( isNull ()) 630 return 0 ; 632 return cal . daysInYear ( year: year ( cal )); 633} 635 /*! 636 \overload 637 */ 639 int QDate :: daysInYear () const 640{ 641 return isValid () ? QGregorianCalendar :: leapTest ( year: year ()) ? 366 : 365 : 0 ; 642} 644 /*! 645 Returns the ISO 8601 week number (1 to 53). 647 Returns 0 if the date is invalid. Otherwise, returns the week number for the 648 date. If \a yearNumber is not \nullptr (its default), stores the year as 649 *\a {yearNumber}. 651 In accordance with ISO 8601, each week falls in the year to which most of 652 its days belong, in the Gregorian calendar. As ISO 8601's week starts on 653 Monday, this is the year in which the week's Thursday falls. Most years have 654 52 weeks, but some have 53. 656 \note *\a {yearNumber} is not always the same as year(). For example, 1 657 January 2000 has week number 52 in the year 1999, and 31 December 658 2002 has week number 1 in the year 2003. 660 \sa isValid() 661 */ 663 int QDate :: weekNumber ( int * yearNumber ) const 664{ 665 if (! isValid ()) 666 return 0 ; 668 // This could be replaced by use of QIso8601Calendar, once we implement it. 669 // The Thursday of the same week determines our answer: 670 QDate thursday ( addDays ( days: 4 - dayOfWeek ())); 671 int year = thursday . year (); 672 // Week n's Thurs's DOY has 1 <= DOY - 7*(n-1) < 8, so 0 <= DOY + 6 - 7*n < 7: 673 int week = ( thursday . dayOfYear () + 6 ) / 7 ; 675 if ( yearNumber ) 676 * yearNumber = year ; 677 return week ; 678} 680 static bool inDateTimeRange ( qint64 jd , bool start ) 681{ 682 using Bounds = std:: numeric_limits < qint64 >; 683 if ( jd < Bounds :: min () + JULIAN_DAY_FOR_EPOCH ) 684 return false ; 685 jd -= JULIAN_DAY_FOR_EPOCH ; 686 const qint64 maxDay = Bounds :: max () / MSECS_PER_DAY ; 687 const qint64 minDay = Bounds :: min () / MSECS_PER_DAY - 1 ; 688 // (Divisions rounded towards zero, as MSECS_PER_DAY has factors other than two.) 689 // Range includes start of last day and end of first: 690 if ( start ) 691 return jd > minDay && jd <= maxDay ; 692 return jd >= minDay && jd < maxDay ; 693} 695 static QDateTime toEarliest ( QDate day , const QDateTime & form ) 696{ 697 const Qt:: TimeSpec spec = form . timeSpec (); 698 const int offset = ( spec == Qt:: OffsetFromUTC ) ? form . offsetFromUtc () : 0 ; 699 # if QT_CONFIG (timezone) 700 QTimeZone zone ; 701 if ( spec == Qt:: TimeZone ) 702 zone = form . timeZone (); 703 # endif 704 auto moment = [=]( QTime time ) { 705 switch ( spec ) { 706 case Qt:: OffsetFromUTC : return QDateTime ( day , time , spec , offset ); 707 # if QT_CONFIG (timezone) 708 case Qt:: TimeZone : return QDateTime ( day , time , zone ); 709 # endif 710 default : return QDateTime ( day , time , spec ); 711 } 712 }; 713 // Longest routine time-zone transition is 2 hours: 714 QDateTime when = moment ( QTime ( 2 , 0 )); 715 if (! when . isValid ()) { 716 // Noon should be safe ... 717 when = moment ( QTime ( 12 , 0 )); 718 if (! when . isValid ()) { 719 // ... unless it's a 24-hour jump (moving the date-line) 720 when = moment ( QTime ( 23 , 59 , 59 , 999 )); 721 if (! when . isValid ()) 722 return QDateTime ( ); 723 } 724 } 725 int high = when . time (). msecsSinceStartOfDay () / 60000 ; 726 int low = 0 ; 727 // Binary chop to the right minute 728 while ( high > low + 1 ) { 729 int mid = ( high + low ) / 2 ; 730 QDateTime probe = moment ( QTime ( mid / 60 , mid % 60 )); 731 if ( probe . isValid () && probe . date () == day ) { 732 high = mid ; 733 when = probe ; 734 } else { 735 low = mid ; 736 } 737 } 738 return when ; 739} 741 /*! 742 \since 5.14 743 \fn QDateTime QDate::startOfDay(Qt::TimeSpec spec, int offsetSeconds) const 744 \fn QDateTime QDate::startOfDay(const QTimeZone &zone) const 746 Returns the start-moment of the day. Usually, this shall be midnight at the 747 start of the day: however, if a time-zone transition causes the given date 748 to skip over that midnight (e.g. a DST spring-forward skipping from the end 749 of the previous day to 01:00 of the new day), the actual earliest time in 750 the day is returned. This can only arise when the start-moment is specified 751 in terms of a time-zone (by passing its QTimeZone as \a zone) or in terms of 752 local time (by passing Qt::LocalTime as \a spec; this is its default). 754 The \a offsetSeconds is ignored unless \a spec is Qt::OffsetFromUTC, when it 755 gives the implied zone's offset from UTC. As UTC and such zones have no 756 transitions, the start of the day is QTime(0, 0) in these cases. 758 In the rare case of a date that was entirely skipped (this happens when a 759 zone east of the international date-line switches to being west of it), the 760 return shall be invalid. Passing Qt::TimeZone as \a spec (instead of 761 passing a QTimeZone) or passing an invalid time-zone as \a zone will also 762 produce an invalid result, as shall dates that start outside the range 763 representable by QDateTime. 765 \sa endOfDay() 766 */ 767 QDateTime QDate :: startOfDay ( Qt:: TimeSpec spec , int offsetSeconds ) const 768{ 769 if (! inDateTimeRange ( jd , start: true )) 770 return QDateTime ( ); 772 switch ( spec ) { 773 case Qt:: TimeZone : // should pass a QTimeZone instead of Qt::TimeZone 774 qWarning () << "Called QDate::startOfDay(Qt::TimeZone) on" << * this ; 775 return QDateTime ( ); 776 case Qt:: OffsetFromUTC : 777 case Qt:: UTC : 778 return QDateTime ( * this , QTime ( 0 , 0 ), spec , offsetSeconds ); 780 case Qt:: LocalTime : 781 if ( offsetSeconds ) 782 qWarning ( msg: "Ignoring offset (%d seconds) passed with Qt::LocalTime" , offsetSeconds ); 783 break ; 784 } 785 QDateTime when ( * this , QTime ( 0 , 0 ), spec ); 786 if (! when . isValid ()) 787 when = toEarliest ( day: * this , form: when ); 789 return when . isValid () ? when : QDateTime ( ); 790} 792 # if QT_CONFIG (timezone) 793 /*! 794 \overload 795 \since 5.14 796 */ 797 QDateTime QDate :: startOfDay ( const QTimeZone & zone ) const 798{ 799 if (! inDateTimeRange ( jd , start: true ) || ! zone . isValid ()) 800 return QDateTime ( ); 802 QDateTime when ( * this , QTime ( 0 , 0 ), zone ); 803 if ( when . isValid ()) 804 return when ; 806 // The start of the day must have fallen in a spring-forward's gap; find the spring-forward: 807 if ( zone . hasTransitions ()) { 808 QTimeZone :: OffsetData tran = zone . previousTransition ( beforeDateTime: QDateTime ( * this , QTime ( 23 , 59 , 59 , 999 ), zone )); 809 const QDateTime & at = tran . atUtc . toTimeZone ( toZone: zone ); 810 if ( at . isValid () && at . date () == * this ) 811 return at ; 812 } 814 when = toEarliest ( day: * this , form: when ); 815 return when . isValid () ? when : QDateTime ( ); 816} 817 # endif // timezone 819 static QDateTime toLatest ( QDate day , const QDateTime & form ) 820{ 821 const Qt:: TimeSpec spec = form . timeSpec (); 822 const int offset = ( spec == Qt:: OffsetFromUTC ) ? form . offsetFromUtc () : 0 ; 823 # if QT_CONFIG (timezone) 824 QTimeZone zone ; 825 if ( spec == Qt:: TimeZone ) 826 zone = form . timeZone (); 827 # endif 828 auto moment = [=]( QTime time ) { 829 switch ( spec ) { 830 case Qt:: OffsetFromUTC : return QDateTime ( day , time , spec , offset ); 831 # if QT_CONFIG (timezone) 832 case Qt:: TimeZone : return QDateTime ( day , time , zone ); 833 # endif 834 default : return QDateTime ( day , time , spec ); 835 } 836 }; 837 // Longest routine time-zone transition is 2 hours: 838 QDateTime when = moment ( QTime ( 21 , 59 , 59 , 999 )); 839 if (! when . isValid ()) { 840 // Noon should be safe ... 841 when = moment ( QTime ( 12 , 0 )); 842 if (! when . isValid ()) { 843 // ... unless it's a 24-hour jump (moving the date-line) 844 when = moment ( QTime ( 0 , 0 )); 845 if (! when . isValid ()) 846 return QDateTime ( ); 847 } 848 } 849 int high = 24 * 60 ; 850 int low = when . time (). msecsSinceStartOfDay () / 60000 ; 851 // Binary chop to the right minute 852 while ( high > low + 1 ) { 853 int mid = ( high + low ) / 2 ; 854 QDateTime probe = moment ( QTime ( mid / 60 , mid % 60 , 59 , 999 )); 855 if ( probe . isValid () && probe . date () == day ) { 856 low = mid ; 857 when = probe ; 858 } else { 859 high = mid ; 860 } 861 } 862 return when ; 863} 865 /*! 866 \since 5.14 867 \fn QDateTime QDate::endOfDay(Qt::TimeSpec spec, int offsetSeconds) const 868 \fn QDateTime QDate::endOfDay(const QTimeZone &zone) const 870 Returns the end-moment of the day. Usually, this is one millisecond before 871 the midnight at the end of the day: however, if a time-zone transition 872 causes the given date to skip over that midnight (e.g. a DST spring-forward 873 skipping from just before 23:00 to the start of the next day), the actual 874 latest time in the day is returned. This can only arise when the 875 start-moment is specified in terms of a time-zone (by passing its QTimeZone 876 as \a zone) or in terms of local time (by passing Qt::LocalTime as \a spec; 877 this is its default). 879 The \a offsetSeconds is ignored unless \a spec is Qt::OffsetFromUTC, when it 880 gives the implied zone's offset from UTC. As UTC and such zones have no 881 transitions, the end of the day is QTime(23, 59, 59, 999) in these cases. 883 In the rare case of a date that was entirely skipped (this happens when a 884 zone east of the international date-line switches to being west of it), the 885 return shall be invalid. Passing Qt::TimeZone as \a spec (instead of 886 passing a QTimeZone) will also produce an invalid result, as shall dates 887 that end outside the range representable by QDateTime. 889 \sa startOfDay() 890 */ 891 QDateTime QDate :: endOfDay ( Qt:: TimeSpec spec , int offsetSeconds ) const 892{ 893 if (! inDateTimeRange ( jd , start: false )) 894 return QDateTime ( ); 896 switch ( spec ) { 897 case Qt:: TimeZone : // should pass a QTimeZone instead of Qt::TimeZone 898 qWarning () << "Called QDate::endOfDay(Qt::TimeZone) on" << * this ; 899 return QDateTime ( ); 900 case Qt:: UTC : 901 case Qt:: OffsetFromUTC : 902 return QDateTime ( * this , QTime ( 23 , 59 , 59 , 999 ), spec , offsetSeconds ); 904 case Qt:: LocalTime : 905 if ( offsetSeconds ) 906 qWarning ( msg: "Ignoring offset (%d seconds) passed with Qt::LocalTime" , offsetSeconds ); 907 break ; 908 } 909 QDateTime when ( * this , QTime ( 23 , 59 , 59 , 999 ), spec ); 910 if (! when . isValid ()) 911 when = toLatest ( day: * this , form: when ); 912 return when . isValid () ? when : QDateTime ( ); 913} 915 # if QT_CONFIG (timezone) 916 /*! 917 \overload 918 \since 5.14 919 */ 920 QDateTime QDate :: endOfDay ( const QTimeZone & zone ) const 921{ 922 if (! inDateTimeRange ( jd , start: false ) || ! zone . isValid ()) 923 return QDateTime ( ); 925 QDateTime when ( * this , QTime ( 23 , 59 , 59 , 999 ), zone ); 926 if ( when . isValid ()) 927 return when ; 929 // The end of the day must have fallen in a spring-forward's gap; find the spring-forward: 930 if ( zone . hasTransitions ()) { 931 QTimeZone :: OffsetData tran = zone . nextTransition ( afterDateTime: QDateTime ( * this , QTime ( 0 , 0 ), zone )); 932 const QDateTime & at = tran . atUtc . toTimeZone ( toZone: zone ); 933 if ( at . isValid () && at . date () == * this ) 934 return at ; 935 } 937 when = toLatest ( day: * this , form: when ); 938 return when . isValid () ? when : QDateTime ( ); 939} 940 # endif // timezone 942 # if QT_DEPRECATED_SINCE (5, 11) && QT_CONFIG (textdate) 944 /*! 945 \since 4.5 946 \deprecated 948 Returns the short name of the \a month for the representation specified 949 by \a type. 951 The months are enumerated using the following convention: 953 \list 954 \li 1 = "Jan" 955 \li 2 = "Feb" 956 \li 3 = "Mar" 957 \li 4 = "Apr" 958 \li 5 = "May" 959 \li 6 = "Jun" 960 \li 7 = "Jul" 961 \li 8 = "Aug" 962 \li 9 = "Sep" 963 \li 10 = "Oct" 964 \li 11 = "Nov" 965 \li 12 = "Dec" 966 \endlist 968 The month names will be localized according to the system's 969 locale settings, i.e. using QLocale::system(). 971 Returns an empty string if the date is invalid. 973 \sa toString(), longMonthName(), shortDayName(), longDayName() 974 */ 976 QString QDate :: shortMonthName ( int month , QDate :: MonthNameType type ) 977{ 978 switch ( type ) { 979 case QDate :: DateFormat : 980 return QCalendar ( ). monthName ( locale: QLocale :: system (), month , 981 year: QCalendar :: Unspecified , format: QLocale :: ShortFormat ); 982 case QDate :: StandaloneFormat : 983 return QCalendar ( ). standaloneMonthName ( locale: QLocale :: system (), month , 984 year: QCalendar :: Unspecified , format: QLocale :: ShortFormat ); 985 } 986 return QString ( ); 987} 989 /*! 990 \since 4.5 991 \deprecated 993 Returns the long name of the \a month for the representation specified 994 by \a type. 996 The months are enumerated using the following convention: 998 \list 999 \li 1 = "January" 1000 \li 2 = "February" 1001 \li 3 = "March" 1002 \li 4 = "April" 1003 \li 5 = "May" 1004 \li 6 = "June" 1005 \li 7 = "July" 1006 \li 8 = "August" 1007 \li 9 = "September" 1008 \li 10 = "October" 1009 \li 11 = "November" 1010 \li 12 = "December" 1011 \endlist 1013 The month names will be localized according to the system's 1014 locale settings, i.e. using QLocale::system(). 1016 Returns an empty string if the date is invalid. 1018 \sa toString(), shortMonthName(), shortDayName(), longDayName() 1019 */ 1021 QString QDate :: longMonthName ( int month , MonthNameType type ) 1022{ 1023 switch ( type ) { 1024 case QDate :: DateFormat : 1025 return QCalendar ( ). monthName ( locale: QLocale :: system (), month , 1026 year: QCalendar :: Unspecified , format: QLocale :: LongFormat ); 1027 case QDate :: StandaloneFormat : 1028 return QCalendar ( ). standaloneMonthName ( locale: QLocale :: system (), month , 1029 year: QCalendar :: Unspecified , format: QLocale :: LongFormat ); 1030 } 1031 return QString ( ); 1032} 1034 /*! 1035 \since 4.5 1036 \deprecated 1038 Returns the short name of the \a weekday for the representation specified 1039 by \a type. 1041 The days are enumerated using the following convention: 1043 \list 1044 \li 1 = "Mon" 1045 \li 2 = "Tue" 1046 \li 3 = "Wed" 1047 \li 4 = "Thu" 1048 \li 5 = "Fri" 1049 \li 6 = "Sat" 1050 \li 7 = "Sun" 1051 \endlist 1053 The day names will be localized according to the system's 1054 locale settings, i.e. using QLocale::system(). 1056 Returns an empty string if the date is invalid. 1058 \sa toString(), shortMonthName(), longMonthName(), longDayName() 1059 */ 1061 QString QDate :: shortDayName ( int weekday , MonthNameType type ) 1062{ 1063 switch ( type ) { 1064 case QDate :: DateFormat : 1065 return QLocale :: system (). dayName ( weekday , format: QLocale :: ShortFormat ); 1066 case QDate :: StandaloneFormat : 1067 return QLocale :: system (). standaloneDayName ( weekday , format: QLocale :: ShortFormat ); 1068 } 1069 return QString ( ); 1070} 1072 /*! 1073 \since 4.5 1074 \deprecated 1076 Returns the long name of the \a weekday for the representation specified 1077 by \a type. 1079 The days are enumerated using the following convention: 1081 \list 1082 \li 1 = "Monday" 1083 \li 2 = "Tuesday" 1084 \li 3 = "Wednesday" 1085 \li 4 = "Thursday" 1086 \li 5 = "Friday" 1087 \li 6 = "Saturday" 1088 \li 7 = "Sunday" 1089 \endlist 1091 The day names will be localized according to the system's 1092 locale settings, i.e. using QLocale::system(). 1094 Returns an empty string if the date is invalid. 1096 \sa toString(), shortDayName(), shortMonthName(), longMonthName() 1097 */ 1099 QString QDate :: longDayName ( int weekday , MonthNameType type ) 1100{ 1101 switch ( type ) { 1102 case QDate :: DateFormat : 1103 return QLocale :: system (). dayName ( weekday , format: QLocale :: LongFormat ); 1104 case QDate :: StandaloneFormat : 1105 return QLocale :: system (). standaloneDayName ( weekday , format: QLocale :: LongFormat ); 1106 } 1107 return QString ( ); 1108} 1109 # endif // textdate && deprecated 1111 # if QT_CONFIG (datestring) // depends on, so implies, textdate 1113 static QString toStringTextDate ( QDate date ) 1114{ 1115 if ( date . isValid ()) { 1116 QCalendar cal ; // Always Gregorian 1117 const auto parts = cal . partsFromDate ( date ); 1118 if ( parts . isValid ()) { 1119 const QLatin1Char sp ( ' ' ); 1120 return QLocale :: system (). dayName ( cal . dayOfWeek ( date ), format: QLocale :: ShortFormat ) + sp 1121 + cal . monthName ( locale: QLocale :: system (), month: parts . month , year: parts . year , format: QLocale :: ShortFormat ) 1122 + sp + QString :: number ( parts . day ) + sp + QString :: number ( parts . year ); 1123 } 1124 } 1125 return QString ( ); 1126} 1128 static QString toStringIsoDate ( QDate date ) 1129{ 1130 const auto parts = QCalendar ( ). partsFromDate ( date ); 1131 if ( parts . isValid () && parts . year >= 0 && parts . year <= 9999 ) 1132 return QString :: asprintf ( format: "%04d-%02d-%02d" , parts . year , parts . month , parts . day ); 1133 return QString ( ); 1134} 1136 /*! 1137 \overload 1139 Returns the date as a string. The \a format parameter determines the format 1140 of the string. 1142 If the \a format is Qt::TextDate, the string is formatted in the default 1143 way. The day and month names will be localized names using the system 1144 locale, i.e. QLocale::system(). An example of this formatting 1145 is "Sat May 20 1995". 1147 If the \a format is Qt::ISODate, the string format corresponds 1148 to the ISO 8601 extended specification for representations of 1149 dates and times, taking the form yyyy-MM-dd, where yyyy is the 1150 year, MM is the month of the year (between 01 and 12), and dd is 1151 the day of the month between 01 and 31. 1153 The \a format options Qt::SystemLocaleDate, Qt::SystemLocaleShortDate and 1154 Qt::SystemLocaleLongDate shall be removed in Qt 6. Their use should be 1155 replaced with 1156 \l {QLocale::toString()}{QLocale::system().toString(date, QLocale::ShortFormat)} or 1157 \l {QLocale::toString()}{QLocale::system().toString(date, QLocale::LongFormat)}. 1159 The \a format options Qt::LocaleDate, Qt::DefaultLocaleShortDate and 1160 Qt::DefaultLocaleLongDate shall be removed in Qt 6. Their use should be 1161 replaced with 1162 \l {QLocale::toString()}{QLocale().toString(date, QLocale::ShortFormat)} or 1163 \l {QLocale::toString()}{QLocale().toString(date, QLocale::LongFormat)}. 1165 If the \a format is Qt::RFC2822Date, the string is formatted in 1166 an \l {RFC 2822} compatible way. An example of this formatting is 1167 "20 May 1995". 1169 If the date is invalid, an empty string will be returned. 1171 \warning The Qt::ISODate format is only valid for years in the 1172 range 0 to 9999. 1174 \sa fromString(), QLocale::toString() 1175 */ 1176 QString QDate :: toString ( Qt:: DateFormat format ) const 1177{ 1178 if (! isValid ()) 1179 return QString ( ); 1181 switch ( format ) { 1182 # if QT_DEPRECATED_SINCE (5, 15) 1183 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED 1184 case Qt:: SystemLocaleDate : 1185 case Qt:: SystemLocaleShortDate : 1186 return QLocale :: system (). toString ( date: * this , format: QLocale :: ShortFormat ); 1187 case Qt:: SystemLocaleLongDate : 1188 return QLocale :: system (). toString ( date: * this , format: QLocale :: LongFormat ); 1189 case Qt:: LocaleDate : 1190 case Qt:: DefaultLocaleShortDate : 1191 return QLocale ( ). toString ( date: * this , format: QLocale :: ShortFormat ); 1192 case Qt:: DefaultLocaleLongDate : 1193 return QLocale ( ). toString ( date: * this , format: QLocale :: LongFormat ); 1194 QT_WARNING_POP 1195 # endif // 5.15 1196 case Qt:: RFC2822Date : 1197 return QLocale :: c (). toString ( date: * this , formatStr: QStringView ( u "dd MMM yyyy" )); 1198 default : 1199 case Qt:: TextDate : 1200 return toStringTextDate ( date: * this ); 1201 case Qt:: ISODate : 1202 case Qt:: ISODateWithMs : 1203 // No calendar dependence 1204 return toStringIsoDate ( date: * this ); 1205 } 1206} 1208 # if QT_DEPRECATED_SINCE (5, 15) 1209 QString QDate :: toString ( Qt:: DateFormat format , QCalendar cal ) const 1210{ 1211 if (! isValid ()) 1212 return QString ( ); 1214 switch ( format ) { 1215 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED 1216 case Qt:: SystemLocaleDate : 1217 case Qt:: SystemLocaleShortDate : 1218 return QLocale :: system (). toString ( date: * this , format: QLocale :: ShortFormat , cal ); 1219 case Qt:: SystemLocaleLongDate : 1220 return QLocale :: system (). toString ( date: * this , format: QLocale :: LongFormat , cal ); 1221 case Qt:: LocaleDate : 1222 case Qt:: DefaultLocaleShortDate : 1223 return QLocale ( ). toString ( date: * this , format: QLocale :: ShortFormat , cal ); 1224 case Qt:: DefaultLocaleLongDate : 1225 return QLocale ( ). toString ( date: * this , format: QLocale :: LongFormat , cal ); 1226 QT_WARNING_POP 1227 case Qt:: RFC2822Date : 1228 return QLocale :: c (). toString ( date: * this , formatStr: QStringView ( u "dd MMM yyyy" ), cal ); 1229 default : 1230 case Qt:: TextDate : 1231 return toStringTextDate ( date: * this ); 1232 case Qt:: ISODate : 1233 case Qt:: ISODateWithMs : 1234 // No calendar dependence 1235 return toStringIsoDate ( date: * this ); 1236 } 1237} 1238 # endif // 5.15 1240 /*! 1241 \fn QString QDate::toString(const QString &format) const 1242 \fn QString QDate::toString(const QString &format, QCalendar cal) const 1243 \fn QString QDate::toString(QStringView format) const 1244 \fn QString QDate::toString(QStringView format, QCalendar cal) const 1246 Returns the date as a string. The \a format parameter determines the format 1247 of the result string. If \a cal is supplied, it determines the calendar used 1248 to represent the date; it defaults to Gregorian. 1250 These expressions may be used: 1252 \table 1253 \header \li Expression \li Output 1254 \row \li d \li The day as a number without a leading zero (1 to 31) 1255 \row \li dd \li The day as a number with a leading zero (01 to 31) 1256 \row \li ddd 1257 \li The abbreviated localized day name (e.g. 'Mon' to 'Sun'). 1258 Uses the system locale to localize the name, i.e. QLocale::system(). 1259 \row \li dddd 1260 \li The long localized day name (e.g. 'Monday' to 'Sunday'). 1261 Uses the system locale to localize the name, i.e. QLocale::system(). 1262 \row \li M \li The month as a number without a leading zero (1 to 12) 1263 \row \li MM \li The month as a number with a leading zero (01 to 12) 1264 \row \li MMM 1265 \li The abbreviated localized month name (e.g. 'Jan' to 'Dec'). 1266 Uses the system locale to localize the name, i.e. QLocale::system(). 1267 \row \li MMMM 1268 \li The long localized month name (e.g. 'January' to 'December'). 1269 Uses the system locale to localize the name, i.e. QLocale::system(). 1270 \row \li yy \li The year as a two digit number (00 to 99) 1271 \row \li yyyy \li The year as a four digit number. If the year is negative, 1272 a minus sign is prepended, making five characters. 1273 \endtable 1275 Any sequence of characters enclosed in single quotes will be included 1276 verbatim in the output string (stripped of the quotes), even if it contains 1277 formatting characters. Two consecutive single quotes ("''") are replaced by 1278 a single quote in the output. All other characters in the format string are 1279 included verbatim in the output string. 1281 Formats without separators (e.g. "ddMM") are supported but must be used with 1282 care, as the resulting strings aren't always reliably readable (e.g. if "dM" 1283 produces "212" it could mean either the 2nd of December or the 21st of 1284 February). 1286 Example format strings (assuming that the QDate is the 20 July 1287 1969): 1289 \table 1290 \header \li Format \li Result 1291 \row \li dd.MM.yyyy \li 20.07.1969 1292 \row \li ddd MMMM d yy \li Sun July 20 69 1293 \row \li 'The day is' dddd \li The day is Sunday 1294 \endtable 1296 If the datetime is invalid, an empty string will be returned. 1298 \note If localized month and day names are desired, please switch to using 1299 QLocale::system().toString() as QDate methods shall change to use English (C 1300 locale) names at Qt 6. 1302 \sa fromString(), QDateTime::toString(), QTime::toString(), QLocale::toString() 1304 */ 1305 QString QDate :: toString ( QStringView format ) const 1306{ 1307 return toString ( format , cal: QCalendar ( )); 1308} 1310 QString QDate :: toString ( QStringView format , QCalendar cal ) const 1311{ 1312 return QLocale :: system (). toString ( date: * this , formatStr: format , cal ); // QLocale::c() ### Qt6 1313} 1315 # if QT_STRINGVIEW_LEVEL < 2 1316 QString QDate :: toString ( const QString & format ) const 1317{ 1318 return toString ( format: qToStringViewIgnoringNull ( s: format ), cal: QCalendar ( )); 1319} 1321 QString QDate :: toString ( const QString & format , QCalendar cal ) const 1322{ 1323 return toString ( format: qToStringViewIgnoringNull ( s: format ), cal ); 1324} 1325 # endif 1327 # endif // datestring 1329 /*! 1330 \fn bool QDate::setYMD(int y, int m, int d) 1332 \deprecated in 5.0, use setDate() instead. 1334 Sets the date's year \a y, month \a m, and day \a d. 1336 If \a y is in the range 0 to 99, it is interpreted as 1900 to 1337 1999. 1338 Returns \c false if the date is invalid. 1340 Use setDate() instead. 1341 */ 1343 /*! 1344 \since 4.2 1346 Sets this to represent the date, in the Gregorian calendar, with the given 1347 \a year, \a month and \a day numbers. Returns true if the resulting date is 1348 valid, otherwise it sets this to represent an invalid date and returns 1349 false. 1351 \sa isValid(), QCalendar::dateFromParts() 1352 */ 1353 bool QDate :: setDate ( int year , int month , int day ) 1354{ 1355 if ( QGregorianCalendar :: julianFromParts ( year , month , day , jd: & jd )) 1356 return true ; 1358 jd = nullJd (); 1359 return false ; 1360} 1362 /*! 1363 \since 5.14 1365 Sets this to represent the date, in the given calendar \a cal, with the 1366 given \a year, \a month and \a day numbers. Returns true if the resulting 1367 date is valid, otherwise it sets this to represent an invalid date and 1368 returns false. 1370 \sa isValid(), QCalendar::dateFromParts() 1371 */ 1373 bool QDate :: setDate ( int year , int month , int day , QCalendar cal ) 1374{ 1375 * this = QDate ( year , month , day , cal ); 1376 return isValid (); 1377} 1379 /*! 1380 \since 4.5 1382 Extracts the date's year, month, and day, and assigns them to 1383 *\a year, *\a month, and *\a day. The pointers may be null. 1385 Returns 0 if the date is invalid. 1387 \note In Qt versions prior to 5.7, this function is marked as non -\c {const}. 1389 \sa year(), month(), day(), isValid(), QCalendar::partsFromDate() 1390 */ 1391 void QDate :: getDate ( int * year , int * month , int * day ) const 1392{ 1393 QCalendar :: YearMonthDay parts ; // invalid by default 1394 if ( isValid ()) 1395 parts = QGregorianCalendar :: partsFromJulian ( jd ); 1397 const bool ok = parts . isValid (); 1398 if ( year ) 1399 * year = ok ? parts . year : 0 ; 1400 if ( month ) 1401 * month = ok ? parts . month : 0 ; 1402 if ( day ) 1403 * day = ok ? parts . day : 0 ; 1404} 1406 # if QT_VERSION < QT_VERSION_CHECK (6, 0, 0) 1407 /*! 1408 \overload 1409 \internal 1410 */ 1411 void QDate :: getDate ( int * year , int * month , int * day ) 1412{ 1413 qAsConst ( t&: * this ). getDate ( year , month , day ); 1414} 1415 # endif // < Qt 6 1417 /*! 1418 Returns a QDate object containing a date \a ndays later than the 1419 date of this object (or earlier if \a ndays is negative). 1421 Returns a null date if the current date is invalid or the new date is 1422 out of range. 1424 \sa addMonths(), addYears(), daysTo() 1425 */ 1427 QDate QDate :: addDays ( qint64 ndays ) const 1428{ 1429 if ( isNull ()) 1430 return QDate ( ); 1432 // Due to limits on minJd() and maxJd() we know that any overflow 1433 // will be invalid and caught by fromJulianDay(). 1434 return fromJulianDay ( jd_: jd + ndays ); 1435} 1437 /*! 1438 Returns a QDate object containing a date \a nmonths later than the 1439 date of this object (or earlier if \a nmonths is negative). 1441 Uses \a cal as calendar, if supplied, else the Gregorian calendar. 1443 \note If the ending day/month combination does not exist in the resulting 1444 month/year, this function will return a date that is the latest valid date 1445 in the selected month. 1447 \sa addDays(), addYears() 1448 */ 1450 QDate QDate :: addMonths ( int nmonths , QCalendar cal ) const 1451{ 1452 if (! isValid ()) 1453 return QDate ( ); 1455 if ( nmonths == 0 ) 1456 return * this ; 1458 auto parts = cal . partsFromDate ( date: * this ); 1460 if (! parts . isValid ()) 1461 return QDate ( ); 1462 Q_ASSERT ( parts . year || cal . hasYearZero ()); 1464 parts . month += nmonths ; 1465 while ( parts . month <= 0 ) { 1466 if (-- parts . year || cal . hasYearZero ()) 1467 parts . month += cal . monthsInYear ( year: parts . year ); 1468 } 1469 int count = cal . monthsInYear ( year: parts . year ); 1470 while ( parts . month > count ) { 1471 parts . month -= count ; 1472 count = (++ parts . year || cal . hasYearZero ()) ? cal . monthsInYear ( year: parts . year ) : 0 ; 1473 } 1475 return fixedDate ( parts: std:: move ( parts ), cal ); 1476} 1478 /*! 1479 \overload 1480 */ 1482 QDate QDate :: addMonths ( int nmonths ) const 1483{ 1484 if ( isNull ()) 1485 return QDate ( ); 1487 if ( nmonths == 0 ) 1488 return * this ; 1490 auto parts = QGregorianCalendar :: partsFromJulian ( jd ); 1492 if (! parts . isValid ()) 1493 return QDate ( ); 1494 Q_ASSERT ( parts . year ); 1496 parts . month += nmonths ; 1497 while ( parts . month <= 0 ) { 1498 if (-- parts . year ) // skip over year 0 1499 parts . month += 12 ; 1500 } 1501 while ( parts . month > 12 ) { 1502 parts . month -= 12 ; 1503 if (!++ parts . year ) // skip over year 0 1504 ++ parts . year ; 1505 } 1507 return fixedDate ( parts: std:: move ( parts )); 1508} 1510 /*! 1511 Returns a QDate object containing a date \a nyears later than the 1512 date of this object (or earlier if \a nyears is negative). 1514 Uses \a cal as calendar, if supplied, else the Gregorian calendar. 1516 \note If the ending day/month combination does not exist in the resulting 1517 year (e.g., for the Gregorian calendar, if the date was Feb 29 and the final 1518 year is not a leap year), this function will return a date that is the 1519 latest valid date in the given month (in the example, Feb 28). 1521 \sa addDays(), addMonths() 1522 */ 1524 QDate QDate :: addYears ( int nyears , QCalendar cal ) const 1525{ 1526 if (! isValid ()) 1527 return QDate ( ); 1529 auto parts = cal . partsFromDate ( date: * this ); 1530 if (! parts . isValid ()) 1531 return QDate ( ); 1533 int old_y = parts . year ; 1534 parts . year += nyears ; 1536 // If we just crossed (or hit) a missing year zero, adjust year by +/- 1: 1537 if (! cal . hasYearZero () && (( old_y > 0 ) != ( parts . year > 0 ) || ! parts . year )) 1538 parts . year += nyears > 0 ? + 1 : - 1 ; 1540 return fixedDate ( parts: std:: move ( parts ), cal ); 1541} 1543 /*! 1544 \overload 1545 */ 1547 QDate QDate :: addYears ( int nyears ) const 1548{ 1549 if ( isNull ()) 1550 return QDate ( ); 1552 auto parts = QGregorianCalendar :: partsFromJulian ( jd ); 1553 if (! parts . isValid ()) 1554 return QDate ( ); 1556 int old_y = parts . year ; 1557 parts . year += nyears ; 1559 // If we just crossed (or hit) a missing year zero, adjust year by +/- 1: 1560 if (( old_y > 0 ) != ( parts . year > 0 ) || ! parts . year ) 1561 parts . year += nyears > 0 ? + 1 : - 1 ; 1563 return fixedDate ( parts: std:: move ( parts )); 1564} 1566 /*! 1567 Returns the number of days from this date to \a d (which is 1568 negative if \a d is earlier than this date). 1570 Returns 0 if either date is invalid. 1572 Example: 1573 \snippet code/src_corelib_tools_qdatetime.cpp 0 1575 \sa addDays() 1576 */ 1578 qint64 QDate :: daysTo ( const QDate & d ) const 1579{ 1580 if ( isNull () || d . isNull ()) 1581 return 0 ; 1583 // Due to limits on minJd() and maxJd() we know this will never overflow 1584 return d . jd - jd ; 1585} 1588 /*! 1589 \fn bool QDate::operator==(const QDate &d) const 1591 Returns \c true if this date and \a d represent the same day, otherwise 1592 \c false. 1593 */ 1595 /*! 1596 \fn bool QDate::operator!=(const QDate &d) const 1598 Returns \c true if this date is different from \a d; otherwise 1599 returns \c false. 1601 \sa operator==() 1602 */ 1604 /*! 1605 \fn bool QDate::operator<(const QDate &d) const 1607 Returns \c true if this date is earlier than \a d; otherwise returns 1608 false. 1609 */ 1611 /*! 1612 \fn bool QDate::operator<=(const QDate &d) const 1614 Returns \c true if this date is earlier than or equal to \a d; 1615 otherwise returns \c false. 1616 */ 1618 /*! 1619 \fn bool QDate::operator>(const QDate &d) const 1621 Returns \c true if this date is later than \a d; otherwise returns 1622 false. 1623 */ 1625 /*! 1626 \fn bool QDate::operator>=(const QDate &d) const 1628 Returns \c true if this date is later than or equal to \a d; 1629 otherwise returns \c false. 1630 */ 1632 /*! 1633 \fn QDate::currentDate() 1634 Returns the current date, as reported by the system clock. 1636 \sa QTime::currentTime(), QDateTime::currentDateTime() 1637 */ 1639 # if QT_CONFIG (datestring) // depends on, so implies, textdate 1640 namespace { 1642 struct ParsedInt { int value = 0 ; bool ok = false ; }; 1644 /* 1645 /internal 1647 Read an int that must be the whole text. QStringRef::toInt() will ignore 1648 spaces happily; but ISO date format should not. 1649 */ 1650 ParsedInt readInt ( QStringView text ) 1651{ 1652 ParsedInt result ; 1653 for ( const auto & ch : text ) { 1654 if ( ch . isSpace ()) 1655 return result ; 1656 } 1657 result . value = QLocale :: c (). toInt ( s: text , ok: & result . ok ); 1658 return result ; 1659} 1661} 1663 /*! 1664 Returns the QDate represented by the \a string, using the 1665 \a format given, or an invalid date if the string cannot be 1666 parsed. 1668 Note for Qt::TextDate: It is recommended that you use the English short 1669 month names (e.g. "Jan"). Although localized month names can also be used in 1670 Qt 5, they depend on the user's locale settings. 1672 \note Support for localized dates, including the format options 1673 Qt::SystemLocaleDate, Qt::SystemLocaleShortDate, Qt::SystemLocaleLongDate, 1674 Qt::LocaleDate, Qt::DefaultLocaleShortDate, and Qt::DefaultLocaleLongDate, 1675 shall be removed in Qt 6. Use QLocale::toDate() instead. 1677 \sa toString(), QLocale::toDate() 1678 */ 1680 QDate QDate :: fromString ( const QString & string , Qt:: DateFormat format ) 1681{ 1682 if ( string . isEmpty ()) 1683 return QDate ( ); 1685 switch ( format ) { 1686 # if QT_DEPRECATED_SINCE (5, 15) 1687 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED 1688 case Qt:: SystemLocaleDate : 1689 case Qt:: SystemLocaleShortDate : 1690 return QLocale :: system (). toDate ( string , QLocale :: ShortFormat ); 1691 case Qt:: SystemLocaleLongDate : 1692 return QLocale :: system (). toDate ( string , QLocale :: LongFormat ); 1693 case Qt:: LocaleDate : 1694 case Qt:: DefaultLocaleShortDate : 1695 return QLocale ( ). toDate ( string , QLocale :: ShortFormat ); 1696 case Qt:: DefaultLocaleLongDate : 1697 return QLocale ( ). toDate ( string , QLocale :: LongFormat ); 1698 QT_WARNING_POP 1699 # endif // 5.15 1700 case Qt:: RFC2822Date : 1701 return rfcDateImpl ( s: string ). date ; 1702 default : 1703 case Qt:: TextDate : { 1704 QVector < QStringRef > parts = string . splitRef ( sep: QLatin1Char ( ' ' ), behavior: Qt:: SkipEmptyParts ); 1706 if ( parts . count () != 4 ) 1707 return QDate ( ); 1709 bool ok = false ; 1710 int year = parts . at ( i: 3 ). toInt ( ok: & ok ); 1711 int day = ok ? parts . at ( i: 2 ). toInt ( ok: & ok ) : 0 ; 1712 if (! ok || ! day ) 1713 return QDate ( ); 1715 const int month = fromShortMonthName ( monthName: parts . at ( i: 1 ), year ); 1716 if ( month == - 1 ) // Month name matches no English or localised name. 1717 return QDate ( ); 1719 return QDate ( year , month , day ); 1720 } 1721 case Qt:: ISODate : 1722 // Semi-strict parsing, must be long enough and have punctuators as separators 1723 if ( string . size () >= 10 && string . at ( i: 4 ). isPunct () && string . at ( i: 7 ). isPunct () 1724 && ( string . size () == 10 || ! string . at ( i: 10 ). isDigit ())) { 1725 QStringView view ( string ); 1726 const ParsedInt year = readInt ( text: view . mid ( pos: 0 , n: 4 )); 1727 const ParsedInt month = readInt ( text: view . mid ( pos: 5 , n: 2 )); 1728 const ParsedInt day = readInt ( text: view . mid ( pos: 8 , n: 2 )); 1729 if ( year . ok && year . value > 0 && year . value <= 9999 && month . ok && day . ok ) 1730 return QDate ( year . value , month . value , day . value ); 1731 } 1732 break ; 1733 } 1734 return QDate ( ); 1735} 1737 /*! 1738 Returns the QDate represented by the \a string, using the \a 1739 format given, or an invalid date if the string cannot be parsed. 1741 Uses \a cal as calendar if supplied, else the Gregorian calendar. Ranges of 1742 values in the format descriptions below are for the latter; they may be 1743 different for other calendars. 1745 These expressions may be used for the format: 1747 \table 1748 \header \li Expression \li Output 1749 \row \li d \li The day as a number without a leading zero (1 to 31) 1750 \row \li dd \li The day as a number with a leading zero (01 to 31) 1751 \row \li ddd 1752 \li The abbreviated localized day name (e.g. 'Mon' to 'Sun'). 1753 Uses the system locale to localize the name, i.e. QLocale::system(). 1754 \row \li dddd 1755 \li The long localized day name (e.g. 'Monday' to 'Sunday'). 1756 Uses the system locale to localize the name, i.e. QLocale::system(). 1757 \row \li M \li The month as a number without a leading zero (1 to 12) 1758 \row \li MM \li The month as a number with a leading zero (01 to 12) 1759 \row \li MMM 1760 \li The abbreviated localized month name (e.g. 'Jan' to 'Dec'). 1761 Uses the system locale to localize the name, i.e. QLocale::system(). 1762 \row \li MMMM 1763 \li The long localized month name (e.g. 'January' to 'December'). 1764 Uses the system locale to localize the name, i.e. QLocale::system(). 1765 \row \li yy \li The year as a two digit number (00 to 99) 1766 \row \li yyyy \li The year as a four digit number, possibly plus a leading 1767 minus sign for negative years. 1768 \endtable 1770 \note Unlike the other version of this function, day and month names must 1771 be given in the user's local language. It is only possible to use the English 1772 names if the user's language is English. 1774 All other input characters will be treated as text. Any non-empty sequence 1775 of characters enclosed in single quotes will also be treated (stripped of 1776 the quotes) as text and not be interpreted as expressions. For example: 1778 \snippet code/src_corelib_tools_qdatetime.cpp 1 1780 If the format is not satisfied, an invalid QDate is returned. The 1781 expressions that don't expect leading zeroes (d, M) will be 1782 greedy. This means that they will use two digits even if this 1783 will put them outside the accepted range of values and leaves too 1784 few digits for other sections. For example, the following format 1785 string could have meant January 30 but the M will grab two 1786 digits, resulting in an invalid date: 1788 \snippet code/src_corelib_tools_qdatetime.cpp 2 1790 For any field that is not represented in the format the following 1791 defaults are used: 1793 \table 1794 \header \li Field \li Default value 1795 \row \li Year \li 1900 1796 \row \li Month \li 1 1797 \row \li Day \li 1 1798 \endtable 1800 The following examples demonstrate the default values: 1802 \snippet code/src_corelib_tools_qdatetime.cpp 3 1804 \note If localized month and day names are used, please switch to using 1805 QLocale::system().toDate() as QDate methods shall change to only recognize 1806 English (C locale) names at Qt 6. 1808 \sa toString(), QDateTime::fromString(), QTime::fromString(), 1809 QLocale::toDate() 1810 */ 1812 QDate QDate :: fromString ( const QString & string , const QString & format , QCalendar cal ) 1813{ 1814 QDate date ; 1815 # if QT_CONFIG (datetimeparser) 1816 QDateTimeParser dt ( QMetaType :: QDate , QDateTimeParser :: FromString , cal ); 1817 // dt.setDefaultLocale(QLocale::c()); ### Qt 6 1818 if ( dt . parseFormat ( format )) 1819 dt . fromString ( text: string , date: & date , time: nullptr ); 1820 # else 1821 Q_UNUSED(string); 1822 Q_UNUSED(format); 1823 Q_UNUSED(cal); 1824 # endif 1825 return date ; 1826} 1828 /*! 1829 \overload 1830 */ 1832 QDate QDate :: fromString ( const QString & string , const QString & format ) 1833{ 1834 return fromString ( string , format , cal: QCalendar ( )); 1835} 1836 # endif // datestring 1838 /*! 1839 \overload 1841 Returns \c true if the specified date (\a year, \a month, and \a day) is 1842 valid in the Gregorian calendar; otherwise returns \c false. 1844 Example: 1845 \snippet code/src_corelib_tools_qdatetime.cpp 4 1847 \sa isNull(), setDate(), QCalendar::isDateValid() 1848 */ 1850 bool QDate :: isValid ( int year , int month , int day ) 1851{ 1852 return QGregorianCalendar :: validParts ( year , month , day ); 1853} 1855 /*! 1856 \fn bool QDate::isLeapYear(int year) 1858 Returns \c true if the specified \a year is a leap year in the Gregorian 1859 calendar; otherwise returns \c false. 1861 \sa QCalendar::isLeapYear() 1862 */ 1864 bool QDate :: isLeapYear ( int y ) 1865{ 1866 return QGregorianCalendar :: leapTest ( year: y ); 1867} 1869 /*! \fn static QDate QDate::fromJulianDay(qint64 jd) 1871 Converts the Julian day \a jd to a QDate. 1873 \sa toJulianDay() 1874 */ 1876 /*! \fn int QDate::toJulianDay() const 1878 Converts the date to a Julian day. 1880 \sa fromJulianDay() 1881 */ 1883 /***************************************************************************** 1884 QTime member functions 1885 *****************************************************************************/ 1887 /*! 1888 \class QTime 1889 \inmodule QtCore 1890 \reentrant 1892 \brief The QTime class provides clock time functions. 1895 A QTime object contains a clock time, which it can express as the numbers of 1896 hours, minutes, seconds, and milliseconds since midnight. It provides 1897 functions for comparing times and for manipulating a time by adding a number 1898 of milliseconds. 1900 QTime uses the 24-hour clock format; it has no concept of AM/PM. 1901 Unlike QDateTime, QTime knows nothing about time zones or 1902 daylight-saving time (DST). 1904 A QTime object is typically created either by giving the number of hours, 1905 minutes, seconds, and milliseconds explicitly, or by using the static 1906 function currentTime(), which creates a QTime object that represents the 1907 system's local time. 1909 The hour(), minute(), second(), and msec() functions provide 1910 access to the number of hours, minutes, seconds, and milliseconds 1911 of the time. The same information is provided in textual format by 1912 the toString() function. 1914 The addSecs() and addMSecs() functions provide the time a given 1915 number of seconds or milliseconds later than a given time. 1916 Correspondingly, the number of seconds or milliseconds 1917 between two times can be found using secsTo() or msecsTo(). 1919 QTime provides a full set of operators to compare two QTime 1920 objects; an earlier time is considered smaller than a later one; 1921 if A.msecsTo(B) is positive, then A < B. 1923 \sa QDate, QDateTime 1924 */ 1926 /*! 1927 \fn QTime::QTime() 1929 Constructs a null time object. For a null time, isNull() returns \c true and 1930 isValid() returns \c false. If you need a zero time, use QTime(0, 0). For 1931 the start of a day, see QDate::startOfDay(). 1933 \sa isNull(), isValid() 1934 */ 1936 /*! 1937 Constructs a time with hour \a h, minute \a m, seconds \a s and 1938 milliseconds \a ms. 1940 \a h must be in the range 0 to 23, \a m and \a s must be in the 1941 range 0 to 59, and \a ms must be in the range 0 to 999. 1943 \sa isValid() 1944 */ 1946 QTime :: QTime ( int h , int m , int s , int ms ) 1947{ 1948 setHMS ( h , m , s , ms ); 1949} 1952 /*! 1953 \fn bool QTime::isNull() const 1955 Returns \c true if the time is null (i.e., the QTime object was 1956 constructed using the default constructor); otherwise returns 1957 false. A null time is also an invalid time. 1959 \sa isValid() 1960 */ 1962 /*! 1963 Returns \c true if the time is valid; otherwise returns \c false. For example, 1964 the time 23:30:55.746 is valid, but 24:12:30 is invalid. 1966 \sa isNull() 1967 */ 1969 bool QTime :: isValid () const 1970{ 1971 return mds > NullTime && mds < MSECS_PER_DAY ; 1972} 1975 /*! 1976 Returns the hour part (0 to 23) of the time. 1978 Returns -1 if the time is invalid. 1980 \sa minute(), second(), msec() 1981 */ 1983 int QTime :: hour () const 1984{ 1985 if (! isValid ()) 1986 return - 1 ; 1988 return ds () / MSECS_PER_HOUR ; 1989} 1991 /*! 1992 Returns the minute part (0 to 59) of the time. 1994 Returns -1 if the time is invalid. 1996 \sa hour(), second(), msec() 1997 */ 1999 int QTime :: minute () const 2000{ 2001 if (! isValid ()) 2002 return - 1 ; 2004 return ( ds () % MSECS_PER_HOUR ) / MSECS_PER_MIN ; 2005} 2007 /*! 2008 Returns the second part (0 to 59) of the time. 2010 Returns -1 if the time is invalid. 2012 \sa hour(), minute(), msec() 2013 */ 2015 int QTime :: second () const 2016{ 2017 if (! isValid ()) 2018 return - 1 ; 2020 return ( ds () / 1000 )% SECS_PER_MIN ; 2021} 2023 /*! 2024 Returns the millisecond part (0 to 999) of the time. 2026 Returns -1 if the time is invalid. 2028 \sa hour(), minute(), second() 2029 */ 2031 int QTime :: msec () const 2032{ 2033 if (! isValid ()) 2034 return - 1 ; 2036 return ds () % 1000 ; 2037} 2039 # if QT_CONFIG (datestring) // depends on, so implies, textdate 2040 /*! 2041 \overload 2043 Returns the time as a string. The \a format parameter determines 2044 the format of the string. 2046 If \a format is Qt::TextDate, the string format is HH:mm:ss; 2047 e.g. 1 second before midnight would be "23:59:59". 2049 If \a format is Qt::ISODate, the string format corresponds to the 2050 ISO 8601 extended specification for representations of dates, 2051 represented by HH:mm:ss. To include milliseconds in the ISO 8601 2052 date, use the \a format Qt::ISODateWithMs, which corresponds to 2053 HH:mm:ss.zzz. 2055 The \a format options Qt::SystemLocaleDate:, Qt::SystemLocaleShortDate and 2056 Qt::SystemLocaleLongDate shall be removed in Qt 6. Their use should be 2057 replaced with: 2058 \l {QLocale::toString()}{QLocale::system().toString(time, QLocale::ShortFormat)} or 2059 \l {QLocale::toString()}{QLocale::system().toString(time, QLocale::LongFormat)}. 2061 The \a format options Qt::LocaleDate, Qt::DefaultLocaleShortDate and 2062 Qt::DefaultLocaleLongDate shall be removed in Qt 6. Their use should be 2063 replaced with: 2064 \l {QLocale::toString()}{QLocale().toString(time, QLocale::ShortFormat)} or 2065 \l {QLocale::toString()}{QLocale().toString(time, QLocale::LongFormat)}. 2067 If the \a format is Qt::RFC2822Date, the string is formatted in 2068 an \l {RFC 2822} compatible way. An example of this formatting is 2069 "23:59:20". 2071 If the time is invalid, an empty string will be returned. 2073 \sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString() 2074 */ 2076 QString QTime :: toString ( Qt:: DateFormat format ) const 2077{ 2078 if (! isValid ()) 2079 return QString ( ); 2081 switch ( format ) { 2082 # if QT_DEPRECATED_SINCE (5, 15) 2083 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED 2084 case Qt:: SystemLocaleDate : 2085 case Qt:: SystemLocaleShortDate : 2086 return QLocale :: system (). toString ( time: * this , format: QLocale :: ShortFormat ); 2087 case Qt:: SystemLocaleLongDate : 2088 return QLocale :: system (). toString ( time: * this , format: QLocale :: LongFormat ); 2089 case Qt:: LocaleDate : 2090 case Qt:: DefaultLocaleShortDate : 2091 return QLocale ( ). toString ( time: * this , format: QLocale :: ShortFormat ); 2092 case Qt:: DefaultLocaleLongDate : 2093 return QLocale ( ). toString ( time: * this , format: QLocale :: LongFormat ); 2094 QT_WARNING_POP 2095 # endif // 5.15 2096 case Qt:: ISODateWithMs : 2097 return QString :: asprintf ( format: "%02d:%02d:%02d.%03d" , hour (), minute (), second (), msec ()); 2098 case Qt:: RFC2822Date : 2099 case Qt:: ISODate : 2100 case Qt:: TextDate : 2101 default : 2102 return QString :: asprintf ( format: "%02d:%02d:%02d" , hour (), minute (), second ()); 2103 } 2104} 2106 /*! 2107 \fn QString QTime::toString(const QString &format) const 2108 \fn QString QTime::toString(QStringView format) const 2110 Returns the time as a string. The \a format parameter determines 2111 the format of the result string. 2113 These expressions may be used: 2115 \table 2116 \header \li Expression \li Output 2117 \row \li h 2118 \li The hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display) 2119 \row \li hh 2120 \li The hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display) 2121 \row \li H 2122 \li The hour without a leading zero (0 to 23, even with AM/PM display) 2123 \row \li HH 2124 \li The hour with a leading zero (00 to 23, even with AM/PM display) 2125 \row \li m \li The minute without a leading zero (0 to 59) 2126 \row \li mm \li The minute with a leading zero (00 to 59) 2127 \row \li s \li The whole second, without any leading zero (0 to 59) 2128 \row \li ss \li The whole second, with a leading zero where applicable (00 to 59) 2129 \row \li z \li The fractional part of the second, to go after a decimal 2130 point, without trailing zeroes (0 to 999). Thus "\c{s.z}" 2131 reports the seconds to full available (millisecond) precision 2132 without trailing zeroes. 2133 \row \li zzz \li The fractional part of the second, to millisecond 2134 precision, including trailing zeroes where applicable (000 to 999). 2135 \row \li AP or A 2136 \li Use AM/PM display. \e A/AP will be replaced by an upper-case 2137 version of either QLocale::amText() or QLocale::pmText(). 2138 \row \li ap or a 2139 \li Use am/pm display. \e a/ap will be replaced by a lower-case version 2140 of either QLocale::amText() or QLocale::pmText(). 2141 \row \li t \li The timezone (for example "CEST") 2142 \endtable 2144 Any non-empty sequence of characters enclosed in single quotes will be 2145 included verbatim in the output string (stripped of the quotes), even if it 2146 contains formatting characters. Two consecutive single quotes ("''") are 2147 replaced by a single quote in the output. All other characters in the format 2148 string are included verbatim in the output string. 2150 Formats without separators (e.g. "ddMM") are supported but must be used with 2151 care, as the resulting strings aren't always reliably readable (e.g. if "dM" 2152 produces "212" it could mean either the 2nd of December or the 21st of 2153 February). 2155 Example format strings (assuming that the QTime is 14:13:09.042 and the system 2156 locale is \c {en_US}) 2158 \table 2159 \header \li Format \li Result 2160 \row \li hh:mm:ss.zzz \li 14:13:09.042 2161 \row \li h:m:s ap \li 2:13:9 pm 2162 \row \li H:m:s a \li 14:13:9 pm 2163 \endtable 2165 If the time is invalid, an empty string will be returned. 2166 If \a format is empty, the default format "hh:mm:ss" is used. 2168 \note If localized forms of am or pm (the AP, ap, A or a formats) are 2169 desired, please switch to using QLocale::system().toString() as QTime 2170 methods shall change to use English (C locale) at Qt 6. 2172 \sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString() 2173 */ 2174 QString QTime :: toString ( QStringView format ) const 2175{ 2176 return QLocale :: system (). toString ( time: * this , formatStr: format ); // QLocale::c() ### Qt6 2177} 2179 # if QT_STRINGVIEW_VERSION < 2 2180 QString QTime :: toString ( const QString & format ) const 2181{ 2182 return toString ( format: qToStringViewIgnoringNull ( s: format )); 2183} 2184 # endif 2186 # endif // datestring 2188 /*! 2189 Sets the time to hour \a h, minute \a m, seconds \a s and 2190 milliseconds \a ms. 2192 \a h must be in the range 0 to 23, \a m and \a s must be in the 2193 range 0 to 59, and \a ms must be in the range 0 to 999. 2194 Returns \c true if the set time is valid; otherwise returns \c false. 2196 \sa isValid() 2197 */ 2199 bool QTime :: setHMS ( int h , int m , int s , int ms ) 2200{ 2201 if (! isValid ( h , m , s , ms )) { 2202 mds = NullTime ; // make this invalid 2203 return false ; 2204 } 2205 mds = ( h * SECS_PER_HOUR + m * SECS_PER_MIN + s )* 1000 + ms ; 2206 return true ; 2207} 2209 /*! 2210 Returns a QTime object containing a time \a s seconds later 2211 than the time of this object (or earlier if \a s is negative). 2213 Note that the time will wrap if it passes midnight. 2215 Returns a null time if this time is invalid. 2217 Example: 2219 \snippet code/src_corelib_tools_qdatetime.cpp 5 2221 \sa addMSecs(), secsTo(), QDateTime::addSecs() 2222 */ 2224 QTime QTime :: addSecs ( int s ) const 2225{ 2226 s %= SECS_PER_DAY ; 2227 return addMSecs ( ms: s * 1000 ); 2228} 2230 /*! 2231 Returns the number of seconds from this time to \a t. 2232 If \a t is earlier than this time, the number of seconds returned 2233 is negative. 2235 Because QTime measures time within a day and there are 86400 2236 seconds in a day, the result is always between -86400 and 86400. 2238 secsTo() does not take into account any milliseconds. 2240 Returns 0 if either time is invalid. 2242 \sa addSecs(), QDateTime::secsTo() 2243 */ 2245 int QTime :: secsTo ( const QTime & t ) const 2246{ 2247 if (! isValid () || ! t . isValid ()) 2248 return 0 ; 2250 // Truncate milliseconds as we do not want to consider them. 2251 int ourSeconds = ds () / 1000 ; 2252 int theirSeconds = t . ds () / 1000 ; 2253 return theirSeconds - ourSeconds ; 2254} 2256 /*! 2257 Returns a QTime object containing a time \a ms milliseconds later 2258 than the time of this object (or earlier if \a ms is negative). 2260 Note that the time will wrap if it passes midnight. See addSecs() 2261 for an example. 2263 Returns a null time if this time is invalid. 2265 \sa addSecs(), msecsTo(), QDateTime::addMSecs() 2266 */ 2268 QTime QTime :: addMSecs ( int ms ) const 2269{ 2270 QTime t ; 2271 if ( isValid ()) { 2272 if ( ms < 0 ) { 2273 // %,/ not well-defined for -ve, so always work with +ve. 2274 int negdays = ( MSECS_PER_DAY - ms ) / MSECS_PER_DAY ; 2275 t . mds = ( ds () + ms + negdays * MSECS_PER_DAY ) % MSECS_PER_DAY ; 2276 } else { 2277 t . mds = ( ds () + ms ) % MSECS_PER_DAY ; 2278 } 2279 } 2280 return t ; 2281} 2283 /*! 2284 Returns the number of milliseconds from this time to \a t. 2285 If \a t is earlier than this time, the number of milliseconds returned 2286 is negative. 2288 Because QTime measures time within a day and there are 86400 2289 seconds in a day, the result is always between -86400000 and 2290 86400000 ms. 2292 Returns 0 if either time is invalid. 2294 \sa secsTo(), addMSecs(), QDateTime::msecsTo() 2295 */ 2297 int QTime :: msecsTo ( const QTime & t ) const 2298{ 2299 if (! isValid () || ! t . isValid ()) 2300 return 0 ; 2301 return t . ds () - ds (); 2302} 2305 /*! 2306 \fn bool QTime::operator==(const QTime &t) const 2308 Returns \c true if this time is equal to \a t; otherwise returns \c false. 2309 */ 2311 /*! 2312 \fn bool QTime::operator!=(const QTime &t) const 2314 Returns \c true if this time is different from \a t; otherwise returns \c false. 2315 */ 2317 /*! 2318 \fn bool QTime::operator<(const QTime &t) const 2320 Returns \c true if this time is earlier than \a t; otherwise returns \c false. 2321 */ 2323 /*! 2324 \fn bool QTime::operator<=(const QTime &t) const 2326 Returns \c true if this time is earlier than or equal to \a t; 2327 otherwise returns \c false. 2328 */ 2330 /*! 2331 \fn bool QTime::operator>(const QTime &t) const 2333 Returns \c true if this time is later than \a t; otherwise returns \c false. 2334 */ 2336 /*! 2337 \fn bool QTime::operator>=(const QTime &t) const 2339 Returns \c true if this time is later than or equal to \a t; 2340 otherwise returns \c false. 2341 */ 2343 /*! 2344 \fn QTime QTime::fromMSecsSinceStartOfDay(int msecs) 2346 Returns a new QTime instance with the time set to the number of \a msecs 2347 since the start of the day, i.e. since 00:00:00. 2349 If \a msecs falls outside the valid range an invalid QTime will be returned. 2351 \sa msecsSinceStartOfDay() 2352 */ 2354 /*! 2355 \fn int QTime::msecsSinceStartOfDay() const 2357 Returns the number of msecs since the start of the day, i.e. since 00:00:00. 2359 \sa fromMSecsSinceStartOfDay() 2360 */ 2362 /*! 2363 \fn QTime::currentTime() 2365 Returns the current time as reported by the system clock. 2367 Note that the accuracy depends on the accuracy of the underlying 2368 operating system; not all systems provide 1-millisecond accuracy. 2370 Furthermore, currentTime() only increases within each day; it shall drop by 2371 24 hours each time midnight passes; and, beside this, changes in it may not 2372 correspond to elapsed time, if a daylight-saving transition intervenes. 2374 \sa QDateTime::currentDateTime(), QDateTime::currentDateTimeUtc() 2375 */ 2377 # if QT_CONFIG (datestring) // depends on, so implies, textdate 2379 static QTime fromIsoTimeString ( QStringView string , Qt:: DateFormat format , bool * isMidnight24 ) 2380{ 2381 if ( isMidnight24 ) 2382 * isMidnight24 = false ; 2384 const int size = string . size (); 2385 if ( size < 5 || string . at ( n: 2 ) != QLatin1Char ( ':' )) 2386 return QTime ( ); 2388 ParsedInt hour = readInt ( text: string . mid ( pos: 0 , n: 2 )); 2389 ParsedInt minute = readInt ( text: string . mid ( pos: 3 , n: 2 )); 2390 if (! hour . ok || ! minute . ok ) 2391 return QTime ( ); 2392 // FIXME: ISO 8601 allows [,.]\d+ after hour, just as it does after minute 2394 int second = 0 ; 2395 int msec = 0 ; 2397 if ( size == 5 ) { 2398 // HH:mm format 2399 second = 0 ; 2400 msec = 0 ; 2401 } else if ( string . at ( n: 5 ) == QLatin1Char ( ',' ) || string . at ( n: 5 ) == QLatin1Char ( '.' )) { 2402 if ( format == Qt:: TextDate ) 2403 return QTime ( ); 2404 // ISODate HH:mm.ssssss format 2405 // We only want 5 digits worth of fraction of minute. This follows the existing 2406 // behavior that determines how milliseconds are read; 4 millisecond digits are 2407 // read and then rounded to 3. If we read at most 5 digits for fraction of minute, 2408 // the maximum amount of millisecond digits it will expand to once converted to 2409 // seconds is 4. E.g. 12:34,99999 will expand to 12:34:59.9994. The milliseconds 2410 // will then be rounded up AND clamped to 999. 2412 const QStringView minuteFractionStr = string . mid ( pos: 6 , n: qMin ( a: qsizetype ( 5 ), b: string . size () - 6 )); 2413 const ParsedInt parsed = readInt ( text: minuteFractionStr ); 2414 if (! parsed . ok ) 2415 return QTime ( ); 2416 const float secondWithMs 2417 = double ( parsed . value ) * 60 / ( std:: pow ( x: double ( 10 ), y: minuteFractionStr . size ())); 2419 second = std:: floor ( x: secondWithMs ); 2420 const float secondFraction = secondWithMs - second ; 2421 msec = qMin ( a: qRound ( d: secondFraction * 1000.0 ), b: 999 ); 2422 } else if ( string . at ( n: 5 ) == QLatin1Char ( ':' )) { 2423 // HH:mm:ss or HH:mm:ss.zzz 2424 const ParsedInt parsed = readInt ( text: string . mid ( pos: 6 , n: qMin ( a: qsizetype ( 2 ), b: string . size () - 6 ))); 2425 if (! parsed . ok ) 2426 return QTime ( ); 2427 second = parsed . value ; 2428 if ( size <= 8 ) { 2429 // No fractional part to read 2430 } else if ( string . at ( n: 8 ) == QLatin1Char ( ',' ) || string . at ( n: 8 ) == QLatin1Char ( '.' )) { 2431 QStringView msecStr ( string . mid ( pos: 9 , n: qMin ( a: qsizetype ( 4 ), b: string . size () - 9 ))); 2432 bool ok = true ; 2433 // Can't use readInt() here, as we *do* allow trailing space - but not leading: 2434 if (! msecStr . isEmpty () && ! msecStr . at ( n: 0 ). isDigit ()) 2435 return QTime ( ); 2436 msecStr = msecStr . trimmed (); 2437 int msecInt = msecStr . isEmpty () ? 0 : QLocale :: c (). toInt ( s: msecStr , ok: & ok ); 2438 if (! ok ) 2439 return QTime ( ); 2440 const double secondFraction ( msecInt / ( std:: pow ( x: double ( 10 ), y: msecStr . size ()))); 2441 msec = qMin ( a: qRound ( d: secondFraction * 1000.0 ), b: 999 ); 2442 } else { 2443 # if QT_VERSION >= QT_VERSION_CHECK (6,0,0) // behavior change 2444 // Stray cruft after date-time: tolerate trailing space, but nothing else. 2445 for ( const auto &ch : string.mid( 8 )) { 2446 if (!ch.isSpace()) 2447 return QTime(); 2448 } 2449 # endif 2450 } 2451 } else { 2452 return QTime ( ); 2453 } 2455 const bool isISODate = format == Qt:: ISODate || format == Qt:: ISODateWithMs ; 2456 if ( isISODate && hour . value == 24 && minute . value == 0 && second == 0 && msec == 0 ) { 2457 if ( isMidnight24 ) 2458 * isMidnight24 = true ; 2459 hour . value = 0 ; 2460 } 2462 return QTime ( hour . value , minute . value , second , msec ); 2463} 2465 /*! 2466 Returns the time represented in the \a string as a QTime using the 2467 \a format given, or an invalid time if this is not possible. 2469 Note that fromString() uses a "C" locale encoded string to convert 2470 milliseconds to a float value. If the default locale is not "C", 2471 this may result in two conversion attempts (if the conversion 2472 fails for the default locale). This should be considered an 2473 implementation detail. 2476 \note Support for localized dates, including the format options 2477 Qt::SystemLocaleDate, Qt::SystemLocaleShortDate, Qt::SystemLocaleLongDate, 2478 Qt::LocaleDate, Qt::DefaultLocaleShortDate, and Qt::DefaultLocaleLongDate, 2479 shall be removed in Qt 6. Use QLocale::toTime() instead. 2481 \sa toString(), QLocale::toTime() 2482 */ 2483 QTime QTime :: fromString ( const QString & string , Qt:: DateFormat format ) 2484{ 2485 if ( string . isEmpty ()) 2486 return QTime ( ); 2488 switch ( format ) { 2489 # if QT_DEPRECATED_SINCE (5, 15) 2490 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED 2491 case Qt:: SystemLocaleDate : 2492 case Qt:: SystemLocaleShortDate : 2493 return QLocale :: system (). toTime ( string , QLocale :: ShortFormat ); 2494 case Qt:: SystemLocaleLongDate : 2495 return QLocale :: system (). toTime ( string , QLocale :: LongFormat ); 2496 case Qt:: LocaleDate : 2497 case Qt:: DefaultLocaleShortDate : 2498 return QLocale ( ). toTime ( string , QLocale :: ShortFormat ); 2499 case Qt:: DefaultLocaleLongDate : 2500 return QLocale ( ). toTime ( string , QLocale :: LongFormat ); 2501 QT_WARNING_POP 2502 # endif // 5.15 2503 case Qt:: RFC2822Date : 2504 return rfcDateImpl ( s: string ). time ; 2505 case Qt:: ISODate : 2506 case Qt:: ISODateWithMs : 2507 case Qt:: TextDate : 2508 default : 2509 return fromIsoTimeString ( string: QStringView ( string ), format , isMidnight24: nullptr ); 2510 } 2511} 2513 /*! 2514 Returns the QTime represented by the \a string, using the \a 2515 format given, or an invalid time if the string cannot be parsed. 2517 These expressions may be used for the format: 2519 \table 2520 \header \li Expression \li Output 2521 \row \li h 2522 \li The hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display) 2523 \row \li hh 2524 \li The hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display) 2525 \row \li H 2526 \li The hour without a leading zero (0 to 23, even with AM/PM display) 2527 \row \li HH 2528 \li The hour with a leading zero (00 to 23, even with AM/PM display) 2529 \row \li m \li The minute without a leading zero (0 to 59) 2530 \row \li mm \li The minute with a leading zero (00 to 59) 2531 \row \li s \li The whole second, without any leading zero (0 to 59) 2532 \row \li ss \li The whole second, with a leading zero where applicable (00 to 59) 2533 \row \li z \li The fractional part of the second, to go after a decimal 2534 point, without trailing zeroes (0 to 999). Thus "\c{s.z}" 2535 reports the seconds to full available (millisecond) precision 2536 without trailing zeroes. 2537 \row \li zzz \li The fractional part of the second, to millisecond 2538 precision, including trailing zeroes where applicable (000 to 999). 2539 \row \li AP or A 2540 \li Interpret as an AM/PM time. \e A/AP will match an upper-case 2541 version of either QLocale::amText() or QLocale::pmText(). 2542 \row \li ap or a 2543 \li Interpret as an am/pm time. \e a/ap will match a lower-case version 2544 of either QLocale::amText() or QLocale::pmText(). 2545 \endtable 2547 All other input characters will be treated as text. Any non-empty sequence 2548 of characters enclosed in single quotes will also be treated (stripped of 2549 the quotes) as text and not be interpreted as expressions. 2551 \snippet code/src_corelib_tools_qdatetime.cpp 6 2553 If the format is not satisfied, an invalid QTime is returned. 2554 Expressions that do not expect leading zeroes to be given (h, m, s 2555 and z) are greedy. This means that they will use two digits even if 2556 this puts them outside the range of accepted values and leaves too 2557 few digits for other sections. For example, the following string 2558 could have meant 00:07:10, but the m will grab two digits, resulting 2559 in an invalid time: 2561 \snippet code/src_corelib_tools_qdatetime.cpp 7 2563 Any field that is not represented in the format will be set to zero. 2564 For example: 2566 \snippet code/src_corelib_tools_qdatetime.cpp 8 2568 \note If localized forms of am or pm (the AP, ap, A or a formats) are used, 2569 please switch to using QLocale::system().toTime() as QTime methods shall 2570 change to only recognize English (C locale) at Qt 6. 2572 \sa toString(), QDateTime::fromString(), QDate::fromString(), 2573 QLocale::toTime() 2574 */ 2576 QTime QTime :: fromString ( const QString & string , const QString & format ) 2577{ 2578 QTime time ; 2579 # if QT_CONFIG (datetimeparser) 2580 QDateTimeParser dt ( QMetaType :: QTime , QDateTimeParser :: FromString , QCalendar ( )); 2581 // dt.setDefaultLocale(QLocale::c()); ### Qt 6 2582 if ( dt . parseFormat ( format )) 2583 dt . fromString ( text: string , date: nullptr , time: & time ); 2584 # else 2585 Q_UNUSED(string); 2586 Q_UNUSED(format); 2587 # endif 2588 return time ; 2589} 2591 # endif // datestring 2594 /*! 2595 \overload 2597 Returns \c true if the specified time is valid; otherwise returns 2598 false. 2600 The time is valid if \a h is in the range 0 to 23, \a m and 2601 \a s are in the range 0 to 59, and \a ms is in the range 0 to 999. 2603 Example: 2605 \snippet code/src_corelib_tools_qdatetime.cpp 9 2606 */ 2608 bool QTime :: isValid ( int h , int m , int s , int ms ) 2609{ 2610 return ( uint ) h < 24 && ( uint ) m < 60 && ( uint ) s < 60 && ( uint ) ms < 1000 ; 2611} 2613 # if QT_DEPRECATED_SINCE (5, 14) // ### Qt 6: remove 2614 /*! 2615 Sets this time to the current time. This is practical for timing: 2617 \snippet code/src_corelib_tools_qdatetime.cpp 10 2619 \sa restart(), elapsed(), currentTime() 2620 */ 2622 void QTime :: start () 2623{ 2624 * this = currentTime (); 2625} 2627 /*! 2628 Sets this time to the current time and returns the number of 2629 milliseconds that have elapsed since the last time start() or 2630 restart() was called. 2632 This function is guaranteed to be atomic and is thus very handy 2633 for repeated measurements. Call start() to start the first 2634 measurement, and restart() for each later measurement. 2636 Note that the counter wraps to zero 24 hours after the last call 2637 to start() or restart(). 2639 \warning If the system's clock setting has been changed since the 2640 last time start() or restart() was called, the result is 2641 undefined. This can happen when daylight-saving time is turned on 2642 or off. 2644 \sa start(), elapsed(), currentTime() 2645 */ 2647 int QTime :: restart () 2648{ 2649 QTime t = currentTime (); 2650 int n = msecsTo ( t ); 2651 if ( n < 0 ) // passed midnight 2652 n += 86400 * 1000 ; 2653 * this = t ; 2654 return n ; 2655} 2657 /*! 2658 Returns the number of milliseconds that have elapsed since the 2659 last time start() or restart() was called. 2661 Note that the counter wraps to zero 24 hours after the last call 2662 to start() or restart. 2664 Note that the accuracy depends on the accuracy of the underlying 2665 operating system; not all systems provide 1-millisecond accuracy. 2667 \warning If the system's clock setting has been changed since the 2668 last time start() or restart() was called, the result is 2669 undefined. This can happen when daylight-saving time is turned on 2670 or off. 2672 \sa start(), restart() 2673 */ 2675 int QTime :: elapsed () const 2676{ 2677 int n = msecsTo ( t: currentTime ()); 2678 if ( n < 0 ) // passed midnight 2679 n += 86400 * 1000 ; 2680 return n ; 2681} 2682 # endif // Use QElapsedTimer instead ! 2684 /***************************************************************************** 2685 QDateTime static helper functions 2686 *****************************************************************************/ 2688 // get the types from QDateTime (through QDateTimePrivate) 2689 typedef QDateTimePrivate :: QDateTimeShortData ShortData ; 2690 typedef QDateTimePrivate :: QDateTimeData QDateTimeData ; 2692 // Returns the platform variant of timezone, i.e. the standard time offset 2693 // The timezone external variable is documented as always holding the 2694 // Standard Time offset as seconds west of Greenwich, i.e. UTC+01:00 is -3600 2695 // Note this may not be historicaly accurate. 2696 // Relies on tzset, mktime, or localtime having been called to populate timezone 2697 static int qt_timezone () 2698{ 2699 # if defined( _MSC_VER ) 2700 long offset; 2701 _get_timezone(&offset); 2702 return offset; 2703 # elif defined( Q_OS_BSD4 ) && !defined( Q_OS_DARWIN ) 2704 time_t clock = time(NULL); 2705 struct tm t; 2706 localtime_r(&clock, &t); 2707 // QTBUG-36080 Workaround for systems without the POSIX timezone 2708 // variable. This solution is not very efficient but fixing it is up to 2709 // the libc implementations. 2710 // 2711 // tm_gmtoff has some important differences compared to the timezone 2712 // variable: 2713 // - It returns the number of seconds east of UTC, and we want the 2714 // number of seconds west of UTC. 2715 // - It also takes DST into account, so we need to adjust it to always 2716 // get the Standard Time offset. 2717 return -t.tm_gmtoff + (t.tm_isdst ? ( long )SECS_PER_HOUR : 0L ); 2718 # elif defined( Q_OS_INTEGRITY ) || defined( Q_OS_RTEMS ) 2719 return 0 ; 2720 # else 2721 return timezone ; 2722 # endif // Q_OS_WIN 2723} 2725 // Returns the tzname, assume tzset has been called already 2726 static QString qt_tzname ( QDateTimePrivate :: DaylightStatus daylightStatus ) 2727{ 2728 int isDst = ( daylightStatus == QDateTimePrivate :: DaylightTime ) ? 1 : 0 ; 2729 # if defined( Q_CC_MSVC ) 2730 size_t s = 0 ; 2731 char name[ 512 ]; 2732 if (_get_tzname(&s, name, 512 , isDst)) 2733 return QString(); 2734 return QString::fromLocal8Bit(name); 2735 # else 2736 return QString :: fromLocal8Bit ( str: tzname [ isDst ]); 2737 # endif // Q_OS_WIN 2738} 2740 # if QT_CONFIG (datetimeparser) 2741 /* 2742 \internal 2743 Implemented here to share qt_tzname() 2744 */ 2745 int QDateTimeParser :: startsWithLocalTimeZone ( const QStringRef name ) 2746{ 2747 QDateTimePrivate :: DaylightStatus zones [ 2 ] = { 2748 QDateTimePrivate :: StandardTime , 2749 QDateTimePrivate :: DaylightTime 2750 }; 2751 for ( const auto z : zones ) { 2752 QString zone ( qt_tzname ( daylightStatus: z )); 2753 if ( name . startsWith ( s: zone )) 2754 return zone . size (); 2755 } 2756 return 0 ; 2757} 2758 # endif // datetimeparser 2760 // Calls the platform variant of mktime for the given date, time and daylightStatus, 2761 // and updates the date, time, daylightStatus and abbreviation with the returned values 2762 // If the date falls outside the 1970 to 2037 range supported by mktime / time_t 2763 // then null date/time will be returned, you should adjust the date first if 2764 // you need a guaranteed result. 2765 static qint64 qt_mktime ( QDate * date , QTime * time , QDateTimePrivate :: DaylightStatus * daylightStatus , 2766 QString * abbreviation , bool * ok = nullptr ) 2767{ 2768 const qint64 msec = time -> msec (); 2769 int yy , mm , dd ; 2770 date -> getDate ( year: & yy , month: & mm , day: & dd ); 2772 // All other platforms provide standard C library time functions 2773 tm local ; 2774 memset ( s: & local , c: 0 , n: sizeof ( local )); // tm_[wy]day plus any non-standard fields 2775 local . tm_sec = time -> second (); 2776 local . tm_min = time -> minute (); 2777 local . tm_hour = time -> hour (); 2778 local . tm_mday = dd ; 2779 local . tm_mon = mm - 1 ; 2780 local . tm_year = yy - 1900 ; 2781 if ( daylightStatus ) 2782 local . tm_isdst = int (* daylightStatus ); 2783 else 2784 local . tm_isdst = - 1 ; 2786 # if defined( Q_OS_WIN ) 2787 int hh = local.tm_hour; 2788 # endif // Q_OS_WIN 2789 time_t secsSinceEpoch = qMkTime ( when: & local ); 2790 if ( secsSinceEpoch != time_t (- 1 )) { 2791 * date = QDate ( local . tm_year + 1900 , local . tm_mon + 1 , local . tm_mday ); 2792 * time = QTime ( local . tm_hour , local . tm_min , local . tm_sec , msec ); 2793 # if defined( Q_OS_WIN ) 2794 // Windows mktime for the missing hour subtracts 1 hour from the time 2795 // instead of adding 1 hour. If time differs and is standard time then 2796 // this has happened, so add 2 hours to the time and 1 hour to the msecs 2797 if (local.tm_isdst == 0 && local.tm_hour != hh) { 2798 if (time->hour() >= 22 ) 2799 *date = date->addDays( 1 ); 2800 *time = time->addSecs( 2 * SECS_PER_HOUR); 2801 secsSinceEpoch += SECS_PER_HOUR; 2802 local.tm_isdst = 1 ; 2803 } 2804 # endif // Q_OS_WIN 2805 if ( local . tm_isdst >= 1 ) { 2806 if ( daylightStatus ) 2807 * daylightStatus = QDateTimePrivate :: DaylightTime ; 2808 if ( abbreviation ) 2809 * abbreviation = qt_tzname ( daylightStatus: QDateTimePrivate :: DaylightTime ); 2810 } else if ( local . tm_isdst == 0 ) { 2811 if ( daylightStatus ) 2812 * daylightStatus = QDateTimePrivate :: StandardTime ; 2813 if ( abbreviation ) 2814 * abbreviation = qt_tzname ( daylightStatus: QDateTimePrivate :: StandardTime ); 2815 } else { 2816 if ( daylightStatus ) 2817 * daylightStatus = QDateTimePrivate :: UnknownDaylightTime ; 2818 if ( abbreviation ) 2819 * abbreviation = qt_tzname ( daylightStatus: QDateTimePrivate :: StandardTime ); 2820 } 2821 if ( ok ) 2822 * ok = true ; 2823 } else { 2824 * date = QDate ( ); 2825 * time = QTime ( ); 2826 if ( daylightStatus ) 2827 * daylightStatus = QDateTimePrivate :: UnknownDaylightTime ; 2828 if ( abbreviation ) 2829 * abbreviation = QString ( ); 2830 if ( ok ) 2831 * ok = false ; 2832 } 2834 return (( qint64 ) secsSinceEpoch * 1000 ) + msec ; 2835} 2837 // Calls the platform variant of localtime for the given msecs, and updates 2838 // the date, time, and DST status with the returned values. 2839 static bool qt_localtime ( qint64 msecsSinceEpoch , QDate * localDate , QTime * localTime , 2840 QDateTimePrivate :: DaylightStatus * daylightStatus ) 2841{ 2842 const time_t secsSinceEpoch = msecsSinceEpoch / 1000 ; 2843 const int msec = msecsSinceEpoch % 1000 ; 2845 tm local ; 2846 bool valid = false ; 2848 // localtime() is specified to work as if it called tzset(). 2849 // localtime_r() does not have this constraint, so make an explicit call. 2850 // The explicit call should also request the timezone info be re-parsed. 2851 qTzSet (); 2852 # if QT_CONFIG (thread) && defined( _POSIX_THREAD_SAFE_FUNCTIONS ) 2853 // Use the reentrant version of localtime() where available 2854 // as is thread-safe and doesn't use a shared static data area 2855 tm * res = nullptr ; 2856 res = localtime_r ( timer: & secsSinceEpoch , tp: & local ); 2857 if ( res ) 2858 valid = true ; 2859 # elif defined(Q_CC_MSVC) 2860 if (!_localtime64_s(&local, &secsSinceEpoch)) 2861 valid = true ; 2862 #else 2863 // Returns shared static data which may be overwritten at any time 2864 // So copy the result asap 2865 tm *res = nullptr ; 2866 res = localtime(&secsSinceEpoch); 2867 if (res) { 2868 local = *res; 2869 valid = true ; 2870 } 2871 # endif 2872 if ( valid ) { 2873 * localDate = QDate ( local . tm_year + 1900 , local . tm_mon + 1 , local . tm_mday ); 2874 * localTime = QTime ( local . tm_hour , local . tm_min , local . tm_sec , msec ); 2875 if ( daylightStatus ) { 2876 if ( local . tm_isdst > 0 ) 2877 * daylightStatus = QDateTimePrivate :: DaylightTime ; 2878 else if ( local . tm_isdst < 0 ) 2879 * daylightStatus = QDateTimePrivate :: UnknownDaylightTime ; 2880 else 2881 * daylightStatus = QDateTimePrivate :: StandardTime ; 2882 } 2883 return true ; 2884 } else { 2885 * localDate = QDate ( ); 2886 * localTime = QTime ( ); 2887 if ( daylightStatus ) 2888 * daylightStatus = QDateTimePrivate :: UnknownDaylightTime ; 2889 return false ; 2890 } 2891} 2893 // Converts an msecs value into a date and time 2894 static void msecsToTime ( qint64 msecs , QDate * date , QTime * time ) 2895{ 2896 qint64 jd = JULIAN_DAY_FOR_EPOCH ; 2897 qint64 ds = 0 ; 2899 if ( msecs >= MSECS_PER_DAY || msecs <= - MSECS_PER_DAY ) { 2900 jd += msecs / MSECS_PER_DAY ; 2901 msecs %= MSECS_PER_DAY ; 2902 } 2904 if ( msecs < 0 ) { 2905 ds = MSECS_PER_DAY - msecs - 1 ; 2906 jd -= ds / MSECS_PER_DAY ; 2907 ds = ds % MSECS_PER_DAY ; 2908 ds = MSECS_PER_DAY - ds - 1 ; 2909 } else { 2910 ds = msecs ; 2911 } 2913 if ( date ) 2914 * date = QDate :: fromJulianDay ( jd_: jd ); 2915 if ( time ) 2916 * time = QTime :: fromMSecsSinceStartOfDay ( msecs: ds ); 2917} 2919 // Converts a date/time value into msecs 2920 static qint64 timeToMSecs ( QDate date , QTime time ) 2921{ 2922 return (( date . toJulianDay () - JULIAN_DAY_FOR_EPOCH ) * MSECS_PER_DAY ) 2923 + time . msecsSinceStartOfDay (); 2924} 2926 // Convert an MSecs Since Epoch into Local Time 2927 static bool epochMSecsToLocalTime ( qint64 msecs , QDate * localDate , QTime * localTime , 2928 QDateTimePrivate :: DaylightStatus * daylightStatus = nullptr ) 2929{ 2930 if ( msecs < 0 ) { 2931 // Docs state any LocalTime before 1970-01-01 will *not* have any Daylight Time applied 2932 // Instead just use the standard offset from UTC to convert to UTC time 2933 qTzSet (); 2934 msecsToTime ( msecs: msecs - qt_timezone () * 1000 , date: localDate , time: localTime ); 2935 if ( daylightStatus ) 2936 * daylightStatus = QDateTimePrivate :: StandardTime ; 2937 return true ; 2938 } else if ( msecs > ( qint64 ( TIME_T_MAX ) * 1000 )) { 2939 // Docs state any LocalTime after 2037-12-31 *will* have any DST applied 2940 // but this may fall outside the supported time_t range, so need to fake it. 2941 // Use existing method to fake the conversion, but this is deeply flawed as it may 2942 // apply the conversion from the wrong day number, e.g. if rule is last Sunday of month 2943 // TODO Use QTimeZone when available to apply the future rule correctly 2944 QDate utcDate ; 2945 QTime utcTime ; 2946 msecsToTime ( msecs , date: & utcDate , time: & utcTime ); 2947 int year , month , day ; 2948 utcDate . getDate ( year: & year , month: & month , day: & day ); 2949 // 2037 is not a leap year, so make sure date isn't Feb 29 2950 if ( month == 2 && day == 29 ) 2951 -- day ; 2952 QDate fakeDate ( 2037 , month , day ); 2953 qint64 fakeMsecs = QDateTime ( fakeDate , utcTime , Qt:: UTC ). toMSecsSinceEpoch (); 2954 bool res = qt_localtime ( msecsSinceEpoch: fakeMsecs , localDate , localTime , daylightStatus ); 2955 * localDate = localDate -> addDays ( ndays: fakeDate . daysTo ( d: utcDate )); 2956 return res ; 2957 } else { 2958 // Falls inside time_t suported range so can use localtime 2959 return qt_localtime ( msecsSinceEpoch: msecs , localDate , localTime , daylightStatus ); 2960 } 2961} 2963 // Convert a LocalTime expressed in local msecs encoding and the corresponding 2964 // DST status into a UTC epoch msecs. Optionally populate the returned 2965 // values from mktime for the adjusted local date and time. 2966 static qint64 localMSecsToEpochMSecs ( qint64 localMsecs , 2967 QDateTimePrivate :: DaylightStatus * daylightStatus , 2968 QDate * localDate = nullptr , QTime * localTime = nullptr , 2969 QString * abbreviation = nullptr ) 2970{ 2971 QDate dt ; 2972 QTime tm ; 2973 msecsToTime ( msecs: localMsecs , date: & dt , time: & tm ); 2975 const qint64 msecsMax = qint64 ( TIME_T_MAX ) * 1000 ; 2977 if ( localMsecs <= qint64 ( MSECS_PER_DAY )) { 2979 // Docs state any LocalTime before 1970-01-01 will *not* have any DST applied 2981 // First, if localMsecs is within +/- 1 day of minimum time_t try mktime in case it does 2982 // fall after minimum and needs proper DST conversion 2983 if ( localMsecs >= - qint64 ( MSECS_PER_DAY )) { 2984 bool valid ; 2985 qint64 utcMsecs = qt_mktime ( date: & dt , time: & tm , daylightStatus , abbreviation , ok: & valid ); 2986 if ( valid && utcMsecs >= 0 ) { 2987 // mktime worked and falls in valid range, so use it 2988 if ( localDate ) 2989 * localDate = dt ; 2990 if ( localTime ) 2991 * localTime = tm ; 2992 return utcMsecs ; 2993 } 2994 } else { 2995 // If we don't call mktime then need to call tzset to get offset 2996 qTzSet (); 2997 } 2998 // Time is clearly before 1970-01-01 so just use standard offset to convert 2999 qint64 utcMsecs = localMsecs + qt_timezone () * 1000 ; 3000 if ( localDate || localTime ) 3001 msecsToTime ( msecs: localMsecs , date: localDate , time: localTime ); 3002 if ( daylightStatus ) 3003 * daylightStatus = QDateTimePrivate :: StandardTime ; 3004 if ( abbreviation ) 3005 * abbreviation = qt_tzname ( daylightStatus: QDateTimePrivate :: StandardTime ); 3006 return utcMsecs ; 3008 } else if ( localMsecs >= msecsMax - MSECS_PER_DAY ) { 3010 // Docs state any LocalTime after 2037-12-31 *will* have any DST applied 3011 // but this may fall outside the supported time_t range, so need to fake it. 3013 // First, if localMsecs is within +/- 1 day of maximum time_t try mktime in case it does 3014 // fall before maximum and can use proper DST conversion 3015 if ( localMsecs <= msecsMax + MSECS_PER_DAY ) { 3016 bool valid ; 3017 qint64 utcMsecs = qt_mktime ( date: & dt , time: & tm , daylightStatus , abbreviation , ok: & valid ); 3018 if ( valid && utcMsecs <= msecsMax ) { 3019 // mktime worked and falls in valid range, so use it 3020 if ( localDate ) 3021 * localDate = dt ; 3022 if ( localTime ) 3023 * localTime = tm ; 3024 return utcMsecs ; 3025 } 3026 } 3027 // Use existing method to fake the conversion, but this is deeply flawed as it may 3028 // apply the conversion from the wrong day number, e.g. if rule is last Sunday of month 3029 // TODO Use QTimeZone when available to apply the future rule correctly 3030 int year , month , day ; 3031 dt . getDate ( year: & year , month: & month , day: & day ); 3032 // 2037 is not a leap year, so make sure date isn't Feb 29 3033 if ( month == 2 && day == 29 ) 3034 -- day ; 3035 QDate fakeDate ( 2037 , month , day ); 3036 qint64 fakeDiff = fakeDate . daysTo ( d: dt ); 3037 qint64 utcMsecs = qt_mktime ( date: & fakeDate , time: & tm , daylightStatus , abbreviation ); 3038 if ( localDate ) 3039 * localDate = fakeDate . addDays ( ndays: fakeDiff ); 3040 if ( localTime ) 3041 * localTime = tm ; 3042 QDate utcDate ; 3043 QTime utcTime ; 3044 msecsToTime ( msecs: utcMsecs , date: & utcDate , time: & utcTime ); 3045 utcDate = utcDate . addDays ( ndays: fakeDiff ); 3046 utcMsecs = timeToMSecs ( date: utcDate , time: utcTime ); 3047 return utcMsecs ; 3049 } else { 3051 // Clearly falls inside 1970-2037 suported range so can use mktime 3052 qint64 utcMsecs = qt_mktime ( date: & dt , time: & tm , daylightStatus , abbreviation ); 3053 if ( localDate ) 3054 * localDate = dt ; 3055 if ( localTime ) 3056 * localTime = tm ; 3057 return utcMsecs ; 3059 } 3060} 3062 static inline bool specCanBeSmall ( Qt:: TimeSpec spec ) 3063{ 3064 return spec == Qt:: LocalTime || spec == Qt:: UTC ; 3065} 3067 static inline bool msecsCanBeSmall ( qint64 msecs ) 3068{ 3069 if (! QDateTimeData :: CanBeSmall ) 3070 return false ; 3072 ShortData sd ; 3073 sd . msecs = qintptr ( msecs ); 3074 return sd . msecs == msecs ; 3075} 3077 static Q_DECL_CONSTEXPR inline 3078 QDateTimePrivate :: StatusFlags mergeSpec ( QDateTimePrivate :: StatusFlags status , Qt:: TimeSpec spec ) 3079{ 3080 return QDateTimePrivate :: StatusFlags ( ( status & ~ QDateTimePrivate :: TimeSpecMask ) | 3081 ( int ( spec ) << QDateTimePrivate :: TimeSpecShift )); 3082} 3084 static Q_DECL_CONSTEXPR inline Qt:: TimeSpec extractSpec ( QDateTimePrivate :: StatusFlags status ) 3085{ 3086 return Qt:: TimeSpec ( ( status & QDateTimePrivate :: TimeSpecMask ) >> QDateTimePrivate :: TimeSpecShift ); 3087} 3089 // Set the Daylight Status if LocalTime set via msecs 3090 static Q_DECL_RELAXED_CONSTEXPR inline QDateTimePrivate :: StatusFlags 3091 mergeDaylightStatus ( QDateTimePrivate :: StatusFlags sf , QDateTimePrivate :: DaylightStatus status ) 3092{ 3093 sf &= ~ QDateTimePrivate :: DaylightMask ; 3094 if ( status == QDateTimePrivate :: DaylightTime ) { 3095 sf |= QDateTimePrivate :: SetToDaylightTime ; 3096 } else if ( status == QDateTimePrivate :: StandardTime ) { 3097 sf |= QDateTimePrivate :: SetToStandardTime ; 3098 } 3099 return sf ; 3100} 3102 // Get the DST Status if LocalTime set via msecs 3103 static Q_DECL_RELAXED_CONSTEXPR inline 3104 QDateTimePrivate :: DaylightStatus extractDaylightStatus ( QDateTimePrivate :: StatusFlags status ) 3105{ 3106 if ( status & QDateTimePrivate :: SetToDaylightTime ) 3107 return QDateTimePrivate :: DaylightTime ; 3108 if ( status & QDateTimePrivate :: SetToStandardTime ) 3109 return QDateTimePrivate :: StandardTime ; 3110 return QDateTimePrivate :: UnknownDaylightTime ; 3111} 3113 static inline qint64 getMSecs ( const QDateTimeData & d ) 3114{ 3115 if ( d . isShort ()) { 3116 // same as, but producing better code 3117 //return d.data.msecs; 3118 return qintptr ( d . d ) >> 8 ; 3119 } 3120 return d -> m_msecs ; 3121} 3123 static inline QDateTimePrivate :: StatusFlags getStatus ( const QDateTimeData & d ) 3124{ 3125 if ( d . isShort ()) { 3126 // same as, but producing better code 3127 //return StatusFlag(d.data.status); 3128 return QDateTimePrivate :: StatusFlag ( qintptr ( d . d ) & 0xFF ); 3129 } 3130 return d -> m_status ; 3131} 3133 static inline Qt:: TimeSpec getSpec ( const QDateTimeData & d ) 3134{ 3135 return extractSpec ( status: getStatus ( d )); 3136} 3138 # if QT_CONFIG (timezone) 3139 void QDateTimePrivate :: setUtcOffsetByTZ ( qint64 atMSecsSinceEpoch ) 3140{ 3141 m_offsetFromUtc = m_timeZone . d -> offsetFromUtc ( atMSecsSinceEpoch ); 3142} 3143 # endif 3145 // Refresh the LocalTime validity and offset 3146 static void refreshDateTime ( QDateTimeData & d ) 3147{ 3148 auto status = getStatus ( d ); 3149 const auto spec = extractSpec ( status ); 3150 const qint64 msecs = getMSecs ( d ); 3151 qint64 epochMSecs = 0 ; 3152 int offsetFromUtc = 0 ; 3153 QDate testDate ; 3154 QTime testTime ; 3155 Q_ASSERT ( spec == Qt:: TimeZone || spec == Qt:: LocalTime ); 3157 # if QT_CONFIG (timezone) 3158 // If not valid time zone then is invalid 3159 if ( spec == Qt:: TimeZone ) { 3160 if (! d -> m_timeZone . isValid ()) { 3161 status &= ~ QDateTimePrivate :: ValidDateTime ; 3162 } else { 3163 epochMSecs = QDateTimePrivate :: zoneMSecsToEpochMSecs ( msecs , zone: d -> m_timeZone , hint: extractDaylightStatus ( status ), localDate: & testDate , localTime: & testTime ); 3164 d -> setUtcOffsetByTZ ( epochMSecs ); 3165 } 3166 } 3167 # endif // timezone 3169 // If not valid date and time then is invalid 3170 if ( ! ( status & QDateTimePrivate :: ValidDate ) || ! ( status & QDateTimePrivate :: ValidTime )) { 3171 status &= ~ QDateTimePrivate :: ValidDateTime ; 3172 if ( status & QDateTimePrivate :: ShortData ) { 3173 d . data . status = status ; 3174 } else { 3175 d -> m_status = status ; 3176 d -> m_offsetFromUtc = 0 ; 3177 } 3178 return ; 3179 } 3181 // We have a valid date and time and a Qt::LocalTime or Qt::TimeZone that needs calculating 3182 // LocalTime and TimeZone might fall into a "missing" DST transition hour 3183 // Calling toEpochMSecs will adjust the returned date/time if it does 3184 if ( spec == Qt:: LocalTime ) { 3185 auto dstStatus = extractDaylightStatus ( status ); 3186 epochMSecs = localMSecsToEpochMSecs ( localMsecs: msecs , daylightStatus: & dstStatus , localDate: & testDate , localTime: & testTime ); 3187 status = mergeDaylightStatus ( sf: status , status: dstStatus ); 3188 } 3189 if ( timeToMSecs ( date: testDate , time: testTime ) == msecs ) { 3190 status |= QDateTimePrivate :: ValidDateTime ; 3191 // Cache the offset to use in offsetFromUtc() 3192 offsetFromUtc = ( msecs - epochMSecs ) / 1000 ; 3193 } else { 3194 status &= ~ QDateTimePrivate :: ValidDateTime ; 3195 } 3197 if ( status & QDateTimePrivate :: ShortData ) { 3198 d . data . status = status ; 3199 } else { 3200 d -> m_status = status ; 3201 d -> m_offsetFromUtc = offsetFromUtc ; 3202 } 3203} 3205 // Check the UTC / offsetFromUTC validity 3206 static void checkValidDateTime ( QDateTimeData & d ) 3207{ 3208 auto status = getStatus ( d ); 3209 auto spec = extractSpec ( status ); 3210 switch ( spec ) { 3211 case Qt:: OffsetFromUTC : 3212 case Qt:: UTC : 3213 // for these, a valid date and a valid time imply a valid QDateTime 3214 if ( ( status & QDateTimePrivate :: ValidDate ) && ( status & QDateTimePrivate :: ValidTime )) 3215 status |= QDateTimePrivate :: ValidDateTime ; 3216 else 3217 status &= ~ QDateTimePrivate :: ValidDateTime ; 3218 if ( status & QDateTimePrivate :: ShortData ) 3219 d . data . status = status ; 3220 else 3221 d -> m_status = status ; 3222 break ; 3223 case Qt:: TimeZone : 3224 case Qt:: LocalTime : 3225 // for these, we need to check whether the timezone is valid and whether 3226 // the time is valid in that timezone. Expensive, but no other option. 3227 refreshDateTime ( d ); 3228 break ; 3229 } 3230} 3232 static void setTimeSpec ( QDateTimeData & d , Qt:: TimeSpec spec , int offsetSeconds ) 3233{ 3234 auto status = getStatus ( d ); 3235 status &= ~( QDateTimePrivate :: ValidDateTime | QDateTimePrivate :: DaylightMask | 3236 QDateTimePrivate :: TimeSpecMask ); 3238 switch ( spec ) { 3239 case Qt:: OffsetFromUTC : 3240 if ( offsetSeconds == 0 ) 3241 spec = Qt:: UTC ; 3242 break ; 3243 case Qt:: TimeZone : 3244 // Use system time zone instead 3245 spec = Qt:: LocalTime ; 3246 Q_FALLTHROUGH (); 3247 case Qt:: UTC : 3248 case Qt:: LocalTime : 3249 offsetSeconds = 0 ; 3250 break ; 3251 } 3253 status = mergeSpec ( status , spec ); 3254 if ( d . isShort () && offsetSeconds == 0 ) { 3255 d . data . status = status ; 3256 } else { 3257 d . detach (); 3258 d -> m_status = status & ~ QDateTimePrivate :: ShortData ; 3259 d -> m_offsetFromUtc = offsetSeconds ; 3260 # if QT_CONFIG (timezone) 3261 d -> m_timeZone = QTimeZone ( ); 3262 # endif // timezone 3263 } 3264} 3266 static void setDateTime ( QDateTimeData & d , QDate date , QTime time ) 3267{ 3268 // If the date is valid and the time is not we set time to 00:00:00 3269 QTime useTime = time ; 3270 if (! useTime . isValid () && date . isValid ()) 3271 useTime = QTime :: fromMSecsSinceStartOfDay ( msecs: 0 ); 3273 QDateTimePrivate :: StatusFlags newStatus = { }; 3275 // Set date value and status 3276 qint64 days = 0 ; 3277 if ( date . isValid ()) { 3278 days = date . toJulianDay () - JULIAN_DAY_FOR_EPOCH ; 3279 newStatus = QDateTimePrivate :: ValidDate ; 3280 } 3282 // Set time value and status 3283 int ds = 0 ; 3284 if ( useTime . isValid ()) { 3285 ds = useTime . msecsSinceStartOfDay (); 3286 newStatus |= QDateTimePrivate :: ValidTime ; 3287 } 3289 // Set msecs serial value 3290 qint64 msecs = ( days * MSECS_PER_DAY ) + ds ; 3291 if ( d . isShort ()) { 3292 // let's see if we can keep this short 3293 if ( msecsCanBeSmall ( msecs )) { 3294 // yes, we can 3295 d . data . msecs = qintptr ( msecs ); 3296 d . data . status &= ~( QDateTimePrivate :: ValidityMask | QDateTimePrivate :: DaylightMask ); 3297 d . data . status |= newStatus ; 3298 } else { 3299 // nope... 3300 d . detach (); 3301 } 3302 } 3303 if (! d . isShort ()) { 3304 d . detach (); 3305 d -> m_msecs = msecs ; 3306 d -> m_status &= ~( QDateTimePrivate :: ValidityMask | QDateTimePrivate :: DaylightMask ); 3307 d -> m_status |= newStatus ; 3308 } 3310 // Set if date and time are valid 3311 checkValidDateTime ( d ); 3312} 3314 static QPair < QDate , QTime > getDateTime ( const QDateTimeData & d ) 3315{ 3316 QPair < QDate , QTime > result ; 3317 qint64 msecs = getMSecs ( d ); 3318 auto status = getStatus ( d ); 3319 msecsToTime ( msecs , date: & result . first , time: & result . second ); 3321 if (! status . testFlag ( flag: QDateTimePrivate :: ValidDate )) 3322 result . first = QDate ( ); 3324 if (! status . testFlag ( flag: QDateTimePrivate :: ValidTime )) 3325 result . second = QTime ( ); 3327 return result ; 3328} 3330 /***************************************************************************** 3331 QDateTime::Data member functions 3332 *****************************************************************************/ 3334 inline QDateTime :: Data :: Data () 3335{ 3336 // default-constructed data has a special exception: 3337 // it can be small even if CanBeSmall == false 3338 // (optimization so we don't allocate memory in the default constructor) 3339 quintptr value = quintptr ( mergeSpec ( status: QDateTimePrivate :: ShortData , spec: Qt:: LocalTime )); 3340 d = reinterpret_cast < QDateTimePrivate *>( value ); 3341} 3343 inline QDateTime :: Data :: Data ( Qt:: TimeSpec spec ) 3344{ 3345 if ( CanBeSmall && Q_LIKELY ( specCanBeSmall ( spec ))) { 3346 d = reinterpret_cast < QDateTimePrivate *>( quintptr ( mergeSpec ( status: QDateTimePrivate :: ShortData , spec ))); 3347 } else { 3348 // the structure is too small, we need to detach 3349 d = new QDateTimePrivate ; 3350 d -> ref . ref (); 3351 d -> m_status = mergeSpec ( status: { }, spec ); 3352 } 3353} 3355 inline QDateTime :: Data :: Data ( const Data & other ) 3356 : d ( other . d ) 3357{ 3358 if (! isShort ()) { 3359 // check if we could shrink 3360 if ( specCanBeSmall ( spec: extractSpec ( status: d -> m_status )) && msecsCanBeSmall ( msecs: d -> m_msecs )) { 3361 ShortData sd ; 3362 sd . msecs = qintptr ( d -> m_msecs ); 3363 sd . status = d -> m_status | QDateTimePrivate :: ShortData ; 3364 data = sd ; 3365 } else { 3366 // no, have to keep it big 3367 d -> ref . ref (); 3368 } 3369 } 3370} 3372 inline QDateTime :: Data :: Data ( Data && other ) 3373 : d ( other . d ) 3374{ 3375 // reset the other to a short state 3376 Data dummy ; 3377 Q_ASSERT ( dummy . isShort ()); 3378 other . d = dummy . d ; 3379} 3381 inline QDateTime :: Data & QDateTime :: Data :: operator = ( const Data & other ) 3382{ 3383 if ( d == other . d ) 3384 return * this ; 3386 auto x = d ; 3387 d = other . d ; 3388 if (! other . isShort ()) { 3389 // check if we could shrink 3390 if ( specCanBeSmall ( spec: extractSpec ( status: other . d -> m_status )) && msecsCanBeSmall ( msecs: other . d -> m_msecs )) { 3391 ShortData sd ; 3392 sd . msecs = qintptr ( other . d -> m_msecs ); 3393 sd . status = other . d -> m_status | QDateTimePrivate :: ShortData ; 3394 data = sd ; 3395 } else { 3396 // no, have to keep it big 3397 other . d -> ref . ref (); 3398 } 3399 } 3401 if (!( quintptr ( x ) & QDateTimePrivate :: ShortData ) && ! x -> ref . deref ()) 3402 delete x ; 3403 return * this ; 3404} 3406 inline QDateTime :: Data :: ~Data () 3407{ 3408 if (! isShort () && ! d -> ref . deref ()) 3409 delete d ; 3410} 3412 inline bool QDateTime :: Data :: isShort () const 3413{ 3414 bool b = quintptr ( d ) & QDateTimePrivate :: ShortData ; 3416 // sanity check: 3417 Q_ASSERT ( b || ( d -> m_status & QDateTimePrivate :: ShortData ) == 0 ); 3419 // even if CanBeSmall = false, we have short data for a default-constructed 3420 // QDateTime object. But it's unlikely. 3421 if ( CanBeSmall ) 3422 return Q_LIKELY ( b ); 3423 return Q_UNLIKELY ( b ); 3424} 3426 inline void QDateTime :: Data :: detach () 3427{ 3428 QDateTimePrivate * x ; 3429 bool wasShort = isShort (); 3430 if ( wasShort ) { 3431 // force enlarging 3432 x = new QDateTimePrivate ; 3433 x -> m_status = QDateTimePrivate :: StatusFlag ( data . status & ~ QDateTimePrivate :: ShortData ); 3434 x -> m_msecs = data . msecs ; 3435 } else { 3436 if ( d -> ref . loadRelaxed () == 1 ) 3437 return ; 3439 x = new QDateTimePrivate ( * d ); 3440 } 3442 x -> ref . storeRelaxed ( newValue: 1 ); 3443 if (! wasShort && ! d -> ref . deref ()) 3444 delete d ; 3445 d = x ; 3446} 3448 inline const QDateTimePrivate * QDateTime :: Data :: operator -> () const 3449{ 3450 Q_ASSERT (! isShort ()); 3451 return d ; 3452} 3454 inline QDateTimePrivate * QDateTime :: Data :: operator -> () 3455{ 3456 // should we attempt to detach here? 3457 Q_ASSERT (! isShort ()); 3458 Q_ASSERT ( d -> ref . loadRelaxed () == 1 ); 3459 return d ; 3460} 3462 /***************************************************************************** 3463 QDateTimePrivate member functions 3464 *****************************************************************************/ 3466 Q_NEVER_INLINE 3467 QDateTime :: Data QDateTimePrivate :: create ( const QDate & toDate , const QTime & toTime , Qt:: TimeSpec toSpec , 3468 int offsetSeconds ) 3469{ 3470 QDateTime :: Data result ( toSpec ); 3471 setTimeSpec ( d&: result , spec: toSpec , offsetSeconds ); 3472 setDateTime ( d&: result , date: toDate , time: toTime ); 3473 return result ; 3474} 3476 # if QT_CONFIG (timezone) 3477 inline QDateTime :: Data QDateTimePrivate :: create ( const QDate & toDate , const QTime & toTime , 3478 const QTimeZone & toTimeZone ) 3479{ 3480 QDateTime :: Data result ( Qt:: TimeZone ); 3481 Q_ASSERT (! result . isShort ()); 3483 result . d -> m_status = mergeSpec ( status: result . d -> m_status , spec: Qt:: TimeZone ); 3484 result . d -> m_timeZone = toTimeZone ; 3485 setDateTime ( d&: result , date: toDate , time: toTime ); 3486 return result ; 3487} 3489 // Convert a TimeZone time expressed in zone msecs encoding into a UTC epoch msecs 3490 // DST transitions are disambiguated by hint. 3491 inline qint64 QDateTimePrivate :: zoneMSecsToEpochMSecs ( qint64 zoneMSecs , const QTimeZone & zone , 3492 DaylightStatus hint , 3493 QDate * zoneDate , QTime * zoneTime ) 3494{ 3495 Q_ASSERT ( zone . isValid ()); 3496 // Get the effective data from QTimeZone 3497 QTimeZonePrivate :: Data data = zone . d -> dataForLocalTime ( forLocalMSecs: zoneMSecs , hint: int ( hint )); 3498 // Docs state any time before 1970-01-01 will *not* have any DST applied 3499 // but all affected times afterwards will have DST applied. 3500 if ( data . atMSecsSinceEpoch < 0 ) { 3501 msecsToTime ( msecs: zoneMSecs , date: zoneDate , time: zoneTime ); 3502 return zoneMSecs - data . standardTimeOffset * 1000 ; 3503 } else { 3504 msecsToTime ( msecs: data . atMSecsSinceEpoch + data . offsetFromUtc * 1000 , date: zoneDate , time: zoneTime ); 3505 return data . atMSecsSinceEpoch ; 3506 } 3507} 3508 # endif // timezone 3510 /***************************************************************************** 3511 QDateTime member functions 3512 *****************************************************************************/ 3514 /*! 3515 \class QDateTime 3516 \inmodule QtCore 3517 \ingroup shared 3518 \reentrant 3519 \brief The QDateTime class provides date and time functions. 3522 A QDateTime object encodes a calendar date and a clock time (a 3523 "datetime"). It combines features of the QDate and QTime classes. 3524 It can read the current datetime from the system clock. It 3525 provides functions for comparing datetimes and for manipulating a 3526 datetime by adding a number of seconds, days, months, or years. 3528 QDateTime can describe datetimes with respect to \l {Qt::LocalTime}{local 3529 time}, to \l {Qt::UTC}{UTC}, to a specified \l {Qt::OffsetFromUTC}{offset from 3530 UTC} or to a specified \l {Qt::TimeZone}{time zone}, in conjunction with the 3531 QTimeZone class. For example, a time zone of "Europe/Berlin" will apply the 3532 daylight-saving rules as used in Germany since 1970. In contrast, an offset 3533 from UTC of +3600 seconds is one hour ahead of UTC (usually written in ISO 3534 standard notation as "UTC+01:00"), with no daylight-saving offset or 3535 changes. When using either local time or a specified time zone, time-zone 3536 transitions such as the starts and ends of daylight-saving time (DST; but 3537 see below) are taken into account. The choice of system used to represent a 3538 datetime is described as its "timespec". 3540 A QDateTime object is typically created either by giving a date and time 3541 explicitly in the constructor, or by using a static function such as 3542 currentDateTime() or fromMSecsSinceEpoch(). The date and time can be changed 3543 with setDate() and setTime(). A datetime can also be set using the 3544 setMSecsSinceEpoch() function that takes the time, in milliseconds, since 3545 00:00:00 on January 1, 1970. The fromString() function returns a QDateTime, 3546 given a string and a date format used to interpret the date within the 3547 string. 3549 QDateTime::currentDateTime() returns a QDateTime that expresses the current 3550 time with respect to local time. QDateTime::currentDateTimeUtc() returns a 3551 QDateTime that expresses the current time with respect to UTC. 3553 The date() and time() functions provide access to the date and 3554 time parts of the datetime. The same information is provided in 3555 textual format by the toString() function. 3557 QDateTime provides a full set of operators to compare two 3558 QDateTime objects, where smaller means earlier and larger means 3559 later. 3561 You can increment (or decrement) a datetime by a given number of 3562 milliseconds using addMSecs(), seconds using addSecs(), or days using 3563 addDays(). Similarly, you can use addMonths() and addYears(). The daysTo() 3564 function returns the number of days between two datetimes, secsTo() returns 3565 the number of seconds between two datetimes, and msecsTo() returns the 3566 number of milliseconds between two datetimes. These operations are aware of 3567 daylight-saving time (DST) and other time-zone transitions, where 3568 applicable. 3570 Use toTimeSpec() to express a datetime in local time or UTC, 3571 toOffsetFromUtc() to express in terms of an offset from UTC, or toTimeZone() 3572 to express it with respect to a general time zone. You can use timeSpec() to 3573 find out what time-spec a QDateTime object stores its time relative to. When 3574 that is Qt::TimeZone, you can use timeZone() to find out which zone it is 3575 using. 3577 \note QDateTime does not account for leap seconds. 3579 \section 1 Remarks 3581 \section 2 No Year 0 3583 There is no year 0. Dates in that year are considered invalid. The 3584 year -1 is the year "1 before Christ" or "1 before current era." 3585 The day before 1 January 1 CE is 31 December 1 BCE. 3587 \section 2 Range of Valid Dates 3589 The range of values that QDateTime can represent is dependent on the 3590 internal storage implementation. QDateTime is currently stored in a qint64 3591 as a serial msecs value encoding the date and time. This restricts the date 3592 range to about +/- 292 million years, compared to the QDate range of +/- 2 3593 billion years. Care must be taken when creating a QDateTime with extreme 3594 values that you do not overflow the storage. The exact range of supported 3595 values varies depending on the Qt::TimeSpec and time zone. 3597 \section 2 Use of Timezones 3599 QDateTime uses the system's time zone information to determine the current 3600 local time zone and its offset from UTC. If the system is not configured 3601 correctly or not up-to-date, QDateTime will give wrong results. 3603 QDateTime likewise uses system-provided information to determine the offsets 3604 of other timezones from UTC. If this information is incomplete or out of 3605 date, QDateTime will give wrong results. See the QTimeZone documentation for 3606 more details. 3608 On modern Unix systems, this means QDateTime usually has accurate 3609 information about historical transitions (including DST, see below) whenever 3610 possible. On Windows, where the system doesn't support historical timezone 3611 data, historical accuracy is not maintained with respect to timezone 3612 transitions, notably including DST. 3614 \section 2 Daylight-Saving Time (DST) 3616 QDateTime takes into account transitions between Standard Time and 3617 Daylight-Saving Time. For example, if the transition is at 2am and the clock 3618 goes forward to 3am, then there is a "missing" hour from 02:00:00 to 3619 02:59:59.999 which QDateTime considers to be invalid. Any date arithmetic 3620 performed will take this missing hour into account and return a valid 3621 result. For example, adding one minute to 01:59:59 will get 03:00:00. 3623 The range of valid dates taking DST into account is 1970-01-01 to the 3624 present, and rules are in place for handling DST correctly until 2037-12-31, 3625 but these could change. For dates after 2037, QDateTime makes a \e {best 3626 guess} using the rules for year 2037, but we can't guarantee accuracy; 3627 indeed, for \e {any} future date, the time-zone may change its rules before 3628 that date comes around. For dates before 1970, QDateTime doesn't take DST 3629 changes into account, even if the system's time zone database provides that 3630 information, although it does take into account changes to the time-zone's 3631 standard offset, where this information is available. 3633 \section 2 Offsets From UTC 3635 There is no explicit size restriction on an offset from UTC, but there is an 3636 implicit limit imposed when using the toString() and fromString() methods 3637 which use a [+|-]hh:mm format, effectively limiting the range to +/- 99 3638 hours and 59 minutes and whole minutes only. Note that currently no time 3639 zone lies outside the range of +/- 14 hours. 3641 \sa QDate, QTime, QDateTimeEdit, QTimeZone 3642 */ 3644 /*! 3645 \since 5.14 3646 \enum QDateTime::YearRange 3648 This enumerated type describes the range of years (in the Gregorian 3649 calendar) representable by QDateTime: 3651 \value First The later parts of this year are representable 3652 \value Last The earlier parts of this year are representable 3654 All dates strictly between these two years are also representable. 3655 Note, however, that the Gregorian Calendar has no year zero. 3657 \note QDate can describe dates in a wider range of years. For most 3658 purposes, this makes little difference, as the range of years that QDateTime 3659 can support reaches 292 million years either side of 1970. 3661 \sa isValid(), QDate 3662 */ 3664 /*! 3665 Constructs a null datetime (i.e. null date and null time). A null 3666 datetime is invalid, since the date is invalid. 3668 \sa isValid() 3669 */ 3670 QDateTime :: QDateTime () noexcept ( Data :: CanBeSmall ) 3671{ 3672} 3675 # if QT_DEPRECATED_SINCE (5, 17) // ### Qt 6: remove 3676 /*! 3677 Constructs a datetime with the given \a date, using Qt::LocalTime as the 3678 timeSpec() and the time at the start of that date. 3680 \sa QDate::startOfDay() 3681 */ 3682 QDateTime :: QDateTime ( const QDate & date ) 3683 : QDateTime ( date . startOfDay ( spec: Qt:: LocalTime , offsetSeconds: 0 )) 3684{ 3685} 3686 # endif 3688 /*! 3689 Constructs a datetime with the given \a date and \a time, using 3690 the time specification defined by \a spec. 3692 If \a date is valid and \a time is not, the time will be set to midnight. 3694 If \a spec is Qt::OffsetFromUTC then it will be set to Qt::UTC, i.e. an 3695 offset of 0 seconds. To create a Qt::OffsetFromUTC datetime use the 3696 correct constructor. 3698 If \a spec is Qt::TimeZone then the spec will be set to Qt::LocalTime, 3699 i.e. the current system time zone. To create a Qt::TimeZone datetime 3700 use the correct constructor. 3701 */ 3703 QDateTime :: QDateTime ( const QDate & date , const QTime & time , Qt:: TimeSpec spec ) 3704 : d ( QDateTimePrivate :: create ( toDate: date , toTime: time , toSpec: spec , offsetSeconds: 0 )) 3705{ 3706} 3708 /*! 3709 \since 5.2 3711 Constructs a datetime with the given \a date and \a time, using 3712 the time specification defined by \a spec and \a offsetSeconds seconds. 3714 If \a date is valid and \a time is not, the time will be set to midnight. 3716 If the \a spec is not Qt::OffsetFromUTC then \a offsetSeconds will be ignored. 3718 If the \a spec is Qt::OffsetFromUTC and \a offsetSeconds is 0 then the 3719 timeSpec() will be set to Qt::UTC, i.e. an offset of 0 seconds. 3721 If \a spec is Qt::TimeZone then the spec will be set to Qt::LocalTime, 3722 i.e. the current system time zone. To create a Qt::TimeZone datetime 3723 use the correct constructor. 3724 */ 3726 QDateTime :: QDateTime ( const QDate & date , const QTime & time , Qt:: TimeSpec spec , int offsetSeconds ) 3727 : d ( QDateTimePrivate :: create ( toDate: date , toTime: time , toSpec: spec , offsetSeconds )) 3728{ 3729} 3731 # if QT_CONFIG (timezone) 3732 /*! 3733 \since 5.2 3735 Constructs a datetime with the given \a date and \a time, using 3736 the Time Zone specified by \a timeZone. 3738 If \a date is valid and \a time is not, the time will be set to 00:00:00. 3740 If \a timeZone is invalid then the datetime will be invalid. 3741 */ 3743 QDateTime :: QDateTime ( const QDate & date , const QTime & time , const QTimeZone & timeZone ) 3744 : d ( QDateTimePrivate :: create ( toDate: date , toTime: time , toTimeZone: timeZone )) 3745{ 3746} 3747 # endif // timezone 3749 /*! 3750 Constructs a copy of the \a other datetime. 3751 */ 3752 QDateTime :: QDateTime ( const QDateTime & other ) noexcept 3753 : d ( other . d ) 3754{ 3755} 3757 /*! 3758 \since 5.8 3759 Moves the content of the temporary \a other datetime to this object and 3760 leaves \a other in an unspecified (but proper) state. 3761 */ 3762 QDateTime :: QDateTime ( QDateTime && other ) noexcept 3763 : d ( std:: move ( other . d )) 3764{ 3765} 3767 /*! 3768 Destroys the datetime. 3769 */ 3770 QDateTime :: ~QDateTime () 3771{ 3772} 3774 /*! 3775 Makes a copy of the \a other datetime and returns a reference to the 3776 copy. 3777 */ 3779 QDateTime & QDateTime :: operator = ( const QDateTime & other ) noexcept 3780{ 3781 d = other . d ; 3782 return * this ; 3783} 3784 /*! 3785 \fn void QDateTime::swap(QDateTime &other) 3786 \since 5.0 3788 Swaps this datetime with \a other. This operation is very fast 3789 and never fails. 3790 */ 3792 /*! 3793 Returns \c true if both the date and the time are null; otherwise 3794 returns \c false. A null datetime is invalid. 3796 \sa QDate::isNull(), QTime::isNull(), isValid() 3797 */ 3799 bool QDateTime :: isNull () const 3800{ 3801 auto status = getStatus ( d ); 3802 return ! status . testFlag ( flag: QDateTimePrivate :: ValidDate ) && 3803 ! status . testFlag ( flag: QDateTimePrivate :: ValidTime ); 3804} 3806 /*! 3807 Returns \c true if both the date and the time are valid and they are valid in 3808 the current Qt::TimeSpec, otherwise returns \c false. 3810 If the timeSpec() is Qt::LocalTime or Qt::TimeZone then the date and time are 3811 checked to see if they fall in the Standard Time to Daylight-Saving Time transition 3812 hour, i.e. if the transition is at 2am and the clock goes forward to 3am 3813 then the time from 02:00:00 to 02:59:59.999 is considered to be invalid. 3815 \sa QDateTime::YearRange, QDate::isValid(), QTime::isValid() 3816 */ 3818 bool QDateTime :: isValid () const 3819{ 3820 auto status = getStatus ( d ); 3821 return status & QDateTimePrivate :: ValidDateTime ; 3822} 3824 /*! 3825 Returns the date part of the datetime. 3827 \sa setDate(), time(), timeSpec() 3828 */ 3830 QDate QDateTime :: date () const 3831{ 3832 auto status = getStatus ( d ); 3833 if (! status . testFlag ( flag: QDateTimePrivate :: ValidDate )) 3834 return QDate ( ); 3835 QDate dt ; 3836 msecsToTime ( msecs: getMSecs ( d ), date: & dt , time: nullptr ); 3837 return dt ; 3838} 3840 /*! 3841 Returns the time part of the datetime. 3843 \sa setTime(), date(), timeSpec() 3844 */ 3846 QTime QDateTime :: time () const 3847{ 3848 auto status = getStatus ( d ); 3849 if (! status . testFlag ( flag: QDateTimePrivate :: ValidTime )) 3850 return QTime ( ); 3851 QTime tm ; 3852 msecsToTime ( msecs: getMSecs ( d ), date: nullptr , time: & tm ); 3853 return tm ; 3854} 3856 /*! 3857 Returns the time specification of the datetime. 3859 \sa setTimeSpec(), date(), time(), Qt::TimeSpec 3860 */ 3862 Qt:: TimeSpec QDateTime :: timeSpec () const 3863{ 3864 return getSpec ( d ); 3865} 3867 # if QT_CONFIG (timezone) 3868 /*! 3869 \since 5.2 3871 Returns the time zone of the datetime. 3873 If the timeSpec() is Qt::LocalTime then an instance of the current system 3874 time zone will be returned. Note however that if you copy this time zone 3875 the instance will not remain in sync if the system time zone changes. 3877 \sa setTimeZone(), Qt::TimeSpec 3878 */ 3880 QTimeZone QDateTime :: timeZone () const 3881{ 3882 switch ( getSpec ( d )) { 3883 case Qt:: UTC : 3884 return QTimeZone :: utc (); 3885 case Qt:: OffsetFromUTC : 3886 return QTimeZone ( d -> m_offsetFromUtc ); 3887 case Qt:: TimeZone : 3888 if ( d -> m_timeZone . isValid ()) 3889 return d -> m_timeZone ; 3890 break ; 3891 case Qt:: LocalTime : 3892 return QTimeZone :: systemTimeZone (); 3893 } 3894 return QTimeZone ( ); 3895} 3896 # endif // timezone 3898 /*! 3899 \since 5.2 3901 Returns this date-time's Offset From UTC in seconds. 3903 The result depends on timeSpec(): 3904 \list 3905 \li \c Qt::UTC The offset is 0. 3906 \li \c Qt::OffsetFromUTC The offset is the value originally set. 3907 \li \c Qt::LocalTime The local time's offset from UTC is returned. 3908 \li \c Qt::TimeZone The offset used by the time-zone is returned. 3909 \endlist 3911 For the last two, the offset at this date and time will be returned, taking 3912 account of Daylight-Saving Offset unless the date precedes the start of 3913 1970. The offset is the difference between the local time or time in the 3914 given time-zone and UTC time; it is positive in time-zones ahead of UTC 3915 (East of The Prime Meridian), negative for those behind UTC (West of The 3916 Prime Meridian). 3918 \sa setOffsetFromUtc() 3919 */ 3921 int QDateTime :: offsetFromUtc () const 3922{ 3923 if (! d . isShort ()) 3924 return d -> m_offsetFromUtc ; 3925 if (! isValid ()) 3926 return 0 ; 3928 auto spec = getSpec ( d ); 3929 if ( spec == Qt:: LocalTime ) { 3930 // we didn't cache the value, so we need to calculate it now... 3931 qint64 msecs = getMSecs ( d ); 3932 return ( msecs - toMSecsSinceEpoch ()) / 1000 ; 3933 } 3935 Q_ASSERT ( spec == Qt:: UTC ); 3936 return 0 ; 3937} 3939 /*! 3940 \since 5.2 3942 Returns the Time Zone Abbreviation for the datetime. 3944 If the timeSpec() is Qt::UTC this will be "UTC". 3946 If the timeSpec() is Qt::OffsetFromUTC this will be in the format 3947 "UTC[+-]00:00". 3949 If the timeSpec() is Qt::LocalTime then the host system is queried for the 3950 correct abbreviation. 3952 Note that abbreviations may or may not be localized. 3954 Note too that the abbreviation is not guaranteed to be a unique value, 3955 i.e. different time zones may have the same abbreviation. 3957 \sa timeSpec() 3958 */ 3960 QString QDateTime :: timeZoneAbbreviation () const 3961{ 3962 if (! isValid ()) 3963 return QString ( ); 3965 switch ( getSpec ( d )) { 3966 case Qt:: UTC : 3967 return QLatin1String ( "UTC" ); 3968 case Qt:: OffsetFromUTC : 3969 return QLatin1String ( "UTC" ) + toOffsetString ( format: Qt:: ISODate , offset: d -> m_offsetFromUtc ); 3970 case Qt:: TimeZone : 3971 # if ! QT_CONFIG (timezone) 3972 break ; 3973 # else 3974 Q_ASSERT ( d -> m_timeZone . isValid ()); 3975 return d -> m_timeZone . d -> abbreviation ( atMSecsSinceEpoch: toMSecsSinceEpoch ()); 3976 # endif // timezone 3977 case Qt:: LocalTime : { 3978 QString abbrev ; 3979 auto status = extractDaylightStatus ( status: getStatus ( d )); 3980 localMSecsToEpochMSecs ( localMsecs: getMSecs ( d ), daylightStatus: & status , localDate: nullptr , localTime: nullptr , abbreviation: & abbrev ); 3981 return abbrev ; 3982 } 3983 } 3984 return QString ( ); 3985} 3987 /*! 3988 \since 5.2 3990 Returns if this datetime falls in Daylight-Saving Time. 3992 If the Qt::TimeSpec is not Qt::LocalTime or Qt::TimeZone then will always 3993 return false. 3995 \sa timeSpec() 3996 */ 3998 bool QDateTime :: isDaylightTime () const 3999{ 4000 if (! isValid ()) 4001 return false ; 4003 switch ( getSpec ( d )) { 4004 case Qt:: UTC : 4005 case Qt:: OffsetFromUTC : 4006 return false ; 4007 case Qt:: TimeZone : 4008 # if ! QT_CONFIG (timezone) 4009 break ; 4010 # else 4011 Q_ASSERT ( d -> m_timeZone . isValid ()); 4012 return d -> m_timeZone . d -> isDaylightTime ( atMSecsSinceEpoch: toMSecsSinceEpoch ()); 4013 # endif // timezone 4014 case Qt:: LocalTime : { 4015 auto status = extractDaylightStatus ( status: getStatus ( d )); 4016 if ( status == QDateTimePrivate :: UnknownDaylightTime ) 4017 localMSecsToEpochMSecs ( localMsecs: getMSecs ( d ), daylightStatus: & status ); 4018 return ( status == QDateTimePrivate :: DaylightTime ); 4019 } 4020 } 4021 return false ; 4022} 4024 /*! 4025 Sets the date part of this datetime to \a date. If no time is set yet, it 4026 is set to midnight. If \a date is invalid, this QDateTime becomes invalid. 4028 \sa date(), setTime(), setTimeSpec() 4029 */ 4031 void QDateTime :: setDate ( const QDate & date ) 4032{ 4033 setDateTime ( d , date , time: time ()); 4034} 4036 /*! 4037 Sets the time part of this datetime to \a time. If \a time is not valid, 4038 this function sets it to midnight. Therefore, it's possible to clear any 4039 set time in a QDateTime by setting it to a default QTime: 4041 \code 4042 QDateTime dt = QDateTime::currentDateTime(); 4043 dt.setTime(QTime()); 4044 \endcode 4046 \sa time(), setDate(), setTimeSpec() 4047 */ 4049 void QDateTime :: setTime ( const QTime & time ) 4050{ 4051 setDateTime ( d , date: date (), time ); 4052} 4054 /*! 4055 Sets the time specification used in this datetime to \a spec. 4056 The datetime will refer to a different point in time. 4058 If \a spec is Qt::OffsetFromUTC then the timeSpec() will be set 4059 to Qt::UTC, i.e. an effective offset of 0. 4061 If \a spec is Qt::TimeZone then the spec will be set to Qt::LocalTime, 4062 i.e. the current system time zone. 4064 Example: 4065 \snippet code/src_corelib_tools_qdatetime.cpp 19 4067 \sa timeSpec(), setDate(), setTime(), setTimeZone(), Qt::TimeSpec 4068 */ 4070 void QDateTime :: setTimeSpec ( Qt:: TimeSpec spec ) 4071{ 4072 QT_PREPEND_NAMESPACE ( setTimeSpec ( d , spec , 0 )); 4073 checkValidDateTime ( d ); 4074} 4076 /*! 4077 \since 5.2 4079 Sets the timeSpec() to Qt::OffsetFromUTC and the offset to \a offsetSeconds. 4080 The datetime will refer to a different point in time. 4082 The maximum and minimum offset is 14 positive or negative hours. If 4083 \a offsetSeconds is larger or smaller than that, then the result is 4084 undefined. 4086 If \a offsetSeconds is 0 then the timeSpec() will be set to Qt::UTC. 4088 \sa isValid(), offsetFromUtc() 4089 */ 4091 void QDateTime :: setOffsetFromUtc ( int offsetSeconds ) 4092{ 4093 QT_PREPEND_NAMESPACE ( setTimeSpec ( d , Qt:: OffsetFromUTC , offsetSeconds )); 4094 checkValidDateTime ( d ); 4095} 4097 # if QT_CONFIG (timezone) 4098 /*! 4099 \since 5.2 4101 Sets the time zone used in this datetime to \a toZone. 4102 The datetime will refer to a different point in time. 4104 If \a toZone is invalid then the datetime will be invalid. 4106 \sa timeZone(), Qt::TimeSpec 4107 */ 4109 void QDateTime :: setTimeZone ( const QTimeZone & toZone ) 4110{ 4111 d . detach (); // always detach 4112 d -> m_status = mergeSpec ( status: d -> m_status , spec: Qt:: TimeZone ); 4113 d -> m_offsetFromUtc = 0 ; 4114 d -> m_timeZone = toZone ; 4115 refreshDateTime ( d ); 4116} 4117 # endif // timezone 4119 /*! 4120 \since 4.7 4122 Returns the datetime as the number of milliseconds that have passed 4123 since 1970-01-01T00:00:00.000, Coordinated Universal Time (Qt::UTC). 4125 On systems that do not support time zones, this function will 4126 behave as if local time were Qt::UTC. 4128 The behavior for this function is undefined if the datetime stored in 4129 this object is not valid. However, for all valid dates, this function 4130 returns a unique value. 4132 \sa toSecsSinceEpoch(), setMSecsSinceEpoch() 4133 */ 4134 qint64 QDateTime :: toMSecsSinceEpoch () const 4135{ 4136 // Note: QDateTimeParser relies on this producing a useful result, even when 4137 // !isValid(), at least when the invalidity is a time in a fall-back (that 4138 // we'll have adjusted to lie outside it, but marked invalid because it's 4139 // not what was asked for). Other things may be doing similar. 4140 switch ( getSpec ( d )) { 4141 case Qt:: UTC : 4142 return getMSecs ( d ); 4144 case Qt:: OffsetFromUTC : 4145 return d -> m_msecs - ( d -> m_offsetFromUtc * 1000 ); 4147 case Qt:: LocalTime : { 4148 // recalculate the local timezone 4149 auto status = extractDaylightStatus ( status: getStatus ( d )); 4150 return localMSecsToEpochMSecs ( localMsecs: getMSecs ( d ), daylightStatus: & status ); 4151 } 4153 case Qt:: TimeZone : 4154 # if QT_CONFIG (timezone) 4155 if ( d -> m_timeZone . isValid ()) { 4156 return QDateTimePrivate :: zoneMSecsToEpochMSecs ( zoneMSecs: d -> m_msecs , zone: d -> m_timeZone , 4157 hint: extractDaylightStatus ( status: getStatus ( d ))); 4158 } 4159 # endif 4160 return 0 ; 4161 } 4162 Q_UNREACHABLE (); 4163 return 0 ; 4164} 4166 /*! 4167 \since 5.8 4169 Returns the datetime as the number of seconds that have passed since 4170 1970-01-01T00:00:00.000, Coordinated Universal Time (Qt::UTC). 4172 On systems that do not support time zones, this function will 4173 behave as if local time were Qt::UTC. 4175 The behavior for this function is undefined if the datetime stored in 4176 this object is not valid. However, for all valid dates, this function 4177 returns a unique value. 4179 \sa toMSecsSinceEpoch(), setSecsSinceEpoch() 4180 */ 4181 qint64 QDateTime :: toSecsSinceEpoch () const 4182{ 4183 return toMSecsSinceEpoch () / 1000 ; 4184} 4186 # if QT_DEPRECATED_SINCE (5, 8) 4187 /*! 4188 \deprecated 4190 Returns the datetime as the number of seconds that have passed 4191 since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC). 4193 On systems that do not support time zones, this function will 4194 behave as if local time were Qt::UTC. 4196 \note This function returns a 32-bit unsigned integer and is deprecated. 4198 If the date is outside the range 1970-01-01T00:00:00 to 4199 2106-02-07T06:28:14, this function returns -1 cast to an unsigned integer 4200 (i.e., 0xFFFFFFFF). 4202 To get an extended range, use toMSecsSinceEpoch() or toSecsSinceEpoch(). 4204 \sa toSecsSinceEpoch(), toMSecsSinceEpoch(), setTime_t() 4205 */ 4207 uint QDateTime :: toTime_t () const 4208{ 4209 if (! isValid ()) 4210 return uint (- 1 ); 4211 qint64 retval = toMSecsSinceEpoch () / 1000 ; 4212 if ( quint64 ( retval ) >= Q_UINT64_C ( 0xFFFFFFFF )) 4213 return uint (- 1 ); 4214 return uint ( retval ); 4215} 4216 # endif 4218 /*! 4219 \since 4.7 4221 Sets the date and time given the number of milliseconds \a msecs that have 4222 passed since 1970-01-01T00:00:00.000, Coordinated Universal Time 4223 (Qt::UTC). On systems that do not support time zones this function 4224 will behave as if local time were Qt::UTC. 4226 Note that passing the minimum of \c qint64 4227 (\c {std::numeric_limits<qint64>::min()}) to \a msecs will result in 4228 undefined behavior. 4230 \sa toMSecsSinceEpoch(), setSecsSinceEpoch() 4231 */ 4232 void QDateTime :: setMSecsSinceEpoch ( qint64 msecs ) 4233{ 4234 const auto spec = getSpec ( d ); 4235 auto status = getStatus ( d ); 4237 status &= ~ QDateTimePrivate :: ValidityMask ; 4238 switch ( spec ) { 4239 case Qt:: UTC : 4240 status = status 4241 | QDateTimePrivate :: ValidDate 4242 | QDateTimePrivate :: ValidTime 4243 | QDateTimePrivate :: ValidDateTime ; 4244 break ; 4245 case Qt:: OffsetFromUTC : 4246 msecs = msecs + ( d -> m_offsetFromUtc * 1000 ); 4247 status = status 4248 | QDateTimePrivate :: ValidDate 4249 | QDateTimePrivate :: ValidTime 4250 | QDateTimePrivate :: ValidDateTime ; 4251 break ; 4252 case Qt:: TimeZone : 4253 Q_ASSERT (! d . isShort ()); 4254 # if QT_CONFIG (timezone) 4255 d . detach (); 4256 if (! d -> m_timeZone . isValid ()) 4257 break ; 4258 // Docs state any LocalTime before 1970-01-01 will *not* have any DST applied 4259 // but all affected times afterwards will have DST applied. 4260 if ( msecs >= 0 ) { 4261 status = mergeDaylightStatus ( sf: status , 4262 status: d -> m_timeZone . d -> isDaylightTime ( atMSecsSinceEpoch: msecs ) 4263 ? QDateTimePrivate :: DaylightTime 4264 : QDateTimePrivate :: StandardTime ); 4265 d -> m_offsetFromUtc = d -> m_timeZone . d -> offsetFromUtc ( atMSecsSinceEpoch: msecs ); 4266 } else { 4267 status = mergeDaylightStatus ( sf: status , status: QDateTimePrivate :: StandardTime ); 4268 d -> m_offsetFromUtc = d -> m_timeZone . d -> standardTimeOffset ( atMSecsSinceEpoch: msecs ); 4269 } 4270 msecs = msecs + ( d -> m_offsetFromUtc * 1000 ); 4271 status = status 4272 | QDateTimePrivate :: ValidDate 4273 | QDateTimePrivate :: ValidTime 4274 | QDateTimePrivate :: ValidDateTime ; 4275 # endif // timezone 4276 break ; 4277 case Qt:: LocalTime : { 4278 QDate dt ; 4279 QTime tm ; 4280 QDateTimePrivate :: DaylightStatus dstStatus ; 4281 epochMSecsToLocalTime ( msecs , localDate: & dt , localTime: & tm , daylightStatus: & dstStatus ); 4282 setDateTime ( d , date: dt , time: tm ); 4283 msecs = getMSecs ( d ); 4284 status = mergeDaylightStatus ( sf: getStatus ( d ), status: dstStatus ); 4285 break ; 4286 } 4287 } 4289 if ( msecsCanBeSmall ( msecs ) && d . isShort ()) { 4290 // we can keep short 4291 d . data . msecs = qintptr ( msecs ); 4292 d . data . status = status ; 4293 } else { 4294 d . detach (); 4295 d -> m_status = status & ~ QDateTimePrivate :: ShortData ; 4296 d -> m_msecs = msecs ; 4297 } 4299 if ( spec == Qt:: LocalTime || spec == Qt:: TimeZone ) 4300 refreshDateTime ( d ); 4301} 4303 /*! 4304 \since 5.8 4306 Sets the date and time given the number of seconds \a secs that have 4307 passed since 1970-01-01T00:00:00.000, Coordinated Universal Time 4308 (Qt::UTC). On systems that do not support time zones this function 4309 will behave as if local time were Qt::UTC. 4311 \sa toSecsSinceEpoch(), setMSecsSinceEpoch() 4312 */ 4313 void QDateTime :: setSecsSinceEpoch ( qint64 secs ) 4314{ 4315 setMSecsSinceEpoch ( secs * 1000 ); 4316} 4318 # if QT_DEPRECATED_SINCE (5, 8) 4319 /*! 4320 \fn void QDateTime::setTime_t(uint seconds) 4321 \deprecated 4323 Sets the date and time given the number of \a seconds that have 4324 passed since 1970-01-01T00:00:00, Coordinated Universal Time 4325 (Qt::UTC). On systems that do not support time zones this function 4326 will behave as if local time were Qt::UTC. 4328 \note This function is deprecated. For new code, use setSecsSinceEpoch(). 4330 \sa toTime_t() 4331 */ 4333 void QDateTime :: setTime_t ( uint secsSince1Jan1970UTC ) 4334{ 4335 setMSecsSinceEpoch (( qint64 ) secsSince1Jan1970UTC * 1000 ); 4336} 4337 # endif 4339 # if QT_CONFIG (datestring) // depends on, so implies, textdate 4340 /*! 4341 \overload 4343 Returns the datetime as a string in the \a format given. 4345 If the \a format is Qt::TextDate, the string is formatted in the default 4346 way. The day and month names will be localized names using the system 4347 locale, i.e. QLocale::system(). An example of this formatting is "Wed May 20 4348 03:40:13 1998". 4350 If the \a format is Qt::ISODate, the string format corresponds 4351 to the ISO 8601 extended specification for representations of 4352 dates and times, taking the form yyyy-MM-ddTHH:mm:ss[Z|[+|-]HH:mm], 4353 depending on the timeSpec() of the QDateTime. If the timeSpec() 4354 is Qt::UTC, Z will be appended to the string; if the timeSpec() is 4355 Qt::OffsetFromUTC, the offset in hours and minutes from UTC will 4356 be appended to the string. To include milliseconds in the ISO 8601 4357 date, use the \a format Qt::ISODateWithMs, which corresponds to 4358 yyyy-MM-ddTHH:mm:ss.zzz[Z|[+|-]HH:mm]. 4360 The \a format options Qt::SystemLocaleDate, Qt::SystemLocaleShortDate and 4361 Qt::SystemLocaleLongDate shall be removed in Qt 6. Their use should be 4362 replaced with 4363 \l {QLocale::toString()}{QLocale::system().toString(datetime, QLocale::ShortFormat)} or 4364 \l {QLocale::toString()}{QLocale::system().toString(datetime, QLocale::LongFormat)}. 4366 The \a format options Qt::LocaleDate, Qt::DefaultLocaleShortDate and 4367 Qt::DefaultLocaleLongDate shall be removed in Qt 6. Their use should be 4368 replaced with 4369 \l {QLocale::toString()}{QLocale().toString(datetime, QLocale::ShortFormat)} or 4370 \l {QLocale::toString()}{QLocale().toString(datetime, QLocale::LongFormat)}. 4372 If the \a format is Qt::RFC2822Date, the string is formatted 4373 following \l {RFC 2822}. 4375 If the datetime is invalid, an empty string will be returned. 4377 \warning The Qt::ISODate format is only valid for years in the 4378 range 0 to 9999. 4380 \sa fromString(), QDate::toString(), QTime::toString(), 4381 QLocale::toString() 4382 */ 4384 QString QDateTime :: toString ( Qt:: DateFormat format ) const 4385{ 4386 QString buf ; 4387 if (! isValid ()) 4388 return buf ; 4390 switch ( format ) { 4391 # if QT_DEPRECATED_SINCE (5, 15) 4392 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED 4393 case Qt:: SystemLocaleDate : 4394 case Qt:: SystemLocaleShortDate : 4395 return QLocale :: system (). toString ( dateTime: * this , format: QLocale :: ShortFormat ); 4396 case Qt:: SystemLocaleLongDate : 4397 return QLocale :: system (). toString ( dateTime: * this , format: QLocale :: LongFormat ); 4398 case Qt:: LocaleDate : 4399 case Qt:: DefaultLocaleShortDate : 4400 return QLocale ( ). toString ( dateTime: * this , format: QLocale :: ShortFormat ); 4401 case Qt:: DefaultLocaleLongDate : 4402 return QLocale ( ). toString ( dateTime: * this , format: QLocale :: LongFormat ); 4403 QT_WARNING_POP 4404 # endif // 5.15 4405 case Qt:: RFC2822Date : { 4406 buf = QLocale :: c (). toString ( dateTime: * this , format: u "dd MMM yyyy hh:mm:ss " ); 4407 buf += toOffsetString ( format: Qt:: TextDate , offset: offsetFromUtc ()); 4408 return buf ; 4409 } 4410 default : 4411 case Qt:: TextDate : { 4412 const QPair < QDate , QTime > p = getDateTime ( d ); 4413 buf = toStringTextDate ( date: p . first ); 4414 // Insert time between date's day and year: 4415 buf . insert ( i: buf . lastIndexOf ( c: QLatin1Char ( ' ' )), 4416 s: QLatin1Char ( ' ' ) + p . second . toString ( format: Qt:: TextDate )); 4417 // Append zone/offset indicator, as appropriate: 4418 switch ( timeSpec ()) { 4419 case Qt:: LocalTime : 4420 break ; 4421 # if QT_CONFIG (timezone) 4422 case Qt:: TimeZone : 4423 buf += QLatin1Char ( ' ' ) + d -> m_timeZone . abbreviation ( atDateTime: * this ); 4424 break ; 4425 # endif 4426 default : 4427 buf += QLatin1String ( " GMT" ); 4428 if ( getSpec ( d ) == Qt:: OffsetFromUTC ) 4429 buf += toOffsetString ( format: Qt:: TextDate , offset: offsetFromUtc ()); 4430 } 4431 return buf ; 4432 } 4433 case Qt:: ISODate : 4434 case Qt:: ISODateWithMs : { 4435 const QPair < QDate , QTime > p = getDateTime ( d ); 4436 buf = toStringIsoDate ( date: p . first ); 4437 if ( buf . isEmpty ()) 4438 return QString ( ); // failed to convert 4439 buf += QLatin1Char ( 'T' ) + p . second . toString ( format ); 4440 switch ( getSpec ( d )) { 4441 case Qt:: UTC : 4442 buf += QLatin1Char ( 'Z' ); 4443 break ; 4444 case Qt:: OffsetFromUTC : 4445 # if QT_CONFIG (timezone) 4446 case Qt:: TimeZone : 4447 # endif 4448 buf += toOffsetString ( format: Qt:: ISODate , offset: offsetFromUtc ()); 4449 break ; 4450 default : 4451 break ; 4452 } 4453 return buf ; 4454 } 4455 } 4456} 4458 /*! 4459 \fn QString QDateTime::toString(const QString &format) const 4460 \fn QString QDateTime::toString(const QString &format, QCalendar cal) const 4461 \fn QString QDateTime::toString(QStringView format) const 4462 \fn QString QDateTime::toString(QStringView format, QCalendar cal) const 4464 Returns the datetime as a string. The \a format parameter determines the 4465 format of the result string. If \a cal is supplied, it determines the calendar 4466 used to represent the date; it defaults to Gregorian. See QTime::toString() 4467 and QDate::toString() for the supported specifiers for time and date, 4468 respectively. 4470 Any sequence of characters enclosed in single quotes will be included 4471 verbatim in the output string (stripped of the quotes), even if it contains 4472 formatting characters. Two consecutive single quotes ("''") are replaced by 4473 a single quote in the output. All other characters in the format string are 4474 included verbatim in the output string. 4476 Formats without separators (e.g. "ddMM") are supported but must be used with 4477 care, as the resulting strings aren't always reliably readable (e.g. if "dM" 4478 produces "212" it could mean either the 2nd of December or the 21st of 4479 February). 4481 Example format strings (assumed that the QDateTime is 21 May 2001 4482 14:13:09.120): 4484 \table 4485 \header \li Format \li Result 4486 \row \li dd.MM.yyyy \li 21.05.2001 4487 \row \li ddd MMMM d yy \li Tue May 21 01 4488 \row \li hh:mm:ss.zzz \li 14:13:09.120 4489 \row \li hh:mm:ss.z \li 14:13:09.12 4490 \row \li h:m:s ap \li 2:13:9 pm 4491 \endtable 4493 If the datetime is invalid, an empty string will be returned. 4495 \note If localized month and day names are desired, please switch to using 4496 QLocale::system().toString() as QDateTime methods shall change to use 4497 English (C locale) names at Qt 6. 4499 \sa fromString(), QDate::toString(), QTime::toString(), QLocale::toString() 4500 */ 4501 QString QDateTime :: toString ( QStringView format ) const 4502{ 4503 return toString ( format , cal: QCalendar ( )); 4504} 4506 QString QDateTime :: toString ( QStringView format , QCalendar cal ) const 4507{ 4508 return QLocale :: system (). toString ( dateTime: * this , formatStr: format , cal ); // QLocale::c() ### Qt6 4509} 4511 # if QT_STRINGVIEW_LEVEL < 2 4512 QString QDateTime :: toString ( const QString & format ) const 4513{ 4514 return toString ( format: qToStringViewIgnoringNull ( s: format ), cal: QCalendar ( )); 4515} 4517 QString QDateTime :: toString ( const QString & format , QCalendar cal ) const 4518{ 4519 return toString ( format: qToStringViewIgnoringNull ( s: format ), cal ); 4520} 4521 # endif 4523 # endif // datestring 4525 static inline void massageAdjustedDateTime ( const QDateTimeData & d , QDate * date , QTime * time ) 4526{ 4527 /* 4528 If we have just adjusted to a day with a DST transition, our given time 4529 may lie in the transition hour (either missing or duplicated). For any 4530 other time, telling mktime (deep in the bowels of localMSecsToEpochMSecs) 4531 we don't know its DST-ness will produce no adjustment (just a decision as 4532 to its DST-ness); but for a time in spring's missing hour it'll adjust the 4533 time while picking a DST-ness. (Handling of autumn is trickier, as either 4534 DST-ness is valid, without adjusting the time. We might want to propagate 4535 the daylight status in that case, but it's hard to do so without breaking 4536 (far more common) other cases; and it makes little difference, as the two 4537 answers do then differ only in DST-ness.) 4538 */ 4539 auto spec = getSpec ( d ); 4540 if ( spec == Qt:: LocalTime ) { 4541 QDateTimePrivate :: DaylightStatus status = QDateTimePrivate :: UnknownDaylightTime ; 4542 localMSecsToEpochMSecs ( localMsecs: timeToMSecs ( date: * date , time: * time ), daylightStatus: & status , localDate: date , localTime: time ); 4543 # if QT_CONFIG (timezone) 4544 } else if ( spec == Qt:: TimeZone && d -> m_timeZone . isValid ()) { 4545 QDateTimePrivate :: zoneMSecsToEpochMSecs ( zoneMSecs: timeToMSecs ( date: * date , time: * time ), 4546 zone: d -> m_timeZone , 4547 hint: QDateTimePrivate :: UnknownDaylightTime , 4548 zoneDate: date , zoneTime: time ); 4549 # endif // timezone 4550 } 4551} 4553 /*! 4554 Returns a QDateTime object containing a datetime \a ndays days 4555 later than the datetime of this object (or earlier if \a ndays is 4556 negative). 4558 If the timeSpec() is Qt::LocalTime and the resulting 4559 date and time fall in the Standard Time to Daylight-Saving Time transition 4560 hour then the result will be adjusted accordingly, i.e. if the transition 4561 is at 2am and the clock goes forward to 3am and the result falls between 4562 2am and 3am then the result will be adjusted to fall after 3am. 4564 \sa daysTo(), addMonths(), addYears(), addSecs() 4565 */ 4567 QDateTime QDateTime :: addDays ( qint64 ndays ) const 4568{ 4569 QDateTime dt ( * this ); 4570 QPair < QDate , QTime > p = getDateTime ( d ); 4571 QDate & date = p . first ; 4572 QTime & time = p . second ; 4573 date = date . addDays ( ndays ); 4574 massageAdjustedDateTime ( d: dt . d , date: & date , time: & time ); 4575 setDateTime ( d&: dt . d , date , time ); 4576 return dt ; 4577} 4579 /*! 4580 Returns a QDateTime object containing a datetime \a nmonths months 4581 later than the datetime of this object (or earlier if \a nmonths 4582 is negative). 4584 If the timeSpec() is Qt::LocalTime and the resulting 4585 date and time fall in the Standard Time to Daylight-Saving Time transition 4586 hour then the result will be adjusted accordingly, i.e. if the transition 4587 is at 2am and the clock goes forward to 3am and the result falls between 4588 2am and 3am then the result will be adjusted to fall after 3am. 4590 \sa daysTo(), addDays(), addYears(), addSecs() 4591 */ 4593 QDateTime QDateTime :: addMonths ( int nmonths ) const 4594{ 4595 QDateTime dt ( * this ); 4596 QPair < QDate , QTime > p = getDateTime ( d ); 4597 QDate & date = p . first ; 4598 QTime & time = p . second ; 4599 date = date . addMonths ( nmonths ); 4600 massageAdjustedDateTime ( d: dt . d , date: & date , time: & time ); 4601 setDateTime ( d&: dt . d , date , time ); 4602 return dt ; 4603} 4605 /*! 4606 Returns a QDateTime object containing a datetime \a nyears years 4607 later than the datetime of this object (or earlier if \a nyears is 4608 negative). 4610 If the timeSpec() is Qt::LocalTime and the resulting 4611 date and time fall in the Standard Time to Daylight-Saving Time transition 4612 hour then the result will be adjusted accordingly, i.e. if the transition 4613 is at 2am and the clock goes forward to 3am and the result falls between 4614 2am and 3am then the result will be adjusted to fall after 3am. 4616 \sa daysTo(), addDays(), addMonths(), addSecs() 4617 */ 4619 QDateTime QDateTime :: addYears ( int nyears ) const 4620{ 4621 QDateTime dt ( * this ); 4622 QPair < QDate , QTime > p = getDateTime ( d ); 4623 QDate & date = p . first ; 4624 QTime & time = p . second ; 4625 date = date . addYears ( nyears ); 4626 massageAdjustedDateTime ( d: dt . d , date: & date , time: & time ); 4627 setDateTime ( d&: dt . d , date , time ); 4628 return dt ; 4629} 4631 /*! 4632 Returns a QDateTime object containing a datetime \a s seconds 4633 later than the datetime of this object (or earlier if \a s is 4634 negative). 4636 If this datetime is invalid, an invalid datetime will be returned. 4638 \sa addMSecs(), secsTo(), addDays(), addMonths(), addYears() 4639 */ 4641 QDateTime QDateTime :: addSecs ( qint64 s ) const 4642{ 4643 return addMSecs ( msecs: s * 1000 ); 4644} 4646 /*! 4647 Returns a QDateTime object containing a datetime \a msecs miliseconds 4648 later than the datetime of this object (or earlier if \a msecs is 4649 negative). 4651 If this datetime is invalid, an invalid datetime will be returned. 4653 \sa addSecs(), msecsTo(), addDays(), addMonths(), addYears() 4654 */ 4655 QDateTime QDateTime :: addMSecs ( qint64 msecs ) const 4656{ 4657 if (! isValid ()) 4658 return QDateTime ( ); 4660 QDateTime dt ( * this ); 4661 auto spec = getSpec ( d ); 4662 if ( spec == Qt:: LocalTime || spec == Qt:: TimeZone ) { 4663 // Convert to real UTC first in case crosses DST transition 4664 dt . setMSecsSinceEpoch ( toMSecsSinceEpoch () + msecs ); 4665 } else { 4666 // No need to convert, just add on 4667 if ( d . isShort ()) { 4668 // need to check if we need to enlarge first 4669 msecs += dt . d . data . msecs ; 4670 if ( msecsCanBeSmall ( msecs )) { 4671 dt . d . data . msecs = qintptr ( msecs ); 4672 } else { 4673 dt . d . detach (); 4674 dt . d -> m_msecs = msecs ; 4675 } 4676 } else { 4677 dt . d . detach (); 4678 dt . d -> m_msecs += msecs ; 4679 } 4680 } 4681 return dt ; 4682} 4684 /*! 4685 Returns the number of days from this datetime to the \a other 4686 datetime. The number of days is counted as the number of times 4687 midnight is reached between this datetime to the \a other 4688 datetime. This means that a 10 minute difference from 23:55 to 4689 0:05 the next day counts as one day. 4691 If the \a other datetime is earlier than this datetime, 4692 the value returned is negative. 4694 Example: 4695 \snippet code/src_corelib_tools_qdatetime.cpp 15 4697 \sa addDays(), secsTo(), msecsTo() 4698 */ 4700 qint64 QDateTime :: daysTo ( const QDateTime & other ) const 4701{ 4702 return date (). daysTo ( d: other . date ()); 4703} 4705 /*! 4706 Returns the number of seconds from this datetime to the \a other 4707 datetime. If the \a other datetime is earlier than this datetime, 4708 the value returned is negative. 4710 Before performing the comparison, the two datetimes are converted 4711 to Qt::UTC to ensure that the result is correct if daylight-saving 4712 (DST) applies to one of the two datetimes but not the other. 4714 Returns 0 if either datetime is invalid. 4716 Example: 4717 \snippet code/src_corelib_tools_qdatetime.cpp 11 4719 \sa addSecs(), daysTo(), QTime::secsTo() 4720 */ 4722 qint64 QDateTime :: secsTo ( const QDateTime & other ) const 4723{ 4724 return ( msecsTo ( other ) / 1000 ); 4725} 4727 /*! 4728 Returns the number of milliseconds from this datetime to the \a other 4729 datetime. If the \a other datetime is earlier than this datetime, 4730 the value returned is negative. 4732 Before performing the comparison, the two datetimes are converted 4733 to Qt::UTC to ensure that the result is correct if daylight-saving 4734 (DST) applies to one of the two datetimes and but not the other. 4736 Returns 0 if either datetime is invalid. 4738 \sa addMSecs(), daysTo(), QTime::msecsTo() 4739 */ 4741 qint64 QDateTime :: msecsTo ( const QDateTime & other ) const 4742{ 4743 if (! isValid () || ! other . isValid ()) 4744 return 0 ; 4746 return other . toMSecsSinceEpoch () - toMSecsSinceEpoch (); 4747} 4749 /*! 4750 \fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const 4752 Returns a copy of this datetime converted to the given time 4753 \a spec. 4755 If \a spec is Qt::OffsetFromUTC then it is set to Qt::UTC. To set to a 4756 spec of Qt::OffsetFromUTC use toOffsetFromUtc(). 4758 If \a spec is Qt::TimeZone then it is set to Qt::LocalTime, 4759 i.e. the local Time Zone. 4761 Example: 4762 \snippet code/src_corelib_tools_qdatetime.cpp 16 4764 \sa timeSpec(), toTimeZone(), toOffsetFromUtc() 4765 */ 4767 QDateTime QDateTime :: toTimeSpec ( Qt:: TimeSpec spec ) const 4768{ 4769 if ( getSpec ( d ) == spec && ( spec == Qt:: UTC || spec == Qt:: LocalTime )) 4770 return * this ; 4772 if (! isValid ()) { 4773 QDateTime ret = * this ; 4774 ret . setTimeSpec ( spec ); 4775 return ret ; 4776 } 4778 return fromMSecsSinceEpoch ( msecs: toMSecsSinceEpoch (), spec , offsetFromUtc: 0 ); 4779} 4781 /*! 4782 \since 5.2 4784 \fn QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const 4786 Returns a copy of this datetime converted to a spec of Qt::OffsetFromUTC 4787 with the given \a offsetSeconds. 4789 If the \a offsetSeconds equals 0 then a UTC datetime will be returned 4791 \sa setOffsetFromUtc(), offsetFromUtc(), toTimeSpec() 4792 */ 4794 QDateTime QDateTime :: toOffsetFromUtc ( int offsetSeconds ) const 4795{ 4796 if ( getSpec ( d ) == Qt:: OffsetFromUTC 4797 && d -> m_offsetFromUtc == offsetSeconds ) 4798 return * this ; 4800 if (! isValid ()) { 4801 QDateTime ret = * this ; 4802 ret . setOffsetFromUtc ( offsetSeconds ); 4803 return ret ; 4804 } 4806 return fromMSecsSinceEpoch ( msecs: toMSecsSinceEpoch (), spec: Qt:: OffsetFromUTC , offsetFromUtc: offsetSeconds ); 4807} 4809 # if QT_CONFIG (timezone) 4810 /*! 4811 \since 5.2 4813 Returns a copy of this datetime converted to the given \a timeZone 4815 \sa timeZone(), toTimeSpec() 4816 */ 4818 QDateTime QDateTime :: toTimeZone ( const QTimeZone & timeZone ) const 4819{ 4820 if ( getSpec ( d ) == Qt:: TimeZone && d -> m_timeZone == timeZone ) 4821 return * this ; 4823 if (! isValid ()) { 4824 QDateTime ret = * this ; 4825 ret . setTimeZone ( timeZone ); 4826 return ret ; 4827 } 4829 return fromMSecsSinceEpoch ( msecs: toMSecsSinceEpoch (), timeZone ); 4830} 4831 # endif // timezone 4833 /*! 4834 Returns \c true if this datetime is equal to the \a other datetime; 4835 otherwise returns \c false. 4837 Since 5.14, all invalid datetimes are equal to one another and differ from 4838 all other datetimes. 4840 \sa operator!=() 4841 */ 4843 bool QDateTime :: operator == ( const QDateTime & other ) const 4844{ 4845 if (! isValid ()) 4846 return ! other . isValid (); 4847 if (! other . isValid ()) 4848 return false ; 4850 if ( getSpec ( d ) == Qt:: LocalTime && getStatus ( d ) == getStatus ( d: other . d )) 4851 return getMSecs ( d ) == getMSecs ( d: other . d ); 4853 // Convert to UTC and compare 4854 return toMSecsSinceEpoch () == other . toMSecsSinceEpoch (); 4855} 4857 /*! 4858 \fn bool QDateTime::operator!=(const QDateTime &other) const 4860 Returns \c true if this datetime is different from the \a other 4861 datetime; otherwise returns \c false. 4863 Two datetimes are different if either the date, the time, or the time zone 4864 components are different. Since 5.14, any invalid datetime is less than all 4865 valid datetimes. 4867 \sa operator==() 4868 */ 4870 /*! 4871 Returns \c true if this datetime is earlier than the \a other 4872 datetime; otherwise returns \c false. 4873 */ 4875 bool QDateTime :: operator < ( const QDateTime & other ) const 4876{ 4877 if (! isValid ()) 4878 return other . isValid (); 4879 if (! other . isValid ()) 4880 return false ; 4882 if ( getSpec ( d ) == Qt:: LocalTime && getStatus ( d ) == getStatus ( d: other . d )) 4883 return getMSecs ( d ) < getMSecs ( d: other . d ); 4885 // Convert to UTC and compare 4886 return toMSecsSinceEpoch () < other . toMSecsSinceEpoch (); 4887} 4889 /*! 4890 \fn bool QDateTime::operator<=(const QDateTime &other) const 4892 Returns \c true if this datetime is earlier than or equal to the 4893 \a other datetime; otherwise returns \c false. 4894 */ 4896 /*! 4897 \fn bool QDateTime::operator>(const QDateTime &other) const 4899 Returns \c true if this datetime is later than the \a other datetime; 4900 otherwise returns \c false. 4901 */ 4903 /*! 4904 \fn bool QDateTime::operator>=(const QDateTime &other) const 4906 Returns \c true if this datetime is later than or equal to the 4907 \a other datetime; otherwise returns \c false. 4908 */ 4910 /*! 4911 \fn QDateTime QDateTime::currentDateTime() 4912 Returns the current datetime, as reported by the system clock, in 4913 the local time zone. 4915 \sa currentDateTimeUtc(), QDate::currentDate(), QTime::currentTime(), toTimeSpec() 4916 */ 4918 /*! 4919 \fn QDateTime QDateTime::currentDateTimeUtc() 4920 \since 4.7 4921 Returns the current datetime, as reported by the system clock, in 4922 UTC. 4924 \sa currentDateTime(), QDate::currentDate(), QTime::currentTime(), toTimeSpec() 4925 */ 4927 /*! 4928 \fn qint64 QDateTime::currentMSecsSinceEpoch() 4929 \since 4.7 4931 Returns the number of milliseconds since 1970-01-01T00:00:00 Universal 4932 Coordinated Time. This number is like the POSIX time_t variable, but 4933 expressed in milliseconds instead. 4935 \sa currentDateTime(), currentDateTimeUtc(), toTime_t(), toTimeSpec() 4936 */ 4938 /*! 4939 \fn qint64 QDateTime::currentSecsSinceEpoch() 4940 \since 5.8 4942 Returns the number of seconds since 1970-01-01T00:00:00 Universal 4943 Coordinated Time. 4945 \sa currentMSecsSinceEpoch() 4946 */ 4948 # if defined( Q_OS_WIN ) 4949 static inline uint msecsFromDecomposed( int hour, int minute, int sec, int msec = 0 ) 4950{ 4951 return MSECS_PER_HOUR * hour + MSECS_PER_MIN * minute + 1000 * sec + msec; 4952} 4954QDate QDate::currentDate() 4955{ 4956 SYSTEMTIME st; 4957 memset(&st, 0 , sizeof (SYSTEMTIME)); 4958 GetLocalTime(&st); 4959 return QDate(st.wYear, st.wMonth, st.wDay); 4960} 4962QTime QTime::currentTime() 4963{ 4964 QTime ct; 4965 SYSTEMTIME st; 4966 memset(&st, 0 , sizeof (SYSTEMTIME)); 4967 GetLocalTime(&st); 4968 ct.setHMS(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); 4969 return ct; 4970} 4972QDateTime QDateTime::currentDateTime() 4973{ 4974 QTime t; 4975 SYSTEMTIME st; 4976 memset(&st, 0 , sizeof (SYSTEMTIME)); 4977 GetLocalTime(&st); 4978 QDate d(st.wYear, st.wMonth, st.wDay); 4979 t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); 4980 return QDateTime(d, t); 4981} 4983QDateTime QDateTime::currentDateTimeUtc() 4984{ 4985 QTime t; 4986 SYSTEMTIME st; 4987 memset(&st, 0 , sizeof (SYSTEMTIME)); 4988 GetSystemTime(&st); 4989 QDate d(st.wYear, st.wMonth, st.wDay); 4990 t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); 4991 return QDateTime(d, t, Qt::UTC); 4992} 4994qint64 QDateTime::currentMSecsSinceEpoch() noexcept 4995{ 4996 SYSTEMTIME st; 4997 memset(&st, 0 , sizeof (SYSTEMTIME)); 4998 GetSystemTime(&st); 4999 const qint64 daysAfterEpoch = QDate( 1970 , 1 , 1 ).daysTo(QDate(st.wYear, st.wMonth, st.wDay)); 5001 return msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds) + 5002 daysAfterEpoch * Q_INT64_C( 86400000 ); 5003} 5005qint64 QDateTime::currentSecsSinceEpoch() noexcept 5006{ 5007 SYSTEMTIME st; 5008 memset(&st, 0 , sizeof (SYSTEMTIME)); 5009 GetSystemTime(&st); 5010 const qint64 daysAfterEpoch = QDate( 1970 , 1 , 1 ).daysTo(QDate(st.wYear, st.wMonth, st.wDay)); 5012 return st.wHour * SECS_PER_HOUR + st.wMinute * SECS_PER_MIN + st.wSecond + 5013 daysAfterEpoch * Q_INT64_C( 86400 ); 5014} 5016 # elif defined( Q_OS_UNIX ) 5017 QDate QDate :: currentDate () 5018{ 5019 return QDateTime :: currentDateTime (). date (); 5020} 5022 QTime QTime :: currentTime () 5023{ 5024 return QDateTime :: currentDateTime (). time (); 5025} 5027 QDateTime QDateTime :: currentDateTime () 5028{ 5029 return fromMSecsSinceEpoch ( msecs: currentMSecsSinceEpoch (), spec: Qt:: LocalTime ); 5030} 5032 QDateTime QDateTime :: currentDateTimeUtc () 5033{ 5034 return fromMSecsSinceEpoch ( msecs: currentMSecsSinceEpoch (), spec: Qt:: UTC ); 5035} 5037 qint64 QDateTime :: currentMSecsSinceEpoch () noexcept 5038{ 5039 // posix compliant system 5040 // we have milliseconds 5041 struct timeval tv ; 5042 gettimeofday ( tv: & tv , tz: nullptr ); 5043 return qint64 ( tv . tv_sec ) * Q_INT64_C ( 1000 ) + tv . tv_usec / 1000 ; 5044} 5046 qint64 QDateTime :: currentSecsSinceEpoch () noexcept 5047{ 5048 struct timeval tv ; 5049 gettimeofday ( tv: & tv , tz: nullptr ); 5050 return qint64 ( tv . tv_sec ); 5051} 5052 # else 5053 #error "What system is this?" 5054 # endif 5056 # if QT_DEPRECATED_SINCE (5, 8) 5057 /*! 5058 \since 4.2 5059 \deprecated 5061 Returns a datetime whose date and time are the number of \a seconds 5062 that have passed since 1970-01-01T00:00:00, Coordinated Universal 5063 Time (Qt::UTC) and converted to Qt::LocalTime. On systems that do not 5064 support time zones, the time will be set as if local time were Qt::UTC. 5066 \note This function is deprecated. Please use fromSecsSinceEpoch() in new 5067 code. 5069 \sa toTime_t(), setTime_t() 5070 */ 5071 QDateTime QDateTime :: fromTime_t ( uint seconds ) 5072{ 5073 return fromMSecsSinceEpoch ( msecs: ( qint64 ) seconds * 1000 , spec: Qt:: LocalTime ); 5074} 5076 /*! 5077 \since 5.2 5078 \deprecated 5080 Returns a datetime whose date and time are the number of \a seconds 5081 that have passed since 1970-01-01T00:00:00, Coordinated Universal 5082 Time (Qt::UTC) and converted to the given \a spec. 5084 If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be 5085 ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0 5086 then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds. 5088 \note This function is deprecated. Please use fromSecsSinceEpoch() in new 5089 code. 5091 \sa toTime_t(), setTime_t() 5092 */ 5093 QDateTime QDateTime :: fromTime_t ( uint seconds , Qt:: TimeSpec spec , int offsetSeconds ) 5094{ 5095 return fromMSecsSinceEpoch ( msecs: ( qint64 ) seconds * 1000 , spec , offsetFromUtc: offsetSeconds ); 5096} 5098 # if QT_CONFIG (timezone) 5099 /*! 5100 \since 5.2 5101 \deprecated 5103 Returns a datetime whose date and time are the number of \a seconds 5104 that have passed since 1970-01-01T00:00:00, Coordinated Universal 5105 Time (Qt::UTC) and with the given \a timeZone. 5107 \note This function is deprecated. Please use fromSecsSinceEpoch() in new 5108 code. 5110 \sa toTime_t(), setTime_t() 5111 */ 5112 QDateTime QDateTime :: fromTime_t ( uint seconds , const QTimeZone & timeZone ) 5113{ 5114 return fromMSecsSinceEpoch ( msecs: ( qint64 ) seconds * 1000 , timeZone ); 5115} 5116 # endif 5117 # endif // QT_DEPRECATED_SINCE(5, 8) 5119 /*! 5120 \since 4.7 5122 Returns a datetime whose date and time are the number of milliseconds, \a msecs, 5123 that have passed since 1970-01-01T00:00:00.000, Coordinated Universal 5124 Time (Qt::UTC), and converted to Qt::LocalTime. On systems that do not 5125 support time zones, the time will be set as if local time were Qt::UTC. 5127 Note that there are possible values for \a msecs that lie outside the valid 5128 range of QDateTime, both negative and positive. The behavior of this 5129 function is undefined for those values. 5131 \sa toMSecsSinceEpoch(), setMSecsSinceEpoch() 5132 */ 5133 QDateTime QDateTime :: fromMSecsSinceEpoch ( qint64 msecs ) 5134{ 5135 return fromMSecsSinceEpoch ( msecs , spec: Qt:: LocalTime ); 5136} 5138 /*! 5139 \since 5.2 5141 Returns a datetime whose date and time are the number of milliseconds \a msecs 5142 that have passed since 1970-01-01T00:00:00.000, Coordinated Universal 5143 Time (Qt::UTC) and converted to the given \a spec. 5145 Note that there are possible values for \a msecs that lie outside the valid 5146 range of QDateTime, both negative and positive. The behavior of this 5147 function is undefined for those values. 5149 If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be 5150 ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0 5151 then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds. 5153 If \a spec is Qt::TimeZone then the spec will be set to Qt::LocalTime, 5154 i.e. the current system time zone. 5156 \sa toMSecsSinceEpoch(), setMSecsSinceEpoch() 5157 */ 5158 QDateTime QDateTime :: fromMSecsSinceEpoch ( qint64 msecs , Qt:: TimeSpec spec , int offsetSeconds ) 5159{ 5160 QDateTime dt ; 5161 QT_PREPEND_NAMESPACE ( setTimeSpec ( dt . d , spec , offsetSeconds )); 5162 dt . setMSecsSinceEpoch ( msecs ); 5163 return dt ; 5164} 5166 /*! 5167 \since 5.8 5169 Returns a datetime whose date and time are the number of seconds \a secs 5170 that have passed since 1970-01-01T00:00:00.000, Coordinated Universal 5171 Time (Qt::UTC) and converted to the given \a spec. 5173 Note that there are possible values for \a secs that lie outside the valid 5174 range of QDateTime, both negative and positive. The behavior of this 5175 function is undefined for those values. 5177 If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be 5178 ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0 5179 then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds. 5181 If \a spec is Qt::TimeZone then the spec will be set to Qt::LocalTime, 5182 i.e. the current system time zone. 5184 \sa toSecsSinceEpoch(), setSecsSinceEpoch() 5185 */ 5186 QDateTime QDateTime :: fromSecsSinceEpoch ( qint64 secs , Qt:: TimeSpec spec , int offsetSeconds ) 5187{ 5188 return fromMSecsSinceEpoch ( msecs: secs * 1000 , spec , offsetSeconds ); 5189} 5191 # if QT_CONFIG (timezone) 5192 /*! 5193 \since 5.2 5195 Returns a datetime whose date and time are the number of milliseconds \a msecs 5196 that have passed since 1970-01-01T00:00:00.000, Coordinated Universal 5197 Time (Qt::UTC) and with the given \a timeZone. 5199 \sa fromSecsSinceEpoch() 5200 */ 5201 QDateTime QDateTime :: fromMSecsSinceEpoch ( qint64 msecs , const QTimeZone & timeZone ) 5202{ 5203 QDateTime dt ; 5204 dt . setTimeZone ( timeZone ); 5205 if ( timeZone . isValid ()) 5206 dt . setMSecsSinceEpoch ( msecs ); 5207 return dt ; 5208} 5210 /*! 5211 \since 5.8 5213 Returns a datetime whose date and time are the number of seconds \a secs 5214 that have passed since 1970-01-01T00:00:00.000, Coordinated Universal 5215 Time (Qt::UTC) and with the given \a timeZone. 5217 \sa fromMSecsSinceEpoch() 5218 */ 5219 QDateTime QDateTime :: fromSecsSinceEpoch ( qint64 secs , const QTimeZone & timeZone ) 5220{ 5221 return fromMSecsSinceEpoch ( msecs: secs * 1000 , timeZone ); 5222} 5223 # endif 5225 # if QT_DEPRECATED_SINCE (5, 2) 5226 /*! 5227 \since 4.4 5228 \internal 5229 \obsolete 5231 This method was added in 4.4 but never documented as public. It was replaced 5232 in 5.2 with public method setOffsetFromUtc() for consistency with QTimeZone. 5234 This method should never be made public. 5236 \sa setOffsetFromUtc() 5237 * / 5238 void QDateTime :: setUtcOffset ( int seconds ) 5239{ 5240 setOffsetFromUtc ( seconds ); 5241} 5243 /*! 5244 \since 4.4 5245 \internal 5246 \obsolete 5248 This method was added in 4.4 but never documented as public. It was replaced 5249 in 5.1 with public method offsetFromUTC() for consistency with QTimeZone. 5251 This method should never be made public. 5253 \sa offsetFromUTC() 5254 */ 5255 int QDateTime :: utcOffset () const 5256{ 5257 return offsetFromUtc (); 5258} 5259 # endif // QT_DEPRECATED_SINCE 5261 # if QT_CONFIG (datestring) // depends on, so implies, textdate 5263 /*! 5264 Returns the QDateTime represented by the \a string, using the 5265 \a format given, or an invalid datetime if this is not possible. 5267 Note for Qt::TextDate: It is recommended that you use the English short 5268 month names (e.g. "Jan"). Although localized month names can also be used in 5269 Qt 5, they depend on the user's locale settings. 5271 \note Support for localized dates, including the format options 5272 Qt::SystemLocaleDate, Qt::SystemLocaleShortDate, Qt::SystemLocaleLongDate, 5273 Qt::LocaleDate, Qt::DefaultLocaleShortDate, and Qt::DefaultLocaleLongDate, 5274 shall be removed in Qt 6. Use QLocale::toDateTime() instead. 5276 \sa toString(), QLocale::toDateTime() 5277 */ 5278 QDateTime QDateTime :: fromString ( const QString & string , Qt:: DateFormat format ) 5279{ 5280 if ( string . isEmpty ()) 5281 return QDateTime ( ); 5283 switch ( format ) { 5284 # if QT_DEPRECATED_SINCE (5, 15) 5285 QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED 5286 case Qt:: SystemLocaleDate : 5287 case Qt:: SystemLocaleShortDate : 5288 return QLocale :: system (). toDateTime ( string , format: QLocale :: ShortFormat ); 5289 case Qt:: SystemLocaleLongDate : 5290 return QLocale :: system (). toDateTime ( string , format: QLocale :: LongFormat ); 5291 case Qt:: LocaleDate : 5292 case Qt:: DefaultLocaleShortDate : 5293 return QLocale ( ). toDateTime ( string , format: QLocale :: ShortFormat ); 5294 case Qt:: DefaultLocaleLongDate : 5295 return QLocale ( ). toDateTime ( string , format: QLocale :: LongFormat ); 5296 QT_WARNING_POP 5297 # endif // 5.15 5298 case Qt:: RFC2822Date : { 5299 const ParsedRfcDateTime rfc = rfcDateImpl ( s: string ); 5301 if (! rfc . date . isValid () || ! rfc . time . isValid ()) 5302 return QDateTime ( ); 5304 QDateTime dateTime ( rfc . date , rfc . time , Qt:: UTC ); 5305 dateTime . setOffsetFromUtc ( rfc . utcOffset ); 5306 return dateTime ; 5307 } 5308 case Qt:: ISODate : 5309 case Qt:: ISODateWithMs : { 5310 const int size = string . size (); 5311 if ( size < 10 ) 5312 return QDateTime ( ); 5314 QDate date = QDate :: fromString ( string: string . left ( n: 10 ), format: Qt:: ISODate ); 5315 if (! date . isValid ()) 5316 return QDateTime ( ); 5317 if ( size == 10 ) 5318 return date . startOfDay (); 5320 Qt:: TimeSpec spec = Qt:: LocalTime ; 5321 QStringView isoString = QStringView ( string ). mid ( pos: 10 ); // trim "yyyy-MM-dd" 5323 // Must be left with T (or space) and at least one digit for the hour: 5324 if ( isoString . size () < 2 5325 || !( isoString . startsWith ( c: QLatin1Char ( 'T' ), cs: Qt:: CaseInsensitive ) 5326 // RFC 3339 (section 5.6) allows a space here. (It actually 5327 // allows any separator one considers more readable, merely 5328 // giving space as an example - but let's not go wild !) 5329 || isoString . startsWith ( c: QLatin1Char ( ' ' )))) { 5330 return QDateTime ( ); 5331 } 5332 isoString = isoString . mid ( pos: 1 ); // trim 'T' (or space) 5334 int offset = 0 ; 5335 // Check end of string for Time Zone definition, either Z for UTC or [+-]HH:mm for Offset 5336 if ( isoString . endsWith ( c: QLatin1Char ( 'Z' ), cs: Qt:: CaseInsensitive )) { 5337 spec = Qt:: UTC ; 5338 isoString . chop ( n: 1 ); // trim 'Z' 5339 } else { 5340 // the loop below is faster but functionally equal to: 5341 // const int signIndex = isoString.indexOf(QRegExp(QStringLiteral("[+-]"))); 5342 int signIndex = isoString . size () - 1 ; 5343 Q_ASSERT ( signIndex >= 0 ); 5344 bool found = false ; 5345 { 5346 const QChar plus = QLatin1Char ( '+' ); 5347 const QChar minus = QLatin1Char ( '-' ); 5348 do { 5349 QChar character ( isoString . at ( n: signIndex )); 5350 found = character == plus || character == minus ; 5351 } while (! found && -- signIndex >= 0 ); 5352 } 5354 if ( found ) { 5355 bool ok ; 5356 offset = fromOffsetString ( offsetString: isoString . mid ( pos: signIndex ), valid: & ok ); 5357 if (! ok ) 5358 return QDateTime ( ); 5359 isoString = isoString . left ( n: signIndex ); 5360 spec = Qt:: OffsetFromUTC ; 5361 } 5362 } 5364 // Might be end of day (24:00, including variants), which QTime considers invalid. 5365 // ISO 8601 (section 4.2.3) says that 24:00 is equivalent to 00:00 the next day. 5366 bool isMidnight24 = false ; 5367 QTime time = fromIsoTimeString ( string: isoString , format , isMidnight24: & isMidnight24 ); 5368 if (! time . isValid ()) 5369 return QDateTime ( ); 5370 if ( isMidnight24 ) 5371 date = date . addDays ( ndays: 1 ); 5372 return QDateTime ( date , time , spec , offset ); 5373 } 5374 case Qt:: TextDate : { 5375 QVector < QStringRef > parts = string . splitRef ( sep: QLatin1Char ( ' ' ), behavior: Qt:: SkipEmptyParts ); 5377 if (( parts . count () < 5 ) || ( parts . count () > 6 )) 5378 return QDateTime ( ); 5380 // Accept "Sun Dec 1 13:02:00 1974" and "Sun 1. Dec 13:02:00 1974" 5382 // Year and time can be in either order. 5383 // Guess which by looking for ':' in the time 5384 int yearPart = 3 ; 5385 int timePart = 3 ; 5386 if ( parts . at ( i: 3 ). contains ( c: QLatin1Char ( ':' ))) 5387 yearPart = 4 ; 5388 else if ( parts . at ( i: 4 ). contains ( c: QLatin1Char ( ':' ))) 5389 timePart = 4 ; 5390 else 5391 return QDateTime ( ); 5393 int month = 0 ; 5394 int day = 0 ; 5395 bool ok = false ; 5397 int year = parts . at ( i: yearPart ). toInt ( ok: & ok ); 5398 if (! ok || year == 0 ) 5399 return QDateTime ( ); 5401 // Next try month then day 5402 month = fromShortMonthName ( monthName: parts . at ( i: 1 ), year ); 5403 if ( month ) 5404 day = parts . at ( i: 2 ). toInt ( ok: & ok ); 5406 // If failed, try day then month 5407 if (! ok || ! month || ! day ) { 5408 month = fromShortMonthName ( monthName: parts . at ( i: 2 ), year ); 5409 if ( month ) { 5410 QStringRef dayStr = parts . at ( i: 1 ); 5411 if ( dayStr . endsWith ( c: QLatin1Char ( '.' ))) { 5412 dayStr = dayStr . left ( n: dayStr . size () - 1 ); 5413 day = dayStr . toInt ( ok: & ok ); 5414 } 5415 } 5416 } 5418 // If both failed, give up 5419 if (! ok || ! month || ! day ) 5420 return QDateTime ( ); 5422 QDate date ( year , month , day ); 5423 if (! date . isValid ()) 5424 return QDateTime ( ); 5426 QVector < QStringRef > timeParts = parts . at ( i: timePart ). split ( sep: QLatin1Char ( ':' )); 5427 if ( timeParts . count () < 2 || timeParts . count () > 3 ) 5428 return QDateTime ( ); 5430 int hour = timeParts . at ( i: 0 ). toInt ( ok: & ok ); 5431 if (! ok ) 5432 return QDateTime ( ); 5434 int minute = timeParts . at ( i: 1 ). toInt ( ok: & ok ); 5435 if (! ok ) 5436 return QDateTime ( ); 5438 int second = 0 ; 5439 int millisecond = 0 ; 5440 if ( timeParts . count () > 2 ) { 5441 const QVector < QStringRef > secondParts = timeParts . at ( i: 2 ). split ( sep: QLatin1Char ( '.' )); 5442 if ( secondParts . size () > 2 ) { 5443 return QDateTime ( ); 5444 } 5446 second = secondParts . first (). toInt ( ok: & ok ); 5447 if (! ok ) { 5448 return QDateTime ( ); 5449 } 5451 if ( secondParts . size () > 1 ) { 5452 millisecond = secondParts . last (). toInt ( ok: & ok ); 5453 if (! ok ) { 5454 return QDateTime ( ); 5455 } 5456 } 5457 } 5459 QTime time ( hour , minute , second , millisecond ); 5460 if (! time . isValid ()) 5461 return QDateTime ( ); 5463 if ( parts . count () == 5 ) 5464 return QDateTime ( date , time , Qt:: LocalTime ); 5466 QStringView tz = parts . at ( i: 5 ); 5467 if (! tz . startsWith ( s: QLatin1String ( "GMT" ), cs: Qt:: CaseInsensitive )) 5468 return QDateTime ( ); 5469 tz = tz . mid ( pos: 3 ); 5470 if (! tz . isEmpty ()) { 5471 int offset = fromOffsetString ( offsetString: tz , valid: & ok ); 5472 if (! ok ) 5473 return QDateTime ( ); 5474 return QDateTime ( date , time , Qt:: OffsetFromUTC , offset ); 5475 } else { 5476 return QDateTime ( date , time , Qt:: UTC ); 5477 } 5478 } 5479 } 5481 return QDateTime ( ); 5482} 5484 /*! 5485 Returns the QDateTime represented by the \a string, using the \a 5486 format given, or an invalid datetime if the string cannot be parsed. 5488 Uses the calendar \a cal if supplied, else Gregorian. 5490 In addition to the expressions, recognized in the format string to represent 5491 parts of the date and time, by QDate::fromString() and QTime::fromString(), 5492 this method supports: 5494 \table 5495 \header \li Expression \li Output 5496 \row \li t \li the timezone (for example "CEST") 5497 \endtable 5499 All other input characters will be treated as text. Any non-empty sequence 5500 of characters enclosed in single quotes will also be treated (stripped of 5501 the quotes) as text and not be interpreted as expressions. 5503 \snippet code/src_corelib_tools_qdatetime.cpp 12 5505 If the format is not satisfied, an invalid QDateTime is returned. 5506 The expressions that don't have leading zeroes (d, M, h, m, s, z) will be 5507 greedy. This means that they will use two digits even if this will 5508 put them outside the range and/or leave too few digits for other 5509 sections. 5511 \snippet code/src_corelib_tools_qdatetime.cpp 13 5513 This could have meant 1 January 00:30.00 but the M will grab 5514 two digits. 5516 Incorrectly specified fields of the \a string will cause an invalid 5517 QDateTime to be returned. For example, consider the following code, 5518 where the two digit year 12 is read as 1912 (see the table below for all 5519 field defaults); the resulting datetime is invalid because 23 April 1912 5520 was a Tuesday, not a Monday: 5522 \snippet code/src_corelib_tools_qdatetime.cpp 20 5524 The correct code is: 5526 \snippet code/src_corelib_tools_qdatetime.cpp 21 5528 For any field that is not represented in the format, the following 5529 defaults are used: 5531 \table 5532 \header \li Field \li Default value 5533 \row \li Year \li 1900 5534 \row \li Month \li 1 (January) 5535 \row \li Day \li 1 5536 \row \li Hour \li 0 5537 \row \li Minute \li 0 5538 \row \li Second \li 0 5539 \endtable 5541 For example: 5543 \snippet code/src_corelib_tools_qdatetime.cpp 14 5545 \note If localized month and day names are used, please switch to using 5546 QLocale::system().toDateTime() as QDateTime methods shall change to only 5547 recognize English (C locale) names at Qt 6. 5549 \sa toString(), QDate::fromString(), QTime::fromString(), 5550 QLocale::toDateTime() 5551 */ 5553 QDateTime QDateTime :: fromString ( const QString & string , const QString & format , QCalendar cal ) 5554{ 5555 # if QT_CONFIG (datetimeparser) 5556 QDateTime datetime ; 5558 QDateTimeParser dt ( QMetaType :: QDateTime , QDateTimeParser :: FromString , cal ); 5559 // dt.setDefaultLocale(QLocale::c()); ### Qt 6 5560 if ( dt . parseFormat ( format ) && dt . fromString ( text: string , datetime: & datetime )) 5561 return datetime ; 5562 # else 5563 Q_UNUSED(string); 5564 Q_UNUSED(format); 5565 Q_UNUSED(cal); 5566 # endif 5567 return QDateTime ( ); 5568} 5570 /* 5571 \overload 5572 */ 5574 QDateTime QDateTime :: fromString ( const QString & string , const QString & format ) 5575{ 5576 return fromString ( string , format , cal: QCalendar ( )); 5577} 5579 # endif // datestring 5580 /*! 5581 \fn QDateTime QDateTime::toLocalTime() const 5583 Returns a datetime containing the date and time information in 5584 this datetime, but specified using the Qt::LocalTime definition. 5586 Example: 5588 \snippet code/src_corelib_tools_qdatetime.cpp 17 5590 \sa toTimeSpec() 5591 */ 5593 /*! 5594 \fn QDateTime QDateTime::toUTC() const 5596 Returns a datetime containing the date and time information in 5597 this datetime, but specified using the Qt::UTC definition. 5599 Example: 5601 \snippet code/src_corelib_tools_qdatetime.cpp 18 5603 \sa toTimeSpec() 5604 */ 5606 /***************************************************************************** 5607 Date/time stream functions 5608 *****************************************************************************/ 5610 # ifndef QT_NO_DATASTREAM 5611 /*! 5612 \relates QDate 5614 Writes the \a date to stream \a out. 5616 \sa {Serializing Qt Data Types} 5617 */ 5619 QDataStream & operator << ( QDataStream & out , const QDate & date ) 5620{ 5621 if ( out . version () < QDataStream :: Qt_5_0 ) 5622 return out << quint32 ( date . jd ); 5623 else 5624 return out << qint64 ( date . jd ); 5625} 5627 /*! 5628 \relates QDate 5630 Reads a date from stream \a in into the \a date. 5632 \sa {Serializing Qt Data Types} 5633 */ 5635 QDataStream & operator >> ( QDataStream & in , QDate & date ) 5636{ 5637 if ( in . version () < QDataStream :: Qt_5_0 ) { 5638 quint32 jd ; 5639 in >> jd ; 5640 // Older versions consider 0 an invalid jd. 5641 date . jd = ( jd != 0 ? jd : QDate :: nullJd ()); 5642 } else { 5643 qint64 jd ; 5644 in >> jd ; 5645 date . jd = jd ; 5646 } 5648 return in ; 5649} 5651 /*! 5652 \relates QTime 5654 Writes \a time to stream \a out. 5656 \sa {Serializing Qt Data Types} 5657 */ 5659 QDataStream & operator << ( QDataStream & out , const QTime & time ) 5660{ 5661 if ( out . version () >= QDataStream :: Qt_4_0 ) { 5662 return out << quint32 ( time . mds ); 5663 } else { 5664 // Qt3 had no support for reading -1, QTime() was valid and serialized as 0 5665 return out << quint32 ( time . isNull () ? 0 : time . mds ); 5666 } 5667} 5669 /*! 5670 \relates QTime 5672 Reads a time from stream \a in into the given \a time. 5674 \sa {Serializing Qt Data Types} 5675 */ 5677 QDataStream & operator >> ( QDataStream & in , QTime & time ) 5678{ 5679 quint32 ds ; 5680 in >> ds ; 5681 if ( in . version () >= QDataStream :: Qt_4_0 ) { 5682 time . mds = int ( ds ); 5683 } else { 5684 // Qt3 would write 0 for a null time 5685 time . mds = ( ds == 0 ) ? QTime :: NullTime : int ( ds ); 5686 } 5687 return in ; 5688} 5690 /*! 5691 \relates QDateTime 5693 Writes \a dateTime to the \a out stream. 5695 \sa {Serializing Qt Data Types} 5696 */ 5697 QDataStream & operator << ( QDataStream & out , const QDateTime & dateTime ) 5698{ 5699 QPair < QDate , QTime > dateAndTime ; 5701 if ( out . version () >= QDataStream :: Qt_5_2 ) { 5703 // In 5.2 we switched to using Qt::TimeSpec and added offset support 5704 dateAndTime = getDateTime ( d: dateTime . d ); 5705 out << dateAndTime << qint8 ( dateTime . timeSpec ()); 5706 if ( dateTime . timeSpec () == Qt:: OffsetFromUTC ) 5707 out << qint32 ( dateTime . offsetFromUtc ()); 5708 # if QT_CONFIG (timezone) 5709 else if ( dateTime . timeSpec () == Qt:: TimeZone ) 5710 out << dateTime . timeZone (); 5711 # endif // timezone 5713 } else if ( out . version () == QDataStream :: Qt_5_0 ) { 5715 // In Qt 5.0 we incorrectly serialised all datetimes as UTC. 5716 // This approach is wrong and should not be used again; it breaks 5717 // the guarantee that a deserialised local datetime is the same time 5718 // of day, regardless of which timezone it was serialised in. 5719 dateAndTime = getDateTime ( d: ( dateTime . isValid () ? dateTime . toUTC () : dateTime ). d ); 5720 out << dateAndTime << qint8 ( dateTime . timeSpec ()); 5722 } else if ( out . version () >= QDataStream :: Qt_4_0 ) { 5724 // From 4.0 to 5.1 (except 5.0) we used QDateTimePrivate::Spec 5725 dateAndTime = getDateTime ( d: dateTime . d ); 5726 out << dateAndTime ; 5727 switch ( dateTime . timeSpec ()) { 5728 case Qt:: UTC : 5729 out << ( qint8 ) QDateTimePrivate :: UTC ; 5730 break ; 5731 case Qt:: OffsetFromUTC : 5732 out << ( qint8 ) QDateTimePrivate :: OffsetFromUTC ; 5733 break ; 5734 case Qt:: TimeZone : 5735 out << ( qint8 ) QDateTimePrivate :: TimeZone ; 5736 break ; 5737 case Qt:: LocalTime : 5738 out << ( qint8 ) QDateTimePrivate :: LocalUnknown ; 5739 break ; 5740 } 5742 } else { // version < QDataStream::Qt_4_0 5744 // Before 4.0 there was no TimeSpec, only Qt::LocalTime was supported 5745 dateAndTime = getDateTime ( d: dateTime . d ); 5746 out << dateAndTime ; 5748 } 5750 return out ; 5751} 5753 /*! 5754 \relates QDateTime 5756 Reads a datetime from the stream \a in into \a dateTime. 5758 \sa {Serializing Qt Data Types} 5759 */ 5761 QDataStream & operator >> ( QDataStream & in , QDateTime & dateTime ) 5762{ 5763 QDate dt ; 5764 QTime tm ; 5765 qint8 ts = 0 ; 5766 Qt:: TimeSpec spec = Qt:: LocalTime ; 5767 qint32 offset = 0 ; 5768 # if QT_CONFIG (timezone) 5769 QTimeZone tz ; 5770 # endif // timezone 5772 if ( in . version () >= QDataStream :: Qt_5_2 ) { 5774 // In 5.2 we switched to using Qt::TimeSpec and added offset support 5775 in >> dt >> tm >> ts ; 5776 spec = static_cast < Qt:: TimeSpec >( ts ); 5777 if ( spec == Qt:: OffsetFromUTC ) { 5778 in >> offset ; 5779 dateTime = QDateTime ( dt , tm , spec , offset ); 5780 # if QT_CONFIG (timezone) 5781 } else if ( spec == Qt:: TimeZone ) { 5782 in >> tz ; 5783 dateTime = QDateTime ( dt , tm , tz ); 5784 # endif // timezone 5785 } else { 5786 dateTime = QDateTime ( dt , tm , spec ); 5787 } 5789 } else if ( in . version () == QDataStream :: Qt_5_0 ) { 5791 // In Qt 5.0 we incorrectly serialised all datetimes as UTC 5792 in >> dt >> tm >> ts ; 5793 spec = static_cast < Qt:: TimeSpec >( ts ); 5794 dateTime = QDateTime ( dt , tm , Qt:: UTC ); 5795 dateTime = dateTime . toTimeSpec ( spec ); 5797 } else if ( in . version () >= QDataStream :: Qt_4_0 ) { 5799 // From 4.0 to 5.1 (except 5.0) we used QDateTimePrivate::Spec 5800 in >> dt >> tm >> ts ; 5801 switch (( QDateTimePrivate :: Spec ) ts ) { 5802 case QDateTimePrivate :: UTC : 5803 spec = Qt:: UTC ; 5804 break ; 5805 case QDateTimePrivate :: OffsetFromUTC : 5806 spec = Qt:: OffsetFromUTC ; 5807 break ; 5808 case QDateTimePrivate :: TimeZone : 5809 spec = Qt:: TimeZone ; 5810 # if QT_CONFIG (timezone) 5811 // FIXME: need to use a different constructor ! 5812 # endif 5813 break ; 5814 case QDateTimePrivate :: LocalUnknown : 5815 case QDateTimePrivate :: LocalStandard : 5816 case QDateTimePrivate :: LocalDST : 5817 spec = Qt:: LocalTime ; 5818 break ; 5819 } 5820 dateTime = QDateTime ( dt , tm , spec , offset ); 5822 } else { // version < QDataStream::Qt_4_0 5824 // Before 4.0 there was no TimeSpec, only Qt::LocalTime was supported 5825 in >> dt >> tm ; 5826 dateTime = QDateTime ( dt , tm , spec , offset ); 5828 } 5830 return in ; 5831} 5832 # endif // QT_NO_DATASTREAM 5834 /***************************************************************************** 5835 Date / Time Debug Streams 5836 *****************************************************************************/ 5838 # if !defined( QT_NO_DEBUG_STREAM ) && QT_CONFIG (datestring) 5839 QDebug operator << ( QDebug dbg , const QDate & date ) 5840{ 5841 QDebugStateSaver saver ( dbg ); 5842 dbg . nospace () << "QDate(" ; 5843 if ( date . isValid ()) 5844 dbg . nospace () << date . toString ( format: Qt:: ISODate ); 5845 else 5846 dbg . nospace () << "Invalid" ; 5847 dbg . nospace () << ')' ; 5848 return dbg ; 5849} 5851 QDebug operator << ( QDebug dbg , const QTime & time ) 5852{ 5853 QDebugStateSaver saver ( dbg ); 5854 dbg . nospace () << "QTime(" ; 5855 if ( time . isValid ()) 5856 dbg . nospace () << time . toString ( format: u "HH:mm:ss.zzz" ); 5857 else 5858 dbg . nospace () << "Invalid" ; 5859 dbg . nospace () << ')' ; 5860 return dbg ; 5861} 5863 QDebug operator << ( QDebug dbg , const QDateTime & date ) 5864{ 5865 QDebugStateSaver saver ( dbg ); 5866 dbg . nospace () << "QDateTime(" ; 5867 if ( date . isValid ()) { 5868 const Qt:: TimeSpec ts = date . timeSpec (); 5869 dbg . noquote () << date . toString ( format: u "yyyy-MM-dd HH:mm:ss.zzz t" ) 5870 << ' ' << ts ; 5871 switch ( ts ) { 5872 case Qt:: UTC : 5873 break ; 5874 case Qt:: OffsetFromUTC : 5875 dbg . space () << date . offsetFromUtc () << 's' ; 5876 break ; 5877 case Qt:: TimeZone : 5878 # if QT_CONFIG (timezone) 5879 dbg . space () << date . timeZone (). id (); 5880 # endif // timezone 5881 break ; 5882 case Qt:: LocalTime : 5883 break ; 5884 } 5885 } else { 5886 dbg . nospace () << "Invalid" ; 5887 } 5888 return dbg . nospace () << ')' ; 5889} 5890 # endif // debug_stream && datestring 5892 /*! \fn uint qHash(const QDateTime &key, uint seed = 0) 5893 \relates QHash 5894 \since 5.0 5896 Returns the hash value for the \a key, using \a seed to seed the calculation. 5897 */ 5898 uint qHash ( const QDateTime & key , uint seed ) 5899{ 5900 // Use to toMSecsSinceEpoch instead of individual qHash functions for 5901 // QDate/QTime/spec/offset because QDateTime::operator== converts both arguments 5902 // to the same timezone. If we don't, qHash would return different hashes for 5903 // two QDateTimes that are equivalent once converted to the same timezone. 5904 return key . isValid () ? qHash ( key: key . toMSecsSinceEpoch (), seed ) : seed ; 5905} 5907 /*! \fn uint qHash(const QDate &key, uint seed = 0) 5908 \relates QHash 5909 \since 5.0 5911 Returns the hash value for the \a key, using \a seed to seed the calculation. 5912 */ 5913 uint qHash ( const QDate & key , uint seed ) noexcept 5914{ 5915 return qHash ( key: key . toJulianDay (), seed ); 5916} 5918 /*! \fn uint qHash(const QTime &key, uint seed = 0) 5919 \relates QHash 5920 \since 5.0 5922 Returns the hash value for the \a key, using \a seed to seed the calculation. 5923 */ 5924 uint qHash ( const QTime & key , uint seed ) noexcept 5925{ 5926 return qHash ( key: key . msecsSinceStartOfDay (), seed ); 5927}