diff options
Diffstat (limited to 'src/corelib/tools/qdatetime.cpp')
-rw-r--r-- | src/corelib/tools/qdatetime.cpp | 198 |
1 files changed, 133 insertions, 65 deletions
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 11c023f762..d8d79dfeba 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -160,8 +160,7 @@ static ParsedDate getDateFromJulianDay(qint64 julianDay) if (year <= 0) --year ; - const ParsedDate result = { year, month, day }; - return result; + return { year, month, day }; } /***************************************************************************** @@ -212,7 +211,7 @@ static ParsedRfcDateTime rfcDateImpl(const QString &s) { ParsedRfcDateTime result; - // Matches "Wdy, DD Mon YYYY HH:mm:ss ±hhmm" (Wdy, being optional) + // Matches "Wdy, dd Mon yyyy HH:mm:ss ±hhmm" (Wdy, being optional) QRegExp rex(QStringLiteral("^(?:[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))?")); if (s.indexOf(rex) == 0) { const QStringList cap = rex.capturedTexts(); @@ -224,7 +223,7 @@ static ParsedRfcDateTime rfcDateImpl(const QString &s) const int minOffset = cap[9].toInt(); result.utcOffset = ((hourOffset * 60 + minOffset) * (positiveOffset ? 60 : -60)); } else { - // Matches "Wdy Mon DD HH:mm:ss YYYY" + // Matches "Wdy Mon dd HH:mm:ss yyyy" QRegExp rex(QStringLiteral("^[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))?")); if (s.indexOf(rex) == 0) { const QStringList cap = rex.capturedTexts(); @@ -646,13 +645,11 @@ int QDate::weekNumber(int *yearNumber) const QString QDate::shortMonthName(int month, QDate::MonthNameType type) { - if (month >= 1 || month <= 12) { - switch (type) { - case QDate::DateFormat: - return QLocale::system().monthName(month, QLocale::ShortFormat); - case QDate::StandaloneFormat: - return QLocale::system().standaloneMonthName(month, QLocale::ShortFormat); - } + switch (type) { + case QDate::DateFormat: + return QLocale::system().monthName(month, QLocale::ShortFormat); + case QDate::StandaloneFormat: + return QLocale::system().standaloneMonthName(month, QLocale::ShortFormat); } return QString(); } @@ -690,13 +687,11 @@ QString QDate::shortMonthName(int month, QDate::MonthNameType type) QString QDate::longMonthName(int month, MonthNameType type) { - if (month >= 1 && month <= 12) { - switch (type) { - case QDate::DateFormat: - return QLocale::system().monthName(month, QLocale::LongFormat); - case QDate::StandaloneFormat: - return QLocale::system().standaloneMonthName(month, QLocale::LongFormat); - } + switch (type) { + case QDate::DateFormat: + return QLocale::system().monthName(month, QLocale::LongFormat); + case QDate::StandaloneFormat: + return QLocale::system().standaloneMonthName(month, QLocale::LongFormat); } return QString(); } @@ -729,13 +724,11 @@ QString QDate::longMonthName(int month, MonthNameType type) QString QDate::shortDayName(int weekday, MonthNameType type) { - if (weekday >= 1 && weekday <= 7) { - switch (type) { - case QDate::DateFormat: - return QLocale::system().dayName(weekday, QLocale::ShortFormat); - case QDate::StandaloneFormat: - return QLocale::system().standaloneDayName(weekday, QLocale::ShortFormat); - } + switch (type) { + case QDate::DateFormat: + return QLocale::system().dayName(weekday, QLocale::ShortFormat); + case QDate::StandaloneFormat: + return QLocale::system().standaloneDayName(weekday, QLocale::ShortFormat); } return QString(); } @@ -768,13 +761,11 @@ QString QDate::shortDayName(int weekday, MonthNameType type) QString QDate::longDayName(int weekday, MonthNameType type) { - if (weekday >= 1 && weekday <= 7) { - switch (type) { - case QDate::DateFormat: - return QLocale::system().dayName(weekday, QLocale::LongFormat); - case QDate::StandaloneFormat: - return QLocale::system().standaloneDayName(weekday, QLocale::LongFormat); - } + switch (type) { + case QDate::DateFormat: + return QLocale::system().dayName(weekday, QLocale::LongFormat); + case QDate::StandaloneFormat: + return QLocale::system().standaloneDayName(weekday, QLocale::LongFormat); } return QString(); } @@ -819,8 +810,8 @@ static QString toStringIsoDate(qint64 jd) If the \a format is Qt::ISODate, the string format corresponds to the ISO 8601 extended specification for representations of - dates and times, taking the form YYYY-MM-DD, where YYYY is the - year, MM is the month of the year (between 01 and 12), and DD is + dates and times, taking the form yyyy-MM-dd, where yyyy is the + year, MM is the month of the year (between 01 and 12), and dd is the day of the month between 01 and 31. If the \a format is Qt::SystemLocaleShortDate or @@ -866,7 +857,7 @@ QString QDate::toString(Qt::DateFormat format) const case Qt::DefaultLocaleLongDate: return QLocale().toString(*this, QLocale::LongFormat); case Qt::RFC2822Date: - return QLocale::c().toString(*this, QStringLiteral("dd MMM yyyy")); + return QLocale::c().toString(*this, QStringViewLiteral("dd MMM yyyy")); default: #ifndef QT_NO_TEXTDATE case Qt::TextDate: @@ -879,6 +870,9 @@ QString QDate::toString(Qt::DateFormat format) const } /*! + \fn QString QDate::toString(const QString &format) const + \fn QString QDate::toString(QStringView format) const + Returns the date as a string. The \a format parameter determines the format of the result string. @@ -927,10 +921,18 @@ QString QDate::toString(Qt::DateFormat format) const \sa fromString(), QDateTime::toString(), QTime::toString(), QLocale::toString() */ -QString QDate::toString(const QString& format) const +QString QDate::toString(QStringView format) const { return QLocale::system().toString(*this, format); // QLocale::c() ### Qt6 } + +#if QT_STRINGVIEW_LEVEL < 2 +QString QDate::toString(const QString &format) const +{ + return toString(qToStringViewIgnoringNull(format)); +} +#endif + #endif //QT_NO_DATESTRING /*! @@ -1625,6 +1627,9 @@ QString QTime::toString(Qt::DateFormat format) const } /*! + \fn QString QTime::toString(const QString &format) const + \fn QString QTime::toString(QStringView format) const + Returns the time as a string. The \a format parameter determines the format of the result string. @@ -1679,11 +1684,20 @@ QString QTime::toString(Qt::DateFormat format) const \sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString() */ -QString QTime::toString(const QString& format) const +QString QTime::toString(QStringView format) const { return QLocale::system().toString(*this, format); // QLocale::c() ### Qt6 } + +#if QT_STRINGVIEW_VERSION < 2 +QString QTime::toString(const QString &format) const +{ + return toString(qToStringViewIgnoringNull(format)); +} +#endif + #endif //QT_NO_DATESTRING + /*! Sets the time to hour \a h, minute \a m, seconds \a s and milliseconds \a ms. @@ -2207,6 +2221,26 @@ static QString qt_tzname(QDateTimePrivate::DaylightStatus daylightStatus) #endif // Q_OS_WIN } +#ifndef QT_BOOTSTRAPPED +/* + \internal + Implemented here to share qt_tzname() +*/ +int QDateTimeParser::startsWithLocalTimeZone(const QStringRef name) +{ + QDateTimePrivate::DaylightStatus zones[2] = { + QDateTimePrivate::StandardTime, + QDateTimePrivate::DaylightTime + }; + for (const auto z : zones) { + QString zone(qt_tzname(z)); + if (name.startsWith(zone)) + return zone.size(); + } + return 0; +} +#endif // QT_BOOTSTRAPPED + // Calls the platform variant of mktime for the given date, time and daylightStatus, // and updates the date, time, daylightStatus and abbreviation with the returned values // If the date falls outside the 1970 to 2037 range supported by mktime / time_t @@ -3751,13 +3785,13 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC) If the \a format is Qt::ISODate, the string format corresponds to the ISO 8601 extended specification for representations of - dates and times, taking the form YYYY-MM-DDTHH:mm:ss[Z|[+|-]HH:mm], + dates and times, taking the form yyyy-MM-ddTHH:mm:ss[Z|[+|-]HH:mm], depending on the timeSpec() of the QDateTime. If the timeSpec() is Qt::UTC, Z will be appended to the string; if the timeSpec() is Qt::OffsetFromUTC, the offset in hours and minutes from UTC will be appended to the string. To include milliseconds in the ISO 8601 date, use the \a format Qt::ISODateWithMs, which corresponds to - YYYY-MM-DDTHH:mm:ss.zzz[Z|[+|-]HH:mm]. + yyyy-MM-ddTHH:mm:ss.zzz[Z|[+|-]HH:mm]. If the \a format is Qt::SystemLocaleShortDate or Qt::SystemLocaleLongDate, the string format depends on the locale @@ -3804,7 +3838,7 @@ QString QDateTime::toString(Qt::DateFormat format) const case Qt::DefaultLocaleLongDate: return QLocale().toString(*this, QLocale::LongFormat); case Qt::RFC2822Date: { - buf = QLocale::c().toString(*this, QStringLiteral("dd MMM yyyy hh:mm:ss ")); + buf = QLocale::c().toString(*this, QStringViewLiteral("dd MMM yyyy hh:mm:ss ")); buf += toOffsetString(Qt::TextDate, offsetFromUtc()); return buf; } @@ -3862,6 +3896,9 @@ QString QDateTime::toString(Qt::DateFormat format) const } /*! + \fn QString QDateTime::toString(const QString &format) const + \fn QString QDateTime::toString(QStringView format) const + Returns the datetime as a string. The \a format parameter determines the format of the result string. @@ -3939,10 +3976,18 @@ QString QDateTime::toString(Qt::DateFormat format) const \sa fromString(), QDate::toString(), QTime::toString(), QLocale::toString() */ -QString QDateTime::toString(const QString& format) const +QString QDateTime::toString(QStringView format) const { return QLocale::system().toString(*this, format); // QLocale::c() ### Qt6 } + +#if QT_STRINGVIEW_LEVEL < 2 +QString QDateTime::toString(const QString &format) const +{ + return toString(qToStringViewIgnoringNull(format)); +} +#endif + #endif //QT_NO_DATESTRING static inline void massageAdjustedDateTime(const QDateTimeData &d, QDate *date, QTime *time) @@ -4718,25 +4763,35 @@ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format) if (size < 10) return QDateTime(); - QStringRef isoString(&string); - Qt::TimeSpec spec = Qt::LocalTime; - QDate date = QDate::fromString(string.left(10), Qt::ISODate); if (!date.isValid()) return QDateTime(); if (size == 10) return QDateTime(date); - isoString = isoString.right(isoString.length() - 11); + Qt::TimeSpec spec = Qt::LocalTime; + QStringRef isoString(&string); + isoString = isoString.mid(10); // trim "yyyy-MM-dd" + + // Must be left with T and at least one digit for the hour: + if (isoString.size() < 2 + || !(isoString.startsWith(QLatin1Char('T')) + // FIXME: QSql relies on QVariant::toDateTime() accepting a space here: + || isoString.startsWith(QLatin1Char(' ')))) { + return QDateTime(); + } + isoString = isoString.mid(1); // trim 'T' (or space) + int offset = 0; // Check end of string for Time Zone definition, either Z for UTC or [+-]HH:mm for Offset if (isoString.endsWith(QLatin1Char('Z'))) { spec = Qt::UTC; - isoString = isoString.left(isoString.size() - 1); + isoString.chop(1); // trim 'Z' } else { // the loop below is faster but functionally equal to: // const int signIndex = isoString.indexOf(QRegExp(QStringLiteral("[+-]"))); int signIndex = isoString.size() - 1; + Q_ASSERT(signIndex >= 0); bool found = false; { const QChar plus = QLatin1Char('+'); @@ -4744,8 +4799,7 @@ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format) do { QChar character(isoString.at(signIndex)); found = character == plus || character == minus; - } while (--signIndex >= 0 && !found); - ++signIndex; + } while (!found && --signIndex >= 0); } if (found) { @@ -5275,39 +5329,53 @@ QDataStream &operator>>(QDataStream &in, QDateTime &dateTime) QDebug operator<<(QDebug dbg, const QDate &date) { QDebugStateSaver saver(dbg); - dbg.nospace() << "QDate(" << date.toString(Qt::ISODate) << ')'; + dbg.nospace() << "QDate("; + if (date.isValid()) + dbg.nospace() << date.toString(Qt::ISODate); + else + dbg.nospace() << "Invalid"; + dbg.nospace() << ')'; return dbg; } QDebug operator<<(QDebug dbg, const QTime &time) { QDebugStateSaver saver(dbg); - dbg.nospace() << "QTime(" << time.toString(QStringLiteral("HH:mm:ss.zzz")) << ')'; + dbg.nospace() << "QTime("; + if (time.isValid()) + dbg.nospace() << time.toString(QStringViewLiteral("HH:mm:ss.zzz")); + else + dbg.nospace() << "Invalid"; + dbg.nospace() << ')'; return dbg; } QDebug operator<<(QDebug dbg, const QDateTime &date) { QDebugStateSaver saver(dbg); - const Qt::TimeSpec ts = date.timeSpec(); dbg.nospace() << "QDateTime("; - dbg.noquote() << date.toString(QStringLiteral("yyyy-MM-dd HH:mm:ss.zzz t")) - << ' ' << ts; - switch (ts) { - case Qt::UTC: - break; - case Qt::OffsetFromUTC: - dbg << ' ' << date.offsetFromUtc() << 's'; - break; - case Qt::TimeZone: + if (date.isValid()) { + const Qt::TimeSpec ts = date.timeSpec(); + dbg.noquote() << date.toString(QStringViewLiteral("yyyy-MM-dd HH:mm:ss.zzz t")) + << ' ' << ts; + switch (ts) { + case Qt::UTC: + break; + case Qt::OffsetFromUTC: + dbg.space() << date.offsetFromUtc() << 's'; + break; + case Qt::TimeZone: #if QT_CONFIG(timezone) - dbg << ' ' << date.timeZone().id(); + dbg.space() << date.timeZone().id(); #endif // timezone - break; - case Qt::LocalTime: - break; + break; + case Qt::LocalTime: + break; + } + } else { + dbg.nospace() << "Invalid"; } - return dbg << ')'; + return dbg.nospace() << ')'; } #endif |