1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QTIMEZONELOCALE_P_H
5#define QTIMEZONELOCALE_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of internal files. This header file may change from version to version
13// without notice, or even be removed.
14//
15// We mean it.
16//
17#include <private/qglobal_p.h>
18
19#include <QtCore/qstring.h>
20#include <QtCore/qtimezone.h>
21
22#if QT_CONFIG(icu)
23#include <unicode/ucal.h>
24#else
25#include <QtCore/private/qlocale_p.h> // for DataRange
26#endif
27
28QT_REQUIRE_CONFIG(timezone);
29QT_REQUIRE_CONFIG(timezone_locale);
30// #define QT_CLDR_ZONE_DEBUG
31
32QT_BEGIN_NAMESPACE
33
34namespace QtTimeZoneLocale {
35#if QT_CONFIG(icu)
36QString ucalTimeZoneDisplayName(UCalendar *ucal, QTimeZone::TimeType timeType,
37 QTimeZone::NameType nameType,
38 const QByteArray &localeCode);
39
40bool ucalKnownTimeZoneId(const QString &id);
41#else
42
43QList<QByteArrayView> ianaIdsForTerritory(QLocale::Territory territory);
44
45QList<qsizetype> fallbackLocalesFor(qsizetype index); // qlocale.cpp
46
47// Note: "repurposes" QLocale::FormatType with its own twisted meaning.
48// See comments in QTZL.cpp; qlocale.cpp has a fallback implementation.
49QString zoneOffsetFormat(const QLocale &locale, qsizetype locInd, QLocale::FormatType width,
50 const QDateTime &when, int offsetSeconds);
51
52// Define data types for QTZL_data_p.h
53
54// Accessor methods returning DataRange:
55#define rangeGetter(name) \
56 constexpr QLocaleData::DataRange name() const \
57 { return { m_ ## name ## _idx, m_ ## name ## _size }; }
58// Indices of starts of formats within their tables:
59#define declFieldIndex(name) quint16 m_ ## name ## _idx;
60#define declBigFieldIndex(name) quint32 m_ ## name ## _idx;
61// Lengths of formats:
62#define declFieldSize(name) quint8 m_ ## name ## _size;
63// Generic, standard, daylight-saving triples:
64#define forEachNameType(X, form) X(form ## Generic) X(form ## Standard) X(form ## DaylightSaving)
65// Mapping TimeType to the appropriate one of those:
66#define timeTypeRange(form) \
67 constexpr QLocaleData::DataRange form ## Name(QTimeZone::TimeType timeType) const \
68 { \
69 switch (timeType) { \
70 case QTimeZone::StandardTime: return form ## Standard(); \
71 case QTimeZone::DaylightTime: return form ## DaylightSaving(); \
72 case QTimeZone::GenericTime: return form ## Generic(); \
73 } \
74 Q_UNREACHABLE_RETURN({}); \
75 }
76// Mostly form is short or long and we want to append Name.
77// See kludge below for regionFormat, for which that's not the name the method wants.
78
79struct LocaleZoneData
80{
81#ifdef QT_CLDR_ZONE_DEBUG
82 // Only included when this define is set, for the sake of asserting
83 // consistency with QLocaleData at matching index in tables.
84 quint16 m_language_id, m_script_id, m_territory_id;
85#endif
86
87 // Indices for this locale:
88 quint32 m_exemplarTableStart; // first LocaleZoneExemplar
89 quint32 m_metaLongTableStart; // first LocaleMetaZoneLongNames
90 quint16 m_metaShortTableStart; // first LocaleMetaZoneShortNames
91 quint16 m_zoneTableStart; // first LocaleZoneNames
92
93 // Zone-independent formats:
94#define forEachField(X) \
95 X(posHourFormat) X(negHourFormat) X(offsetGmtFormat) X(fallbackFormat) \
96 forEachNameType(X, regionFormat)
97 // Hour formats: HH is hour, mm is minutes (always use two digits for each).
98 // GMT format: %0 is an hour format's result.
99 // Region formats: %0 is exemplar city or territory.
100 // Fallback format: %0 is exemplar city or territory, %1 is meta-zone name.
101
102 forEachField(rangeGetter)
103 forEachField(declFieldIndex)
104 forEachField(declFieldSize)
105
106#undef forEachField
107#define regionFormatName regionFormatRange // kludge naming
108 timeTypeRange(regionFormat)
109#undef regionFormatName
110};
111
112// Sorted by localeIndex, then ianaIdIndex
113struct LocaleZoneExemplar
114{
115 quint16 localeIndex; // Index in locale data tables
116 quint16 ianaIdIndex; // Location in IANA ID table
117 constexpr QByteArrayView ianaId() const; // Defined in QTZL.cpp
118 rangeGetter(exemplarCity);
119 quint32 m_exemplarCity_idx;
120 quint8 m_exemplarCity_size;
121};
122
123// Sorted by localeIndex, then ianaIdIndex
124struct LocaleZoneNames
125{
126 quint16 localeIndex; // Index in locale data tables
127 quint16 ianaIdIndex; // Location in IANA ID table
128 constexpr QByteArrayView ianaId() const; // Defined in QTZL.cpp
129 constexpr QLocaleData::DataRange name(QTimeZone::NameType nameType,
130 QTimeZone::TimeType timeType) const
131 {
132 return nameType == QTimeZone::ShortName ? shortName(timeType) : longName(timeType);
133 }
134 timeTypeRange(long)
135 timeTypeRange(short)
136#define forEach32BitField(X) forEachNameType(X, long)
137#define forEach16BitField(X) forEachNameType(X, short)
138#define forEachField(X) forEach32BitField(X) forEach16BitField(X)
139 // Localized name of exemplar city for zone.
140 // Long and short localized names (length zero for unspecified) for the zone
141 // in its generic, standard and daylight-saving forms.
142
143 forEachField(rangeGetter)
144 forEach32BitField(declBigFieldIndex)
145 forEach16BitField(declFieldIndex)
146 forEachField(declFieldSize)
147
148#undef forEachField
149#undef forEach16BitField
150#undef forEach32BitField
151};
152
153// Sorted by localeIndex, then metaIdIndex
154struct LocaleMetaZoneLongNames
155{
156 quint16 localeIndex; // Index in locale data tables
157 quint16 metaIdIndex; // As for MetaZoneData metaZoneTable[].
158 timeTypeRange(long)
159#define forEachField(X) forEachNameType(X, long)
160 // Long localized names (length zero for unspecified) for the
161 // metazone in its generic, standard and daylight-saving forms.
162
163 forEachField(rangeGetter)
164 forEachField(declBigFieldIndex)
165 forEachField(declFieldSize)
166
167#undef forEachField
168};
169
170// Sorted by localeIndex, then metaIdIndex
171struct LocaleMetaZoneShortNames
172{
173 quint16 localeIndex; // Index in locale data tables
174 quint16 metaIdIndex; // metaZoneTable[metaZoneKey - 1].metaIdIndex
175 timeTypeRange(short)
176#define forEachField(X) forEachNameType(X, short)
177 // Short localized names (length zero for unspecified) for the
178 // metazone in its generic, standard and daylight-saving forms.
179
180 forEachField(rangeGetter)
181 forEachField(declFieldIndex)
182 forEachField(declFieldSize)
183
184#undef forEachField
185};
186
187#undef timeTypeRange
188#undef forEachNameType
189#undef declFieldSize
190#undef declFieldIndex
191#undef rangeGetter
192#endif
193} // QtTimeZoneLocale
194
195QT_END_NAMESPACE
196
197#endif // QTIMEZONELOCALE_P_H
198

source code of qtbase/src/corelib/time/qtimezonelocale_p.h