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 if (!d->isValid()) {
463 // We may have a legacy alias for a supported IANA ID:
465 if (!name.isEmpty() && name != ianaId)
466 d = newBackendTimeZone(name);
467 }
468 }
469 }
470 // Can also handle UTC with arbitrary (valid) offset, but only do so as
471 // fall-back, since either of the above may handle it more informatively.
472 if (!d->isValid()) {
475 // Should have abs(offset) < 24 * 60 * 60 = 86400.
476 qint32 seconds = qint32(offset);
477 Q_ASSERT(qint64(seconds) == offset);
478 // NB: this canonicalises the name, so it might not match ianaId
479 d = new QUtcTimeZonePrivate(seconds);
480 }
481 }
482}
483
498QTimeZone::QTimeZone(int offsetSeconds)
499 : d((offsetSeconds >= MinUtcOffsetSecs && offsetSeconds <= MaxUtcOffsetSecs)
500 ? new QUtcTimeZonePrivate(offsetSeconds) : nullptr)
501{
502}
503
527QTimeZone::QTimeZone(const QByteArray &zoneId, int offsetSeconds, const QString &name,
528 const QString &abbreviation, QLocale::Territory territory, const QString &comment)
529 : d(QUtcTimeZonePrivate().isTimeZoneIdAvailable(zoneId)
530 || global_tz->backend->isTimeZoneIdAvailable(zoneId)
531 ? nullptr // Don't let client code hijack a real zone name.
532 : new QUtcTimeZonePrivate(zoneId, offsetSeconds, name, abbreviation, territory, comment))
533{
534}
535
545 : d(&dd)
546{
547}
548
572QTimeZone QTimeZone::asBackendZone() const
573{
574 switch (timeSpec()) {
575 case Qt::TimeZone:
576 return *this;
577 case Qt::LocalTime:
578 return systemTimeZone();
579 case Qt::UTC:
580 return utc();
582 return QTimeZone(*new QUtcTimeZonePrivate(int(d.s.offset)));
583 }
584 return QTimeZone();
585}
586#endif // timezone backends
587
687 : d(other.d)
688{
689}
690
704
717{
718 d = other.d;
719 return *this;
720}
721
751bool comparesEqual(const QTimeZone &lhs, const QTimeZone &rhs) noexcept
752{
753 if (lhs.d.isShort())
754 return rhs.d.isShort() && lhs.d.s == rhs.d.s;
755
756 if (!rhs.d.isShort()) {
757 if (lhs.d.d == rhs.d.d)
758 return true;
759#if QT_CONFIG(timezone)
760 return lhs.d.d && rhs.d.d && *lhs.d.d == *rhs.d.d;
761#endif
762 }
763
764 return false;
765}
766
772{
773#if QT_CONFIG(timezone)
774 if (!d.isShort())
775 return d.d && d->isValid();
776#endif
777 return d.isShort();
778}
779
780#if QT_CONFIG(timezone)
812QByteArray QTimeZone::id() const
813{
814 if (d.isShort()) {
815 switch (d.s.spec()) {
816 case Qt::UTC:
818 case Qt::LocalTime:
819 return systemTimeZoneId();
821 return QUtcTimeZonePrivate(d.s.offset).id();
822 case Qt::TimeZone:
823 Q_UNREACHABLE();
824 break;
825 }
826 } else if (d.d) {
827 return d->id();
828 }
829 return QByteArray();
830}
831
847QLocale::Territory QTimeZone::territory() const
848{
849 if (d.isShort()) {
850 if (d.s.spec() == Qt::LocalTime)
851 return systemTimeZone().territory();
852 } else if (isValid()) {
853 return d->territory();
854 }
856}
857
858#if QT_DEPRECATED_SINCE(6, 6)
867QLocale::Country QTimeZone::country() const
868{
869 return territory();
870}
871#endif
872
883QString QTimeZone::comment() const
884{
885 if (d.isShort()) {
886 // TODO: anything ? Or just stick with empty string ?
887 } else if (isValid()) {
888 return d->comment();
889 }
890 return QString();
891}
892
909QString QTimeZone::displayName(const QDateTime &atDateTime, NameType nameType,
910 const QLocale &locale) const
911{
912 if (d.isShort()) {
913 switch (d.s.spec()) {
914 case Qt::LocalTime:
915 return systemTimeZone().displayName(atDateTime, nameType, locale);
916 case Qt::UTC:
918 return QUtcTimeZonePrivate(d.s.offset).displayName(
919 atDateTime.toMSecsSinceEpoch(), nameType, locale);
920 case Qt::TimeZone:
921 Q_UNREACHABLE();
922 break;
923 }
924 } else if (isValid()) {
925 return d->displayName(atDateTime.toMSecsSinceEpoch(), nameType, locale);
926 }
927
928 return QString();
929}
930
948QString QTimeZone::displayName(TimeType timeType, NameType nameType,
949 const QLocale &locale) const
950{
951 if (d.isShort()) {
952 switch (d.s.spec()) {
953 case Qt::LocalTime:
954 return systemTimeZone().displayName(timeType, nameType, locale);
955 case Qt::UTC:
957 return QUtcTimeZonePrivate(d.s.offset).displayName(timeType, nameType, locale);
958 case Qt::TimeZone:
959 Q_UNREACHABLE();
960 break;
961 }
962 } else if (isValid()) {
963 return d->displayName(timeType, nameType, locale);
964 }
965
966 return QString();
967}
968
981QString QTimeZone::abbreviation(const QDateTime &atDateTime) const
982{
983 if (d.isShort()) {
984 switch (d.s.spec()) {
985 case Qt::LocalTime:
986 return systemTimeZone().abbreviation(atDateTime);
987 case Qt::UTC:
989 return QUtcTimeZonePrivate(d.s.offset).abbreviation(atDateTime.toMSecsSinceEpoch());
990 case Qt::TimeZone:
991 Q_UNREACHABLE();
992 break;
993 }
994 } else if (isValid()) {
995 return d->abbreviation(atDateTime.toMSecsSinceEpoch());
996 }
997
998 return QString();
999}
1000
1017int QTimeZone::offsetFromUtc(const QDateTime &atDateTime) const
1018{
1019 if (d.isShort()) {
1020 switch (d.s.spec()) {
1021 case Qt::LocalTime:
1022 return systemTimeZone().offsetFromUtc(atDateTime);
1023 case Qt::UTC:
1024 case Qt::OffsetFromUTC:
1025 return d.s.offset;
1026 case Qt::TimeZone:
1027 Q_UNREACHABLE();
1028 break;
1029 }
1030 } else if (isValid()) {
1031 const int offset = d->offsetFromUtc(atDateTime.toMSecsSinceEpoch());
1033 return offset;
1034 }
1035 return 0;
1036}
1037
1052int QTimeZone::standardTimeOffset(const QDateTime &atDateTime) const
1053{
1054 if (d.isShort()) {
1055 switch (d.s.spec()) {
1056 case Qt::LocalTime:
1057 return systemTimeZone().standardTimeOffset(atDateTime);
1058 case Qt::UTC:
1059 case Qt::OffsetFromUTC:
1060 return d.s.offset;
1061 case Qt::TimeZone:
1062 Q_UNREACHABLE();
1063 break;
1064 }
1065 } else if (isValid()) {
1066 const int offset = d->standardTimeOffset(atDateTime.toMSecsSinceEpoch());
1068 return offset;
1069 }
1070 return 0;
1071}
1072
1087int QTimeZone::daylightTimeOffset(const QDateTime &atDateTime) const
1088{
1089 if (d.isShort()) {
1090 switch (d.s.spec()) {
1091 case Qt::LocalTime:
1092 return systemTimeZone().daylightTimeOffset(atDateTime);
1093 case Qt::UTC:
1094 case Qt::OffsetFromUTC:
1095 return 0;
1096 case Qt::TimeZone:
1097 Q_UNREACHABLE();
1098 break;
1099 }
1100 } else if (hasDaylightTime()) {
1101 const int offset = d->daylightTimeOffset(atDateTime.toMSecsSinceEpoch());
1103 return offset;
1104 }
1105 return 0;
1106}
1107
1116bool QTimeZone::hasDaylightTime() const
1117{
1118 if (d.isShort()) {
1119 switch (d.s.spec()) {
1120 case Qt::LocalTime:
1121 return systemTimeZone().hasDaylightTime();
1122 case Qt::UTC:
1123 case Qt::OffsetFromUTC:
1124 return false;
1125 case Qt::TimeZone:
1126 Q_UNREACHABLE();
1127 break;
1128 }
1129 } else if (isValid()) {
1130 return d->hasDaylightTime();
1131 }
1132 return false;
1133}
1134
1143bool QTimeZone::isDaylightTime(const QDateTime &atDateTime) const
1144{
1145 if (d.isShort()) {
1146 switch (d.s.spec()) {
1147 case Qt::LocalTime:
1148 return systemTimeZone().isDaylightTime(atDateTime);
1149 case Qt::UTC:
1150 case Qt::OffsetFromUTC:
1151 return false;
1152 case Qt::TimeZone:
1153 Q_UNREACHABLE();
1154 break;
1155 }
1156 } else if (hasDaylightTime()) {
1157 return d->isDaylightTime(atDateTime.toMSecsSinceEpoch());
1158 }
1159 return false;
1160}
1161
1175QTimeZone::OffsetData QTimeZone::offsetData(const QDateTime &forDateTime) const
1176{
1177 if (d.isShort()) {
1178 switch (d.s.spec()) {
1179 case Qt::LocalTime:
1180 return systemTimeZone().offsetData(forDateTime);
1181 case Qt::UTC:
1182 case Qt::OffsetFromUTC:
1183 return { abbreviation(forDateTime), forDateTime, int(d.s.offset), int(d.s.offset), 0 };
1184 case Qt::TimeZone:
1185 Q_UNREACHABLE();
1186 break;
1187 }
1188 }
1189 if (isValid())
1190 return QTimeZonePrivate::toOffsetData(d->data(forDateTime.toMSecsSinceEpoch()));
1191
1193}
1194
1206bool QTimeZone::hasTransitions() const
1207{
1208 if (d.isShort()) {
1209 switch (d.s.spec()) {
1210 case Qt::LocalTime:
1211 return systemTimeZone().hasTransitions();
1212 case Qt::UTC:
1213 case Qt::OffsetFromUTC:
1214 return false;
1215 case Qt::TimeZone:
1216 Q_UNREACHABLE();
1217 break;
1218 }
1219 } else if (isValid()) {
1220 return d->hasTransitions();
1221 }
1222 return false;
1223}
1224
1240QTimeZone::OffsetData QTimeZone::nextTransition(const QDateTime &afterDateTime) const
1241{
1242 if (d.isShort()) {
1243 switch (d.s.spec()) {
1244 case Qt::LocalTime:
1245 return systemTimeZone().nextTransition(afterDateTime);
1246 case Qt::UTC:
1247 case Qt::OffsetFromUTC:
1248 break;
1249 case Qt::TimeZone:
1250 Q_UNREACHABLE();
1251 break;
1252 }
1253 } else if (hasTransitions()) {
1254 return QTimeZonePrivate::toOffsetData(d->nextTransition(afterDateTime.toMSecsSinceEpoch()));
1255 }
1256
1258}
1259
1275QTimeZone::OffsetData QTimeZone::previousTransition(const QDateTime &beforeDateTime) const
1276{
1277 if (d.isShort()) {
1278 switch (d.s.spec()) {
1279 case Qt::LocalTime:
1280 return systemTimeZone().previousTransition(beforeDateTime);
1281 case Qt::UTC:
1282 case Qt::OffsetFromUTC:
1283 break;
1284 case Qt::TimeZone:
1285 Q_UNREACHABLE();
1286 break;
1287 }
1288 } else if (hasTransitions()) {
1290 d->previousTransition(beforeDateTime.toMSecsSinceEpoch()));
1291 }
1292
1294}
1295
1308QTimeZone::OffsetDataList QTimeZone::transitions(const QDateTime &fromDateTime,
1309 const QDateTime &toDateTime) const
1310{
1311 OffsetDataList list;
1312 if (d.isShort()) {
1313 switch (d.s.spec()) {
1314 case Qt::LocalTime:
1315 return systemTimeZone().transitions(fromDateTime, toDateTime);
1316 case Qt::UTC:
1317 case Qt::OffsetFromUTC:
1318 break;
1319 case Qt::TimeZone:
1320 Q_UNREACHABLE();
1321 break;
1322 }
1323 } else if (hasTransitions()) {
1324 const QTimeZonePrivate::DataList plist = d->transitions(fromDateTime.toMSecsSinceEpoch(),
1325 toDateTime.toMSecsSinceEpoch());
1326 list.reserve(plist.size());
1327 for (const QTimeZonePrivate::Data &pdata : plist)
1328 list.append(QTimeZonePrivate::toOffsetData(pdata));
1329 }
1330 return list;
1331}
1332
1333// Static methods
1334
1360QByteArray QTimeZone::systemTimeZoneId()
1361{
1362 QByteArray sys = global_tz->backend->systemTimeZoneId();
1363 if (!sys.isEmpty())
1364 return sys;
1365 // The system zone, despite the empty ID, may know its real ID anyway:
1366 return systemTimeZone().id();
1367}
1368
1387QTimeZone QTimeZone::systemTimeZone()
1388{
1389 // Use ID even if empty, as default constructor is invalid but empty-ID
1390 // constructor goes to backend's default constructor, which may succeed.
1391 const auto sys = QTimeZone(global_tz->backend->systemTimeZoneId());
1392 if (!sys.isValid()) {
1393 static bool neverWarned = true;
1394 if (neverWarned) {
1395 // Racey but, at worst, merely repeats the warning.
1396 neverWarned = false;
1397 qWarning("Unable to determine system time zone: "
1398 "please check your system configuration.");
1399 }
1400 }
1401 return sys;
1402}
1403
1415QTimeZone QTimeZone::utc()
1416{
1418}
1419
1431bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &ianaId)
1432{
1433#if defined(Q_OS_UNIX) && !(defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN))
1434 // Keep #if-ery consistent with selection of QTzTimeZonePrivate in
1435 // newBackendTimeZone(). Skip the pre-check, as the TZ backend accepts POSIX
1436 // zone IDs, which need not be valid IANA IDs. See also QTBUG-112006.
1437#else
1438 // isValidId is not strictly required, but faster to weed out invalid
1439 // IDs as availableTimeZoneIds() may be slow
1440 if (!QTimeZonePrivate::isValidId(ianaId))
1441 return false;
1442#endif
1445 || global_tz->backend->isTimeZoneIdAvailable(ianaId);
1446}
1447
1448static QList<QByteArray> set_union(const QList<QByteArray> &l1, const QList<QByteArray> &l2)
1449{
1450 QList<QByteArray> result;
1451 result.reserve(l1.size() + l2.size());
1452 std::set_union(l1.begin(), l1.end(),
1453 l2.begin(), l2.end(),
1454 std::back_inserter(result));
1455 return result;
1456}
1457
1470QList<QByteArray> QTimeZone::availableTimeZoneIds()
1471{
1472 return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(),
1473 global_tz->backend->availableTimeZoneIds());
1474}
1475
1489QList<QByteArray> QTimeZone::availableTimeZoneIds(QLocale::Territory territory)
1490{
1491 return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(territory),
1492 global_tz->backend->availableTimeZoneIds(territory));
1493}
1494
1508QList<QByteArray> QTimeZone::availableTimeZoneIds(int offsetSeconds)
1509{
1510 return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(offsetSeconds),
1511 global_tz->backend->availableTimeZoneIds(offsetSeconds));
1512}
1513
1522QByteArray QTimeZone::ianaIdToWindowsId(const QByteArray &ianaId)
1523{
1525}
1526
1540QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId)
1541{
1543}
1544
1559QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId,
1560 QLocale::Territory territory)
1561{
1562 return QTimeZonePrivate::windowsIdToDefaultIanaId(windowsId, territory);
1563}
1564
1575QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId)
1576{
1577 return QTimeZonePrivate::windowsIdToIanaIds(windowsId);
1578}
1579
1594QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
1595 QLocale::Territory territory)
1596{
1597 return QTimeZonePrivate::windowsIdToIanaIds(windowsId, territory);
1598}
1599
1610#endif // feature timezone
1611
1612template <typename Stream, typename Wrap>
1613void QTimeZone::Data::serialize(Stream &out, const Wrap &wrap) const
1614{
1615 if (isShort()) {
1616 switch (s.spec()) {
1617 case Qt::UTC:
1618 out << wrap("QTimeZone::UTC");
1619 break;
1620 case Qt::LocalTime:
1621 out << wrap("QTimeZone::LocalTime");
1622 break;
1623 case Qt::OffsetFromUTC:
1624 out << wrap("AheadOfUtcBy") << int(s.offset);
1625 break;
1626 case Qt::TimeZone:
1627 Q_UNREACHABLE();
1628 break;
1629 }
1630 return;
1631 }
1632#if QT_CONFIG(timezone)
1633 if constexpr (std::is_same<Stream, QDataStream>::value) {
1634 if (d)
1635 d->serialize(out);
1636 } else {
1637 // QDebug, traditionally gets a QString, hence quotes round the (possibly empty) ID:
1639 }
1640#endif
1641}
1642
1643#ifndef QT_NO_DATASTREAM
1644// Invalid, as an IANA ID: too long, starts with - and has other invalid characters in it
1645static inline QString invalidId() { return QStringLiteral("-No Time Zone Specified!"); }
1646
1648{
1649 const auto toQString = [](const char *text) {
1651 };
1652 if (tz.isValid())
1653 tz.d.serialize(ds, toQString);
1654 else
1655 ds << invalidId();
1656 return ds;
1657}
1658
1660{
1661 QString ianaId;
1662 ds >> ianaId;
1663 // That may be various things other than actual IANA IDs:
1664 if (ianaId == invalidId()) {
1665 tz = QTimeZone();
1666 } else if (ianaId == "OffsetFromUtc"_L1) {
1667 int utcOffset;
1668 QString name;
1669 QString abbreviation;
1670 int territory;
1671 QString comment;
1672 ds >> ianaId >> utcOffset >> name >> abbreviation >> territory >> comment;
1673#if QT_CONFIG(timezone)
1674 // Try creating as a system timezone, which succeeds (producing a valid
1675 // zone) iff ianaId is valid; use this if it is a plain offset from UTC
1676 // zone, with the right offset, ignoring the other data:
1677 tz = QTimeZone(ianaId.toUtf8());
1678 if (!tz.isValid() || tz.hasDaylightTime()
1679 || tz.offsetFromUtc(QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC)) != utcOffset) {
1680 // Construct a custom timezone using the saved values:
1681 tz = QTimeZone(ianaId.toUtf8(), utcOffset, name, abbreviation,
1682 QLocale::Territory(territory), comment);
1683 }
1684#else
1686#endif
1687 } else if (ianaId == "AheadOfUtcBy"_L1) {
1688 int utcOffset;
1689 ds >> utcOffset;
1691 } else if (ianaId == "QTimeZone::UTC"_L1) {
1693 } else if (ianaId == "QTimeZone::LocalTime"_L1) {
1695#if QT_CONFIG(timezone)
1696 } else {
1697 tz = QTimeZone(ianaId.toUtf8());
1698#endif
1699 }
1700 return ds;
1701}
1702#endif // QT_NO_DATASTREAM
1703
1704#ifndef QT_NO_DEBUG_STREAM
1706{
1707 QDebugStateSaver saver(dbg);
1708 const auto asIs = [](const char *text) { return text; };
1709 // TODO Include backend and data version details?
1710 dbg.nospace() << "QTimeZone(";
1711 tz.d.serialize(dbg, asIs);
1712 dbg.nospace() << ')';
1713 return dbg;
1714}
1715#endif
1716
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 aliasToIana(QByteArrayView alias)
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]