12using namespace std::chrono;
13using namespace std::chrono_literals;
15#define EXCEPTION_CHECKED(expression, fallback)
18 } QT_CATCH (const std::runtime_error &) {
25 return sys_time<milliseconds>(milliseconds(millis));
33 EXCEPTION_CHECKED(
return zone->get_info(chronoForEpochMillis(millis)),
return std::nullopt);
48 const tzdb &db = get_tzdb();
49 std::vector<std::string_view> raw, links, all;
50 auto now = system_clock::now();
51 for (
const time_zone &zone : db.zones) {
53 const sys_info info = zone.get_info(now);
54 if (info.offset.count() != *offset)
57 raw.push_back(zone.name());
59 for (
const time_zone_link &link : db.links) {
61 const std::string_view target = link.target();
62 const time_zone *zone = db.locate_zone(target);
63 const sys_info info = zone->get_info(now);
64 if (info.offset.count() != *offset)
67 links.push_back(link.name());
70 all.reserve(raw.size() + links.size());
71 std::set_union(raw.begin(), raw.end(), links.begin(), links.end(), std::back_inserter(all));
85fromSysInfo(std::chrono::sys_info info, qint64 atMSecsSinceEpoch)
87 QString abbreviation = QString::fromLatin1(info.abbrev);
88 int offsetFromUtc = info.offset.count();
90 int standardTimeOffset = offsetFromUtc - seconds(info.save).count();
91 return QChronoTimeZonePrivate::Data(abbreviation, atMSecsSinceEpoch,
92 offsetFromUtc, standardTimeOffset);
95QChronoTimeZonePrivate::QChronoTimeZonePrivate()
96 : m_timeZone(currentZone())
99 m_id.assign(m_timeZone->name());
102QChronoTimeZonePrivate::QChronoTimeZonePrivate(QByteArrayView id)
103 : m_timeZone(idToZone(std::string_view(id.data(), id.size())))
106 m_id.assign(m_timeZone->name());
109QChronoTimeZonePrivate *QChronoTimeZonePrivate::clone()
const
111 return new QChronoTimeZonePrivate(*
this);
114QChronoTimeZonePrivate::~QChronoTimeZonePrivate()
117QByteArray QChronoTimeZonePrivate::systemTimeZoneId()
const
119 if (
const time_zone *zone = currentZone()) {
120 std::string_view name = zone->name();
121 return {name.data(), qsizetype(name.size())};
126bool QChronoTimeZonePrivate::isTimeZoneIdAvailable(QByteArrayView ianaId)
const
128 return idToZone(std::string_view(ianaId.data(), ianaId.size())) !=
nullptr;
131QList<QByteArray> QChronoTimeZonePrivate::availableTimeZoneIds()
const
133 QList<QByteArray> result;
134 if (
auto ids = allZoneIds()) {
135 result.reserve(ids->size());
136 for (std::string_view id : *ids)
137 result << QByteArray{id.data(), qsizetype(id.size())};
143QList<QByteArray> QChronoTimeZonePrivate::availableTimeZoneIds(
int utcOffset)
const
145 QList<QByteArray> result;
146 if (
auto ids = allZoneIds(utcOffset)) {
147 result.reserve(ids->size());
148 for (std::string_view id : *ids)
149 result << QByteArray{id.data(), qsizetype(id.size())};
152 return padSortedWithAliases(result);
155QString QChronoTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch)
const
157 if (
auto info = infoAtEpochMillis(m_timeZone, atMSecsSinceEpoch))
158 return fromSysInfo(*info, atMSecsSinceEpoch).abbreviation;
162int QChronoTimeZonePrivate::offsetFromUtc(qint64 atMSecsSinceEpoch)
const
164 if (
auto info = infoAtEpochMillis(m_timeZone, atMSecsSinceEpoch))
165 return fromSysInfo(*info, atMSecsSinceEpoch).offsetFromUtc;
166 return invalidSeconds();
169int QChronoTimeZonePrivate::standardTimeOffset(qint64 atMSecsSinceEpoch)
const
172 if (
auto info = infoAtEpochMillis(m_timeZone, atMSecsSinceEpoch))
173 return int((info->offset - info->save).count());
174 return invalidSeconds();
177int QChronoTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch)
const
179 if (
auto info = infoAtEpochMillis(m_timeZone, atMSecsSinceEpoch))
180 return int(std::chrono::seconds(info->save).count());
181 return invalidSeconds();
184bool QChronoTimeZonePrivate::hasDaylightTime()
const
186 Data data = QTimeZonePrivate::data(QTimeZone::DaylightTime);
187 return data.daylightTimeOffset != 0
188 && data.daylightTimeOffset != invalidSeconds();
191bool QChronoTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch)
const
193 if (
auto info = infoAtEpochMillis(m_timeZone, atMSecsSinceEpoch))
194 return info->save != 0min;
198QChronoTimeZonePrivate::Data
199QChronoTimeZonePrivate::data(qint64 forMSecsSinceEpoch)
const
201 if (
auto info = infoAtEpochMillis(m_timeZone, forMSecsSinceEpoch))
202 return fromSysInfo(*info, forMSecsSinceEpoch);
206bool QChronoTimeZonePrivate::hasTransitions()
const
211QChronoTimeZonePrivate::Data
212QChronoTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch)
const
214 if (
const auto info = infoAtEpochMillis(m_timeZone, afterMSecsSinceEpoch)) {
215 const auto tran = info->end;
216 qint64 when = milliseconds(tran.time_since_epoch()).count();
217 if (when > afterMSecsSinceEpoch)
218 return fromSysInfo(m_timeZone->get_info(tran), when);
224QChronoTimeZonePrivate::Data
225QChronoTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch)
const
227 if (
const auto info = infoAtEpochMillis(m_timeZone, beforeMSecsSinceEpoch - 1)) {
228 qint64 when = milliseconds(info->begin.time_since_epoch()).count();
229 if (when < beforeMSecsSinceEpoch)
230 return fromSysInfo(*info, when);
Combined button and popup list for selecting options.
#define EXCEPTION_CHECKED(expression, fallback)
static const std::chrono::time_zone * currentZone()
static const std::vector< std::string_view > getAllZoneIds(std::optional< int > offset=std::nullopt)
static const std::optional< std::vector< std::string_view > > allZoneIds(std::optional< int > offset=std::nullopt)
static std::chrono::sys_time< std::chrono::milliseconds > chronoForEpochMillis(qint64 millis)
static const std::chrono::time_zone * idToZone(std::string_view id)
static QChronoTimeZonePrivate::Data fromSysInfo(std::chrono::sys_info info, qint64 atMSecsSinceEpoch)
static std::optional< std::chrono::sys_info > infoAtEpochMillis(const std::chrono::time_zone *zone, qint64 millis)