Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qtimezone.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2013 John Layt <jlayt@kde.org>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qtimezone.h"
6#if QT_CONFIG(timezone)
7# include "qtimezoneprivate_p.h"
8#endif
9
10#include <QtCore/qdatastream.h>
11#include <QtCore/qdatetime.h>
12
13#include <qdebug.h>
14
15#include <algorithm>
16
18
19using namespace Qt::StringLiterals;
20
21#if QT_CONFIG(timezone)
22// Create default time zone using appropriate backend
23static QTimeZonePrivate *newBackendTimeZone()
24{
25#if defined(Q_OS_DARWIN)
26 return new QMacTimeZonePrivate();
27#elif defined(Q_OS_ANDROID)
28 return new QAndroidTimeZonePrivate();
29#elif defined(Q_OS_UNIX)
30 return new QTzTimeZonePrivate();
31#elif QT_CONFIG(icu)
32 return new QIcuTimeZonePrivate();
33#elif defined(Q_OS_WIN)
34 return new QWinTimeZonePrivate();
35#else
36 return new QUtcTimeZonePrivate();
37#endif // Backend selection
38}
39
40// Create named time zone using appropriate backend
41static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
42{
43 Q_ASSERT(!ianaId.isEmpty());
44#if defined(Q_OS_DARWIN)
45 return new QMacTimeZonePrivate(ianaId);
46#elif defined(Q_OS_ANDROID)
47 return new QAndroidTimeZonePrivate(ianaId);
48#elif defined(Q_OS_UNIX)
49 return new QTzTimeZonePrivate(ianaId);
50#elif QT_CONFIG(icu)
51 return new QIcuTimeZonePrivate(ianaId);
52#elif defined(Q_OS_WIN)
53 return new QWinTimeZonePrivate(ianaId);
54#else
55 return new QUtcTimeZonePrivate(ianaId);
56#endif // Backend selection
57}
58
59class QTimeZoneSingleton
60{
61public:
62 QTimeZoneSingleton() : backend(newBackendTimeZone()) {}
63
64 // The global_tz is the tz to use in static methods such as
65 // availableTimeZoneIds() and isTimeZoneIdAvailable() and to create named
66 // IANA time zones. This is usually the host system, but may be different if
67 // the host resources are insufficient. A simple UTC backend is used if no
68 // alternative is available.
69 QExplicitlySharedDataPointer<QTimeZonePrivate> backend;
70};
71
72Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
73#endif // feature timezone
74
274#if QT_CONFIG(timezone)
363#endif // timezone backends
364
365QTimeZone::Data::Data() noexcept : d(nullptr)
366{
367 // Assumed by the conversion between spec and mode:
368 static_assert(int(Qt::TimeZone) == 3);
369}
370
371QTimeZone::Data::Data(const Data &other) noexcept
372{
373#if QT_CONFIG(timezone)
374 if (!other.isShort() && other.d)
375 other.d->ref.ref();
376#endif
377 d = other.d;
378}
379
380QTimeZone::Data::Data(QTimeZonePrivate *dptr) noexcept
381 : d(dptr)
382{
383#if QT_CONFIG(timezone)
384 if (d)
385 d->ref.ref();
386#endif
387}
388
389QTimeZone::Data::~Data()
390{
391#if QT_CONFIG(timezone)
392 if (!isShort() && d && !d->ref.deref())
393 delete d;
394 d = nullptr;
395#endif
396}
397
398QTimeZone::Data &QTimeZone::Data::operator=(const QTimeZone::Data &other) noexcept
399{
400#if QT_CONFIG(timezone)
401 if (!other.isShort())
402 return *this = other.d;
403 if (!isShort() && d && !d->ref.deref())
404 delete d;
405#endif
406 d = other.d;
407 return *this;
408}
409
415{
416 // Assumed by (at least) Data::swap() and {copy,move} {assign,construct}:
417 static_assert(sizeof(ShortData) <= sizeof(Data::d));
418 // Needed for ShortData::offset to represent all valid offsets:
419 static_assert(qintptr(1) << (sizeof(void *) * 8 - 2) >= MaxUtcOffsetSecs);
420}
421
422#if QT_CONFIG(timezone)
423QTimeZone::Data &QTimeZone::Data::operator=(QTimeZonePrivate *dptr) noexcept
424{
425 if (!isShort()) {
426 if (d == dptr)
427 return *this;
428 if (d && !d->ref.deref())
429 delete d;
430 }
431 if (dptr)
432 dptr->ref.ref();
433 d = dptr;
434 Q_ASSERT(!isShort());
435 return *this;
436}
437
451QTimeZone::QTimeZone(const QByteArray &ianaId)
452{
453 // Try and see if it's a recognized UTC offset ID - just as quick by
454 // creating as by looking up.
455 d = new QUtcTimeZonePrivate(ianaId);
456 // If not recognized, try creating it with the system backend.
457 if (!d->isValid()) {
458 if (ianaId.isEmpty())
459 d = newBackendTimeZone();
460 else // Constructor MUST produce invalid for unsupported ID.
461 d = newBackendTimeZone(ianaId);
462 }
463 // Can also handle UTC with arbitrary (valid) offset, but only do so as
464 // fall-back, since either of the above may handle it more informatively.
465 if (!d->isValid()) {
468 // Should have abs(offset) < 24 * 60 * 60 = 86400.
469 qint32 seconds = qint32(offset);
470 Q_ASSERT(qint64(seconds) == offset);
471 // NB: this canonicalises the name, so it might not match ianaId
472 d = new QUtcTimeZonePrivate(seconds);
473 }
474 }
475}
476
491QTimeZone::QTimeZone(int offsetSeconds)
492 : d((offsetSeconds >= MinUtcOffsetSecs && offsetSeconds <= MaxUtcOffsetSecs)
493 ? new QUtcTimeZonePrivate(offsetSeconds) : nullptr)
494{
495}
496
520QTimeZone::QTimeZone(const QByteArray &zoneId, int offsetSeconds, const QString &name,
521 const QString &abbreviation, QLocale::Territory territory, const QString &comment)
522 : d(QUtcTimeZonePrivate().isTimeZoneIdAvailable(zoneId)
523 || global_tz->backend->isTimeZoneIdAvailable(zoneId)
524 ? nullptr // Don't let client code hijack a real zone name.
525 : new QUtcTimeZonePrivate(zoneId, offsetSeconds, name, abbreviation, territory, comment))
526{
527}
528
538 : d(&dd)
539{
540}
541
565QTimeZone QTimeZone::asBackendZone() const
566{
567 switch (timeSpec()) {
568 case Qt::TimeZone:
569 return *this;
570 case Qt::LocalTime:
571 return systemTimeZone();
572 case Qt::UTC:
573 return utc();
575 return QTimeZone(*new QUtcTimeZonePrivate(int(d.s.offset)));
576 }
577 return QTimeZone();
578}
579#endif // timezone backends
580
680 : d(other.d)
681{
682}
683
697
710{
711 d = other.d;
712 return *this;
713}
714
744bool comparesEqual(const QTimeZone &lhs, const QTimeZone &rhs) noexcept
745{
746 if (lhs.d.isShort())
747 return rhs.d.isShort() && lhs.d.s == rhs.d.s;
748
749 if (!rhs.d.isShort()) {
750 if (lhs.d.d == rhs.d.d)
751 return true;
752#if QT_CONFIG(timezone)
753 return lhs.d.d && rhs.d.d && *lhs.d.d == *rhs.d.d;
754#endif
755 }
756
757 return false;
758}
759
765{
766#if QT_CONFIG(timezone)
767 if (!d.isShort())
768 return d.d && d->isValid();
769#endif
770 return d.isShort();
771}
772
773#if QT_CONFIG(timezone)
805QByteArray QTimeZone::id() const
806{
807 if (d.isShort()) {
808 switch (d.s.spec()) {
809 case Qt::UTC:
811 case Qt::LocalTime:
812 return systemTimeZoneId();
814 return QUtcTimeZonePrivate(d.s.offset).id();
815 case Qt::TimeZone:
816 Q_UNREACHABLE();
817 break;
818 }
819 } else if (d.d) {
820 return d->id();
821 }
822 return QByteArray();
823}
824
840QLocale::Territory QTimeZone::territory() const
841{
842 if (d.isShort()) {
843 if (d.s.spec() == Qt::LocalTime)
844 return systemTimeZone().territory();
845 } else if (isValid()) {
846 return d->territory();
847 }
849}
850
851#if QT_DEPRECATED_SINCE(6, 6)
860QLocale::Country QTimeZone::country() const
861{
862 return territory();
863}
864#endif
865
876QString QTimeZone::comment() const
877{
878 if (d.isShort()) {
879 // TODO: anything ? Or just stick with empty string ?
880 } else if (isValid()) {
881 return d->comment();
882 }
883 return QString();
884}
885
902QString QTimeZone::displayName(const QDateTime &atDateTime, NameType nameType,
903 const QLocale &locale) const
904{
905 if (d.isShort()) {
906 switch (d.s.spec()) {
907 case Qt::LocalTime:
908 return systemTimeZone().displayName(atDateTime, nameType, locale);
909 case Qt::UTC:
911 return QUtcTimeZonePrivate(d.s.offset).displayName(
912 atDateTime.toMSecsSinceEpoch(), nameType, locale);
913 case Qt::TimeZone:
914 Q_UNREACHABLE();
915 break;
916 }
917 } else if (isValid()) {
918 return d->displayName(atDateTime.toMSecsSinceEpoch(), nameType, locale);
919 }
920
921 return QString();
922}
923
941QString QTimeZone::displayName(TimeType timeType, NameType nameType,
942 const QLocale &locale) const
943{
944 if (d.isShort()) {
945 switch (d.s.spec()) {
946 case Qt::LocalTime:
947 return systemTimeZone().displayName(timeType, nameType, locale);
948 case Qt::UTC:
950 return QUtcTimeZonePrivate(d.s.offset).displayName(timeType, nameType, locale);
951 case Qt::TimeZone:
952 Q_UNREACHABLE();
953 break;
954 }
955 } else if (isValid()) {
956 return d->displayName(timeType, nameType, locale);
957 }
958
959 return QString();
960}
961
974QString QTimeZone::abbreviation(const QDateTime &atDateTime) const
975{
976 if (d.isShort()) {
977 switch (d.s.spec()) {
978 case Qt::LocalTime:
979 return systemTimeZone().abbreviation(atDateTime);
980 case Qt::UTC:
982 return QUtcTimeZonePrivate(d.s.offset).abbreviation(atDateTime.toMSecsSinceEpoch());
983 case Qt::TimeZone:
984 Q_UNREACHABLE();
985 break;
986 }
987 } else if (isValid()) {
988 return d->abbreviation(atDateTime.toMSecsSinceEpoch());
989 }
990
991 return QString();
992}
993
1010int QTimeZone::offsetFromUtc(const QDateTime &atDateTime) const
1011{
1012 if (d.isShort()) {
1013 switch (d.s.spec()) {
1014 case Qt::LocalTime:
1015 return systemTimeZone().offsetFromUtc(atDateTime);
1016 case Qt::UTC:
1017 case Qt::OffsetFromUTC:
1018 return d.s.offset;
1019 case Qt::TimeZone:
1020 Q_UNREACHABLE();
1021 break;
1022 }
1023 } else if (isValid()) {
1024 const int offset = d->offsetFromUtc(atDateTime.toMSecsSinceEpoch());
1026 return offset;
1027 }
1028 return 0;
1029}
1030
1045int QTimeZone::standardTimeOffset(const QDateTime &atDateTime) const
1046{
1047 if (d.isShort()) {
1048 switch (d.s.spec()) {
1049 case Qt::LocalTime:
1050 return systemTimeZone().standardTimeOffset(atDateTime);
1051 case Qt::UTC:
1052 case Qt::OffsetFromUTC:
1053 return d.s.offset;
1054 case Qt::TimeZone:
1055 Q_UNREACHABLE();
1056 break;
1057 }
1058 } else if (isValid()) {
1059 const int offset = d->standardTimeOffset(atDateTime.toMSecsSinceEpoch());
1061 return offset;
1062 }
1063 return 0;
1064}
1065
1080int QTimeZone::daylightTimeOffset(const QDateTime &atDateTime) const
1081{
1082 if (d.isShort()) {
1083 switch (d.s.spec()) {
1084 case Qt::LocalTime:
1085 return systemTimeZone().daylightTimeOffset(atDateTime);
1086 case Qt::UTC:
1087 case Qt::OffsetFromUTC:
1088 return 0;
1089 case Qt::TimeZone:
1090 Q_UNREACHABLE();
1091 break;
1092 }
1093 } else if (hasDaylightTime()) {
1094 const int offset = d->daylightTimeOffset(atDateTime.toMSecsSinceEpoch());
1096 return offset;
1097 }
1098 return 0;
1099}
1100
1109bool QTimeZone::hasDaylightTime() const
1110{
1111 if (d.isShort()) {
1112 switch (d.s.spec()) {
1113 case Qt::LocalTime:
1114 return systemTimeZone().hasDaylightTime();
1115 case Qt::UTC:
1116 case Qt::OffsetFromUTC:
1117 return false;
1118 case Qt::TimeZone:
1119 Q_UNREACHABLE();
1120 break;
1121 }
1122 } else if (isValid()) {
1123 return d->hasDaylightTime();
1124 }
1125 return false;
1126}
1127
1136bool QTimeZone::isDaylightTime(const QDateTime &atDateTime) const
1137{
1138 if (d.isShort()) {
1139 switch (d.s.spec()) {
1140 case Qt::LocalTime:
1141 return systemTimeZone().isDaylightTime(atDateTime);
1142 case Qt::UTC:
1143 case Qt::OffsetFromUTC:
1144 return false;
1145 case Qt::TimeZone:
1146 Q_UNREACHABLE();
1147 break;
1148 }
1149 } else if (hasDaylightTime()) {
1150 return d->isDaylightTime(atDateTime.toMSecsSinceEpoch());
1151 }
1152 return false;
1153}
1154
1168QTimeZone::OffsetData QTimeZone::offsetData(const QDateTime &forDateTime) const
1169{
1170 if (d.isShort()) {
1171 switch (d.s.spec()) {
1172 case Qt::LocalTime:
1173 return systemTimeZone().offsetData(forDateTime);
1174 case Qt::UTC:
1175 case Qt::OffsetFromUTC:
1176 return { abbreviation(forDateTime), forDateTime, int(d.s.offset), int(d.s.offset), 0 };
1177 case Qt::TimeZone:
1178 Q_UNREACHABLE();
1179 break;
1180 }
1181 }
1182 if (isValid())
1183 return QTimeZonePrivate::toOffsetData(d->data(forDateTime.toMSecsSinceEpoch()));
1184
1186}
1187
1199bool QTimeZone::hasTransitions() const
1200{
1201 if (d.isShort()) {
1202 switch (d.s.spec()) {
1203 case Qt::LocalTime:
1204 return systemTimeZone().hasTransitions();
1205 case Qt::UTC:
1206 case Qt::OffsetFromUTC:
1207 return false;
1208 case Qt::TimeZone:
1209 Q_UNREACHABLE();
1210 break;
1211 }
1212 } else if (isValid()) {
1213 return d->hasTransitions();
1214 }
1215 return false;
1216}
1217
1233QTimeZone::OffsetData QTimeZone::nextTransition(const QDateTime &afterDateTime) const
1234{
1235 if (d.isShort()) {
1236 switch (d.s.spec()) {
1237 case Qt::LocalTime:
1238 return systemTimeZone().nextTransition(afterDateTime);
1239 case Qt::UTC:
1240 case Qt::OffsetFromUTC:
1241 break;
1242 case Qt::TimeZone:
1243 Q_UNREACHABLE();
1244 break;
1245 }
1246 } else if (hasTransitions()) {
1247 return QTimeZonePrivate::toOffsetData(d->nextTransition(afterDateTime.toMSecsSinceEpoch()));
1248 }
1249
1251}
1252
1268QTimeZone::OffsetData QTimeZone::previousTransition(const QDateTime &beforeDateTime) const
1269{
1270 if (d.isShort()) {
1271 switch (d.s.spec()) {
1272 case Qt::LocalTime:
1273 return systemTimeZone().previousTransition(beforeDateTime);
1274 case Qt::UTC:
1275 case Qt::OffsetFromUTC:
1276 break;
1277 case Qt::TimeZone:
1278 Q_UNREACHABLE();
1279 break;
1280 }
1281 } else if (hasTransitions()) {
1283 d->previousTransition(beforeDateTime.toMSecsSinceEpoch()));
1284 }
1285
1287}
1288
1301QTimeZone::OffsetDataList QTimeZone::transitions(const QDateTime &fromDateTime,
1302 const QDateTime &toDateTime) const
1303{
1304 OffsetDataList list;
1305 if (d.isShort()) {
1306 switch (d.s.spec()) {
1307 case Qt::LocalTime:
1308 return systemTimeZone().transitions(fromDateTime, toDateTime);
1309 case Qt::UTC:
1310 case Qt::OffsetFromUTC:
1311 break;
1312 case Qt::TimeZone:
1313 Q_UNREACHABLE();
1314 break;
1315 }
1316 } else if (hasTransitions()) {
1317 const QTimeZonePrivate::DataList plist = d->transitions(fromDateTime.toMSecsSinceEpoch(),
1318 toDateTime.toMSecsSinceEpoch());
1319 list.reserve(plist.size());
1320 for (const QTimeZonePrivate::Data &pdata : plist)
1321 list.append(QTimeZonePrivate::toOffsetData(pdata));
1322 }
1323 return list;
1324}
1325
1326// Static methods
1327
1353QByteArray QTimeZone::systemTimeZoneId()
1354{
1355 QByteArray sys = global_tz->backend->systemTimeZoneId();
1356 if (!sys.isEmpty())
1357 return sys;
1358 // The system zone, despite the empty ID, may know its real ID anyway:
1359 return systemTimeZone().id();
1360}
1361
1380QTimeZone QTimeZone::systemTimeZone()
1381{
1382 // Use ID even if empty, as default constructor is invalid but empty-ID
1383 // constructor goes to backend's default constructor, which may succeed.
1384 const auto sys = QTimeZone(global_tz->backend->systemTimeZoneId());
1385 if (!sys.isValid()) {
1386 static bool neverWarned = true;
1387 if (neverWarned) {
1388 // Racey but, at worst, merely repeats the warning.
1389 neverWarned = false;
1390 qWarning("Unable to determine system time zone: "
1391 "please check your system configuration.");
1392 }
1393 }
1394 return sys;
1395}
1396
1408QTimeZone QTimeZone::utc()
1409{
1411}
1412
1424bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &ianaId)
1425{
1426#if defined(Q_OS_UNIX) && !(defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN))
1427 // Keep #if-ery consistent with selection of QTzTimeZonePrivate in
1428 // newBackendTimeZone(). Skip the pre-check, as the TZ backend accepts POSIX
1429 // zone IDs, which need not be valid IANA IDs. See also QTBUG-112006.
1430#else
1431 // isValidId is not strictly required, but faster to weed out invalid
1432 // IDs as availableTimeZoneIds() may be slow
1433 if (!QTimeZonePrivate::isValidId(ianaId))
1434 return false;
1435#endif
1438 || global_tz->backend->isTimeZoneIdAvailable(ianaId);
1439}
1440
1441static QList<QByteArray> set_union(const QList<QByteArray> &l1, const QList<QByteArray> &l2)
1442{
1443 QList<QByteArray> result;
1444 result.reserve(l1.size() + l2.size());
1445 std::set_union(l1.begin(), l1.end(),
1446 l2.begin(), l2.end(),
1447 std::back_inserter(result));
1448 return result;
1449}
1450
1463QList<QByteArray> QTimeZone::availableTimeZoneIds()
1464{
1465 return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(),
1466 global_tz->backend->availableTimeZoneIds());
1467}
1468
1482QList<QByteArray> QTimeZone::availableTimeZoneIds(QLocale::Territory territory)
1483{
1484 return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(territory),
1485 global_tz->backend->availableTimeZoneIds(territory));
1486}
1487
1501QList<QByteArray> QTimeZone::availableTimeZoneIds(int offsetSeconds)
1502{
1503 return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(offsetSeconds),
1504 global_tz->backend->availableTimeZoneIds(offsetSeconds));
1505}
1506
1515QByteArray QTimeZone::ianaIdToWindowsId(const QByteArray &ianaId)
1516{
1518}
1519
1533QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId)
1534{
1536}
1537
1552QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId,
1553 QLocale::Territory territory)
1554{
1555 return QTimeZonePrivate::windowsIdToDefaultIanaId(windowsId, territory);
1556}
1557
1568QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId)
1569{
1570 return QTimeZonePrivate::windowsIdToIanaIds(windowsId);
1571}
1572
1587QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
1588 QLocale::Territory territory)
1589{
1590 return QTimeZonePrivate::windowsIdToIanaIds(windowsId, territory);
1591}
1592
1603#endif // feature timezone
1604
1605template <typename Stream, typename Wrap>
1606void QTimeZone::Data::serialize(Stream &out, const Wrap &wrap) const
1607{
1608 if (isShort()) {
1609 switch (s.spec()) {
1610 case Qt::UTC:
1611 out << wrap("QTimeZone::UTC");
1612 break;
1613 case Qt::LocalTime:
1614 out << wrap("QTimeZone::LocalTime");
1615 break;
1616 case Qt::OffsetFromUTC:
1617 out << wrap("AheadOfUtcBy") << int(s.offset);
1618 break;
1619 case Qt::TimeZone:
1620 Q_UNREACHABLE();
1621 break;
1622 }
1623 return;
1624 }
1625#if QT_CONFIG(timezone)
1626 if constexpr (std::is_same<Stream, QDataStream>::value) {
1627 if (d)
1628 d->serialize(out);
1629 } else {
1630 // QDebug, traditionally gets a QString, hence quotes round the (possibly empty) ID:
1632 }
1633#endif
1634}
1635
1636#ifndef QT_NO_DATASTREAM
1637// Invalid, as an IANA ID: too long, starts with - and has other invalid characters in it
1638static inline QString invalidId() { return QStringLiteral("-No Time Zone Specified!"); }
1639
1641{
1642 const auto toQString = [](const char *text) {
1644 };
1645 if (tz.isValid())
1646 tz.d.serialize(ds, toQString);
1647 else
1648 ds << invalidId();
1649 return ds;
1650}
1651
1653{
1654 QString ianaId;
1655 ds >> ianaId;
1656 // That may be various things other than actual IANA IDs:
1657 if (ianaId == invalidId()) {
1658 tz = QTimeZone();
1659 } else if (ianaId == "OffsetFromUtc"_L1) {
1660 int utcOffset;
1661 QString name;
1662 QString abbreviation;
1663 int territory;
1664 QString comment;
1665 ds >> ianaId >> utcOffset >> name >> abbreviation >> territory >> comment;
1666#if QT_CONFIG(timezone)
1667 // Try creating as a system timezone, which succeeds (producing a valid
1668 // zone) iff ianaId is valid; use this if it is a plain offset from UTC
1669 // zone, with the right offset, ignoring the other data:
1670 tz = QTimeZone(ianaId.toUtf8());
1671 if (!tz.isValid() || tz.hasDaylightTime()
1672 || tz.offsetFromUtc(QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC)) != utcOffset) {
1673 // Construct a custom timezone using the saved values:
1674 tz = QTimeZone(ianaId.toUtf8(), utcOffset, name, abbreviation,
1675 QLocale::Territory(territory), comment);
1676 }
1677#else
1679#endif
1680 } else if (ianaId == "AheadOfUtcBy"_L1) {
1681 int utcOffset;
1682 ds >> utcOffset;
1684 } else if (ianaId == "QTimeZone::UTC"_L1) {
1686 } else if (ianaId == "QTimeZone::LocalTime"_L1) {
1688#if QT_CONFIG(timezone)
1689 } else {
1690 tz = QTimeZone(ianaId.toUtf8());
1691#endif
1692 }
1693 return ds;
1694}
1695#endif // QT_NO_DATASTREAM
1696
1697#ifndef QT_NO_DEBUG_STREAM
1699{
1700 QDebugStateSaver saver(dbg);
1701 const auto asIs = [](const char *text) { return text; };
1702 // TODO Include backend and data version details?
1703 dbg.nospace() << "QTimeZone(";
1704 tz.d.serialize(dbg, asIs);
1705 dbg.nospace() << ')';
1706 return dbg;
1707}
1708#endif
1709
bool ref() noexcept
bool deref() noexcept
\inmodule QtCore
Definition qbytearray.h:57
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
\inmodule QtCore\reentrant
Definition qdatastream.h:46
\inmodule QtCore\reentrant
Definition qdatetime.h:283
qint64 toMSecsSinceEpoch() const
static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone)
\inmodule QtCore
\inmodule QtCore
void reserve(qsizetype size)
Definition qlist.h:753
@ AnyTerritory
Definition qlocale.h:568
QAtomicInt ref
Definition qshareddata.h:21
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
QByteArray toUtf8() const &
Definition qstring.h:634
virtual bool hasDaylightTime() const
virtual bool isDaylightTime(qint64 atMSecsSinceEpoch) const
static QByteArray utcQByteArray()
static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId)
virtual Data nextTransition(qint64 afterMSecsSinceEpoch) const
virtual Data data(qint64 forMSecsSinceEpoch) const
virtual bool hasTransitions() const
virtual Data previousTransition(qint64 beforeMSecsSinceEpoch) const
virtual QString displayName(qint64 atMSecsSinceEpoch, QTimeZone::NameType nameType, const QLocale &locale) const
virtual int daylightTimeOffset(qint64 atMSecsSinceEpoch) const
virtual QLocale::Territory territory() const
virtual QString comment() const
virtual void serialize(QDataStream &ds) const
QByteArray id() const
static QList< QByteArray > windowsIdToIanaIds(const QByteArray &windowsId)
virtual QString abbreviation(qint64 atMSecsSinceEpoch) const
static QTimeZone::OffsetData toOffsetData(const Data &data)
DataList transitions(qint64 fromMSecsSinceEpoch, qint64 toMSecsSinceEpoch) const
virtual int standardTimeOffset(qint64 atMSecsSinceEpoch) const
static QByteArray ianaIdToWindowsId(const QByteArray &ianaId)
virtual int offsetFromUtc(qint64 atMSecsSinceEpoch) const
static QTimeZone::OffsetData invalidOffsetData()
static constexpr qint64 invalidSeconds()
static bool isValidId(const QByteArray &ianaId)
\inmodule QtCore
Definition qtimezone.h:26
static constexpr int MaxUtcOffsetSecs
Definition qtimezone.h:90
friend Q_CORE_EXPORT QDataStream & operator<<(QDataStream &ds, const QTimeZone &tz)
~QTimeZone()
Destroys the time zone.
bool isValid() const
Returns true if this time zone is valid.
QTimeZone & operator=(const QTimeZone &other)
Assignment operator, assign other to this.
QTimeZone() noexcept
Create a null/invalid time zone instance.
static QTimeZone fromSecondsAheadOfUtc(int offset)
Definition qtimezone.h:132
constexpr Qt::TimeSpec timeSpec() const noexcept
Definition qtimezone.h:136
static constexpr int MinUtcOffsetSecs
Definition qtimezone.h:87
QList< QByteArray > availableTimeZoneIds() const override
static qint64 offsetFromUtcString(QByteArrayView id)
bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override
QString abbreviation(qint64 atMSecsSinceEpoch) const override
QString displayName(qint64 atMSecsSinceEpoch, QTimeZone::NameType nameType, const QLocale &locale) const override
QString text
list append(new Employee("Blackpool", "Stephen"))
Combined button and popup list for selecting options.
@ UTC
@ OffsetFromUTC
@ LocalTime
@ TimeZone
QDateTimePrivate::QDateTimeShortData ShortData
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:166
GLenum GLuint GLintptr offset
GLuint name
GLbyte GLbyte tz
GLdouble s
[6]
Definition qopenglext.h:235
GLuint64EXT * result
[6]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE QAsn1Element wrap(quint8 type, const QAsn1Element &child)
#define QStringLiteral(str)
static QString invalidId()
bool comparesEqual(const QTimeZone &lhs, const QTimeZone &rhs) noexcept
Q_CORE_EXPORT QDataStream & operator>>(QDataStream &ds, QTimeZone &tz)
int qint32
Definition qtypes.h:49
long long qint64
Definition qtypes.h:60
ptrdiff_t qintptr
Definition qtypes.h:166
QList< int > list
[14]
QTextStream out(stdout)
[7]
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]