diff --git a/src/corelib/time/qtimezone.cpp b/src/corelib/time/qtimezone.cpp index 64501907a9b..a89fe191a65 100644 --- a/src/corelib/time/qtimezone.cpp +++ b/src/corelib/time/qtimezone.cpp @@ -1486,8 +1486,18 @@ bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &ianaId) || global_tz->backend->isTimeZoneIdAvailable(ianaId); } +[[maybe_unused]] static bool isUniqueSorted(const QList &seq) +{ + // Since [..., b, a, ...] isn't unique-sorted if a <= b, at least the + // suggested implementations of is_sorted() and is_sorted_until() imply a + // non-unique sorted list will fail is_sorted() with <= comparison. + return std::is_sorted(seq.begin(), seq.end(), std::less_equal()); +} + static QList set_union(const QList &l1, const QList &l2) { + Q_ASSERT(isUniqueSorted(l1)); + Q_ASSERT(isUniqueSorted(l2)); QList result; result.reserve(l1.size() + l2.size()); std::set_union(l1.begin(), l1.end(), @@ -1511,6 +1521,7 @@ static QList set_union(const QList &l1, const QList QTimeZone::availableTimeZoneIds() { // Backends MUST implement availableTimeZoneIds(). + // The return from each backend MUST be sorted and unique. return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(), global_tz->backend->availableTimeZoneIds()); } diff --git a/src/corelib/time/qtimezoneprivate_android.cpp b/src/corelib/time/qtimezoneprivate_android.cpp index ec0710b1e4e..838f97c746c 100644 --- a/src/corelib/time/qtimezoneprivate_android.cpp +++ b/src/corelib/time/qtimezoneprivate_android.cpp @@ -203,14 +203,19 @@ QList QAndroidTimeZonePrivate::availableTimeZoneIds() const { using namespace QtJniTypes; - const QJniArray androidAvailableIdList = TimeZone::callStaticMethod("getAvailableIDs"); + const QJniArray androidAvailableIdList + = TimeZone::callStaticMethod("getAvailableIDs"); + // Does not document order of entries. - QList availableTimeZoneIdList; - availableTimeZoneIdList.reserve(androidAvailableIdList.size()); + QList result; + result.reserve(androidAvailableIdList.size()); for (const auto &id : androidAvailableIdList) - availableTimeZoneIdList.append(id.toString().toUtf8()); + result.append(id.toString().toUtf8()); - return availableTimeZoneIdList; + // Sort & uniquify (just to be sure; it appears to not need this, but we can't rely on that). + std::sort(result.begin(), result.end()); + result.erase(std::unique(result.begin(), result.end()), result.end()); + return result; } QT_END_NAMESPACE diff --git a/src/corelib/time/qtimezoneprivate_icu.cpp b/src/corelib/time/qtimezoneprivate_icu.cpp index f42ffe07678..30e6b17a7cb 100644 --- a/src/corelib/time/qtimezoneprivate_icu.cpp +++ b/src/corelib/time/qtimezoneprivate_icu.cpp @@ -408,9 +408,10 @@ QList QIcuTimeZonePrivate::availableTimeZoneIds() const { UErrorCode status = U_ZERO_ERROR; UEnumeration *uenum = ucal_openTimeZones(&status); + // Does not document order of entries. QList result; if (U_SUCCESS(status)) - result = uenumToIdList(uenum); + result = uenumToIdList(uenum); // Ensures sorted, unique. uenum_close(uenum); return result; }