diff options
author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-04-24 16:43:14 +0300 |
---|---|---|
committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-04-24 16:43:14 +0300 |
commit | 29400a683f96867133b28299c0d0bd6bcf40df35 (patch) | |
tree | b616dfb91ce111d61a34a67b28069561306575da /src/corelib/time | |
parent | 42e4ae042a4c86e58bcb8b6d2d59ba4a988285b4 (diff) | |
parent | 9c60c8b122e5eb74fe74e11b929c30aa19ec0dd3 (diff) |
Merge remote-tracking branch 'origin/tqtc/lts-5.15.10' into tqtc/lts-5.15-opensourcev5.15.10-lts-lgpl
Change-Id: Ic1bb4240ca70a8a361fa0267476707446579221d
Diffstat (limited to 'src/corelib/time')
-rw-r--r-- | src/corelib/time/qdatetime.cpp | 46 | ||||
-rw-r--r-- | src/corelib/time/qdatetimeparser.cpp | 13 | ||||
-rw-r--r-- | src/corelib/time/qtimezoneprivate_android.cpp | 15 |
3 files changed, 49 insertions, 25 deletions
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index c30fd046a4..c1952f9bf5 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -90,6 +90,7 @@ enum { MSECS_PER_HOUR = 3600000, SECS_PER_MIN = 60, MSECS_PER_MIN = 60000, + MSECS_PER_SEC = 1000, TIME_T_MAX = 2145916799, // int maximum 2037-12-31T23:59:59 UTC JULIAN_DAY_FOR_EPOCH = 2440588 // result of julianDayFromDate(1970, 1, 1) }; @@ -4532,7 +4533,7 @@ QString QDateTime::toString(const QString &format, QCalendar cal) const #endif // datestring -static inline void massageAdjustedDateTime(const QDateTimeData &d, QDate *date, QTime *time) +static inline void massageAdjustedDateTime(QDateTimeData &d, QDate *date, QTime *time) { /* If we have just adjusted to a day with a DST transition, our given time @@ -4547,16 +4548,44 @@ static inline void massageAdjustedDateTime(const QDateTimeData &d, QDate *date, answers do then differ only in DST-ness.) */ auto spec = getSpec(d); + if (spec == Qt::OffsetFromUTC || spec == Qt::UTC) { + setDateTime(d, *date, *time); + checkValidDateTime(d); + return; + } + auto dst = extractDaylightStatus(getStatus(d)); + qint64 utc = 0; + qint64 local = timeToMSecs(*date, *time); if (spec == Qt::LocalTime) { - QDateTimePrivate::DaylightStatus status = QDateTimePrivate::UnknownDaylightTime; - localMSecsToEpochMSecs(timeToMSecs(*date, *time), &status, date, time); + utc = localMSecsToEpochMSecs(local, &dst, date, time); #if QT_CONFIG(timezone) } else if (spec == Qt::TimeZone && d.d->m_timeZone.isValid()) { - QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(*date, *time), - d.d->m_timeZone, - QDateTimePrivate::UnknownDaylightTime, - date, time); + utc = QDateTimePrivate::zoneMSecsToEpochMSecs(local, d.d->m_timeZone, dst, date, time); + // update dst, as it's passed to zoneMSecsToEpochMSecs() by value + dst = d.d->m_timeZone.isDaylightTime(QDateTime::fromMSecsSinceEpoch(utc)) + ? QDateTimePrivate::DaylightTime : QDateTimePrivate::StandardTime; #endif // timezone + } else { + dst = QDateTimePrivate::UnknownDaylightTime; + } + + setDateTime(d, *date, *time); + + auto status = getStatus(d); // Updated by setDateTime() + const bool ok = (dst != QDateTimePrivate::UnknownDaylightTime + && (status & QDateTimePrivate::ValidDate) + && (status & QDateTimePrivate::ValidTime)); + if (ok) + status = mergeDaylightStatus(status | QDateTimePrivate::ValidDateTime, dst); + else + status &= ~QDateTimePrivate::ValidDateTime; + + if (status & QDateTimePrivate::ShortData) { + d.data.status = status; + } else { + d->m_status = status; + if (ok) + d->m_offsetFromUtc = (local - utc) / MSECS_PER_SEC; } } @@ -4582,7 +4611,6 @@ QDateTime QDateTime::addDays(qint64 ndays) const QTime &time = p.second; date = date.addDays(ndays); massageAdjustedDateTime(dt.d, &date, &time); - setDateTime(dt.d, date, time); return dt; } @@ -4608,7 +4636,6 @@ QDateTime QDateTime::addMonths(int nmonths) const QTime &time = p.second; date = date.addMonths(nmonths); massageAdjustedDateTime(dt.d, &date, &time); - setDateTime(dt.d, date, time); return dt; } @@ -4634,7 +4661,6 @@ QDateTime QDateTime::addYears(int nyears) const QTime &time = p.second; date = date.addYears(nyears); massageAdjustedDateTime(dt.d, &date, &time); - setDateTime(dt.d, date, time); return dt; } diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp index c5e0493de5..ce28c6d034 100644 --- a/src/corelib/time/qdatetimeparser.cpp +++ b/src/corelib/time/qdatetimeparser.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -761,6 +761,11 @@ QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex, const int sectionmaxsize = sectionMaxSize(sectionIndex); QStringRef sectionTextRef = text->midRef(offset, sectionmaxsize); + // If the fields we've read thus far imply a time in a spring-forward, + // coerce to a nearby valid time: + const QDateTime defaultValue = currentValue.isValid() ? currentValue + : QDateTime::fromMSecsSinceEpoch(currentValue.toMSecsSinceEpoch()); + QDTPDEBUG << "sectionValue for" << sn.name() << "with text" << *text << "and (at" << offset << ") st:" << sectionTextRef; @@ -793,7 +798,7 @@ QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex, text->replace(offset, used, sectiontext.constData(), used); break; } case TimeZoneSection: - result = findTimeZone(sectionTextRef, currentValue, + result = findTimeZone(sectionTextRef, defaultValue, absoluteMax(sectionIndex), absoluteMin(sectionIndex)); break; @@ -805,7 +810,7 @@ QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex, int num = 0, used = 0; if (sn.type == MonthSection) { const QDate minDate = getMinimum().date(); - const int year = currentValue.date().year(calendar); + const int year = defaultValue.date().year(calendar); const int min = (year == minDate.year(calendar)) ? minDate.month(calendar) : 1; num = findMonth(sectiontext.toLower(), min, sectionIndex, year, §iontext, &used); } else { @@ -887,7 +892,7 @@ QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex, else QDTPDEBUG << "invalid because" << last << "is less than absoluteMin" << absMin; } else if (unfilled && (fi & (FixedWidth|Numeric)) == (FixedWidth|Numeric)) { - if (skipToNextSection(sectionIndex, currentValue, digitsStr)) { + if (skipToNextSection(sectionIndex, defaultValue, digitsStr)) { const int missingZeroes = sectionmaxsize - digitsStr.size(); result = ParsedSection(Acceptable, last, sectionmaxsize, missingZeroes); text->insert(offset, QString(missingZeroes, QLatin1Char('0'))); diff --git a/src/corelib/time/qtimezoneprivate_android.cpp b/src/corelib/time/qtimezoneprivate_android.cpp index da82832455..3609c65d55 100644 --- a/src/corelib/time/qtimezoneprivate_android.cpp +++ b/src/corelib/time/qtimezoneprivate_android.cpp @@ -86,17 +86,10 @@ QAndroidTimeZonePrivate::~QAndroidTimeZonePrivate() static QJNIObjectPrivate getDisplayName(QJNIObjectPrivate zone, jint style, jboolean dst, const QLocale &locale) { - QJNIObjectPrivate jlanguage - = QJNIObjectPrivate::fromString(QLocale::languageToString(locale.language())); - QJNIObjectPrivate jcountry - = QJNIObjectPrivate::fromString(QLocale::countryToString(locale.country())); - QJNIObjectPrivate - jvariant = QJNIObjectPrivate::fromString(QLocale::scriptToString(locale.script())); - QJNIObjectPrivate jlocale("java.util.Locale", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", - static_cast<jstring>(jlanguage.object()), - static_cast<jstring>(jcountry.object()), - static_cast<jstring>(jvariant.object())); + QJNIObjectPrivate jbcpTag = QJNIObjectPrivate::fromString(locale.bcp47Name()); + QJNIObjectPrivate jlocale = QJNIObjectPrivate::callStaticObjectMethod( + "java/util/Locale", "forLanguageTag", "(Ljava/lang/String;)Ljava/util/Locale;", + static_cast<jstring>(jbcpTag.object())); return zone.callObjectMethod("getDisplayName", "(ZILjava/util/Locale;)Ljava/lang/String;", |