Process IANA ID lists joined by spaces correctly
The CLDR data from which they're obtained may contain a space-joined sequence of timezone IDs, rather than a single ID. (This applies principally to the mapping from MS-specific names to IANA IDs, but in principle may also apply to the other data obtained from same-shaped XML.) Note this on the methods of internal types and actually take it into account when using this data to match IDs. See CldrAccess.readWindowsTimeZones() in util/locale_database/cldr.py for the form of the CLDR data from which these are extracted; the type attributes of mapZone elements in the XML are the source of the space-joined lists of IANA IDs. Change-Id: I3f940e4c352d8312ff735f972c9f8f3961572884 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
72dd23cf53
commit
e5034cb453
@ -648,8 +648,12 @@ QByteArray QTimeZonePrivate::ianaIdToWindowsId(const QByteArray &id)
|
||||
QByteArray QTimeZonePrivate::windowsIdToDefaultIanaId(const QByteArray &windowsId)
|
||||
{
|
||||
for (const QWindowsData &data : windowsDataTable) {
|
||||
if (data.windowsId() == windowsId)
|
||||
return data.ianaId().toByteArray();
|
||||
if (data.windowsId() == windowsId) {
|
||||
QByteArrayView id = data.ianaId();
|
||||
if (qsizetype cut = id.indexOf(' '); cut >= 0)
|
||||
id = id.first(cut);
|
||||
return id.toByteArray();
|
||||
}
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
@ -702,6 +706,17 @@ template<> QTimeZonePrivate *QSharedDataPointer<QTimeZonePrivate>::clone()
|
||||
return d->clone();
|
||||
}
|
||||
|
||||
static bool isEntryInIanaList(QByteArrayView id, QByteArrayView ianaIds)
|
||||
{
|
||||
qsizetype cut;
|
||||
while ((cut = ianaIds.indexOf(' ')) >= 0) {
|
||||
if (id == ianaIds.first(cut))
|
||||
return true;
|
||||
ianaIds = ianaIds.sliced(cut);
|
||||
}
|
||||
return id == ianaIds;
|
||||
}
|
||||
|
||||
/*
|
||||
UTC Offset implementation, used when QT_NO_SYSTEMLOCALE set and ICU is not being used,
|
||||
or for QDateTimes with a Qt:Spec of Qt::OffsetFromUtc.
|
||||
@ -719,7 +734,7 @@ QUtcTimeZonePrivate::QUtcTimeZonePrivate(const QByteArray &id)
|
||||
{
|
||||
// Look for the name in the UTC list, if found set the values
|
||||
for (const QUtcData &data : utcDataTable) {
|
||||
if (data.id() == id) {
|
||||
if (isEntryInIanaList(id, data.id())) {
|
||||
QString name = QString::fromUtf8(id);
|
||||
init(id, data.offsetFromUtc, name, name, QLocale::AnyTerritory, name);
|
||||
break;
|
||||
@ -869,7 +884,7 @@ bool QUtcTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
|
||||
{
|
||||
// Only the zone IDs supplied by CLDR and recognized by constructor.
|
||||
for (const QUtcData &data : utcDataTable) {
|
||||
if (data.id() == ianaId)
|
||||
if (isEntryInIanaList(ianaId, data.id()))
|
||||
return true;
|
||||
}
|
||||
// But see offsetFromUtcString(), which lets us accept some "unavailable" IDs.
|
||||
@ -881,8 +896,15 @@ QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds() const
|
||||
// Only the zone IDs supplied by CLDR and recognized by constructor.
|
||||
QList<QByteArray> result;
|
||||
result.reserve(std::size(utcDataTable));
|
||||
for (const QUtcData &data : utcDataTable)
|
||||
result << data.id().toByteArray();
|
||||
for (const QUtcData &data : utcDataTable) {
|
||||
QByteArrayView id = data.id();
|
||||
qsizetype cut;
|
||||
while ((cut = id.indexOf(' ')) >= 0) {
|
||||
result << id.first(cut).toByteArray();
|
||||
id = id.sliced(cut);
|
||||
}
|
||||
result << id.toByteArray();
|
||||
}
|
||||
// Not guaranteed to be sorted, so sort:
|
||||
std::sort(result.begin(), result.end());
|
||||
// ### assuming no duplicates
|
||||
@ -903,8 +925,15 @@ QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds(qint32 offsetSeconds
|
||||
// and UTC-00:00 all have the same offset.)
|
||||
QList<QByteArray> result;
|
||||
for (const QUtcData &data : utcDataTable) {
|
||||
if (data.offsetFromUtc == offsetSeconds)
|
||||
result << data.id().toByteArray();
|
||||
if (data.offsetFromUtc == offsetSeconds) {
|
||||
QByteArrayView id = data.id();
|
||||
qsizetype cut;
|
||||
while ((cut = id.indexOf(' ')) >= 0) {
|
||||
result << id.first(cut).toByteArray();
|
||||
id = id.sliced(cut);
|
||||
}
|
||||
result << id.toByteArray();
|
||||
}
|
||||
}
|
||||
// Not guaranteed to be sorted, so sort:
|
||||
std::sort(result.begin(), result.end());
|
||||
|
@ -44,7 +44,7 @@ struct QZoneData
|
||||
quint16 windowsIdKey; // Windows ID Key
|
||||
quint16 territory; // Territory of IANA ID's, AnyTerritory means No Territory
|
||||
quint16 ianaIdIndex; // All IANA ID's for the Windows ID and Country, space separated
|
||||
inline QLatin1StringView id() const;
|
||||
inline QLatin1StringView id() const; // Space-joined list of IANA IDs
|
||||
inline auto ids() const { return id().tokenize(u' '); }
|
||||
};
|
||||
|
||||
@ -52,17 +52,17 @@ struct QWindowsData
|
||||
{
|
||||
quint16 windowsIdKey; // Windows ID Key
|
||||
quint16 windowsIdIndex; // Windows ID Literal
|
||||
quint16 ianaIdIndex; // Default IANA ID for the Windows ID
|
||||
quint16 ianaIdIndex; // IANA IDs for the Windows ID
|
||||
qint32 offsetFromUtc; // Standard Time Offset from UTC, used for quick look-ups
|
||||
inline QByteArrayView windowsId() const;
|
||||
inline QByteArrayView ianaId() const;
|
||||
inline QByteArrayView ianaId() const; // Space-joined list of IANA IDs
|
||||
};
|
||||
|
||||
struct QUtcData
|
||||
{
|
||||
quint16 ianaIdIndex; // IANA ID
|
||||
quint16 ianaIdIndex; // IANA IDs
|
||||
qint32 offsetFromUtc; // Offset form UTC is seconds
|
||||
inline QByteArrayView id() const;
|
||||
inline QByteArrayView id() const; // Space-joined list of IANA IDs
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1234,6 +1234,7 @@ static constexpr char ianaIdData[] = {
|
||||
// GENERATED PART ENDS HERE
|
||||
|
||||
inline QByteArrayView QWindowsData::windowsId() const { return windowsIdData + windowsIdIndex; }
|
||||
// Each of the following returns a space-joined sequence of IANA IDs:
|
||||
inline QByteArrayView QWindowsData::ianaId() const { return ianaIdData + ianaIdIndex; }
|
||||
inline QByteArrayView QUtcData::id() const { return ianaIdData + ianaIdIndex; }
|
||||
inline QLatin1StringView QZoneData::id() const
|
||||
|
Loading…
Reference in New Issue
Block a user