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));
31 EXCEPTION_CHECKED(
return zone->get_info(chronoForEpochMillis(millis)),
return std::nullopt);
41 const tzdb &db = get_tzdb();
42 std::vector<std::string_view> raw, links, all;
43 auto now = system_clock::now();
44 for (
const time_zone &zone : db.zones) {
46 const sys_info info = zone.get_info(now);
47 if (info.offset.count() != *offset)
50 raw.push_back(zone.name());
52 for (
const time_zone_link &link : db.links) {
54 const std::string_view target = link.target();
55 const time_zone *zone = db.locate_zone(target);
56 const sys_info info = zone->get_info(now);
57 if (info.offset.count() != *offset)
60 links.push_back(link.name());
63 all.reserve(raw.size() + links.size());
64 std::set_union(raw.begin(), raw.end(), links.begin(), links.end(), std::back_inserter(all));
78fromSysInfo(std::chrono::sys_info info, qint64 atMSecsSinceEpoch)
80 QString abbreviation = QString::fromLatin1(info.abbrev);
81 int offsetFromUtc = info.offset.count();
83 int standardTimeOffset = offsetFromUtc - seconds(info.save).count();
84 return QChronoTimeZonePrivate::Data(abbreviation, atMSecsSinceEpoch,
85 offsetFromUtc, standardTimeOffset);
88QChronoTimeZonePrivate::QChronoTimeZonePrivate()
89 : m_timeZone(std::chrono::current_zone())
92 m_id.assign(m_timeZone->name());
95QChronoTimeZonePrivate::QChronoTimeZonePrivate(QByteArrayView id)
96 : m_timeZone(idToZone(std::string_view(id.data(), id.size())))
99 m_id.assign(m_timeZone->name());
102QChronoTimeZonePrivate *QChronoTimeZonePrivate::clone()
const
104 return new QChronoTimeZonePrivate(*
this);
107QChronoTimeZonePrivate::~QChronoTimeZonePrivate()
110QByteArray QChronoTimeZonePrivate::systemTimeZoneId()
const
112 if (
const time_zone *zone = std::chrono::current_zone()) {
113 std::string_view name = zone->name();
114 return {name.data(), qsizetype(name.size())};
119bool QChronoTimeZonePrivate::isTimeZoneIdAvailable(
const QByteArray &ianaId)
const
121 return idToZone(std::string_view(ianaId.data(), ianaId.size())) !=
nullptr;
124QList<QByteArray> QChronoTimeZonePrivate::availableTimeZoneIds()
const
126 QList<QByteArray> result;
127 if (
auto ids = allZoneIds()) {
128 result.reserve(ids->size());
129 for (std::string_view id : *ids)
130 result << QByteArray{id.data(), qsizetype(id.size())};
136QList<QByteArray> QChronoTimeZonePrivate::availableTimeZoneIds(
int utcOffset)
const
138 QList<QByteArray> result;
139 if (
auto ids = allZoneIds(utcOffset)) {
140 result.reserve(ids->size());
141 for (std::string_view id : *ids)
142 result << QByteArray{id.data(), qsizetype(id.size())};
148QString QChronoTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch)
const
150 if (
auto info = infoAtEpochMillis(m_timeZone, atMSecsSinceEpoch))
151 return fromSysInfo(*info, atMSecsSinceEpoch).abbreviation;
155int QChronoTimeZonePrivate::offsetFromUtc(qint64 atMSecsSinceEpoch)
const
157 if (
auto info = infoAtEpochMillis(m_timeZone, atMSecsSinceEpoch))
158 return fromSysInfo(*info, atMSecsSinceEpoch).offsetFromUtc;
159 return invalidSeconds();
162int QChronoTimeZonePrivate::standardTimeOffset(qint64 atMSecsSinceEpoch)
const
165 if (
auto info = infoAtEpochMillis(m_timeZone, atMSecsSinceEpoch))
166 return int((info->offset - info->save).count());
167 return invalidSeconds();
170int QChronoTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch)
const
172 if (
auto info = infoAtEpochMillis(m_timeZone, atMSecsSinceEpoch))
173 return int(std::chrono::seconds(info->save).count());
174 return invalidSeconds();
177bool QChronoTimeZonePrivate::hasDaylightTime()
const
179 Data data = QTimeZonePrivate::data(QTimeZone::DaylightTime);
180 return data.daylightTimeOffset != 0
181 && data.daylightTimeOffset != invalidSeconds();
184bool QChronoTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch)
const
186 if (
auto info = infoAtEpochMillis(m_timeZone, atMSecsSinceEpoch))
187 return info->save != 0min;
191QChronoTimeZonePrivate::Data
192QChronoTimeZonePrivate::data(qint64 forMSecsSinceEpoch)
const
194 if (
auto info = infoAtEpochMillis(m_timeZone, forMSecsSinceEpoch))
195 return fromSysInfo(*info, forMSecsSinceEpoch);
199bool QChronoTimeZonePrivate::hasTransitions()
const
204QChronoTimeZonePrivate::Data
205QChronoTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch)
const
207 if (
const auto info = infoAtEpochMillis(m_timeZone, afterMSecsSinceEpoch)) {
208 const auto tran = info->end;
209 qint64 when = milliseconds(tran.time_since_epoch()).count();
210 if (when > afterMSecsSinceEpoch)
211 return fromSysInfo(m_timeZone->get_info(tran), when);
217QChronoTimeZonePrivate::Data
218QChronoTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch)
const
220 if (
const auto info = infoAtEpochMillis(m_timeZone, beforeMSecsSinceEpoch - 1)) {
221 qint64 when = milliseconds(info->begin.time_since_epoch()).count();
222 if (when < beforeMSecsSinceEpoch)
223 return fromSysInfo(*info, when);
Combined button and popup list for selecting options.
#define EXCEPTION_CHECKED(expression, fallback)
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)