Qt 6.x
The Qt SDK
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#ifdef QT_NO_SYSTEMLOCALE
26#if QT_CONFIG(icu)
27 return new QIcuTimeZonePrivate();
28#else
29 return new QUtcTimeZonePrivate();
30#endif
31#else
32#if defined(Q_OS_DARWIN)
33 return new QMacTimeZonePrivate();
34#elif defined(Q_OS_ANDROID)
35 return new QAndroidTimeZonePrivate();
36#elif defined(Q_OS_UNIX)
37 return new QTzTimeZonePrivate();
38#elif QT_CONFIG(icu)
39 return new QIcuTimeZonePrivate();
40#elif defined(Q_OS_WIN)
41 return new QWinTimeZonePrivate();
42#else
43 return new QUtcTimeZonePrivate();
44#endif // System Locales
45#endif // QT_NO_SYSTEMLOCALE
46}
47
48// Create named time zone using appropriate backend
49static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
50{
51 Q_ASSERT(!ianaId.isEmpty());
52#ifdef QT_NO_SYSTEMLOCALE
53#if QT_CONFIG(icu)
54 return new QIcuTimeZonePrivate(ianaId);
55#else
56 return new QUtcTimeZonePrivate(ianaId);
57#endif
58#else
59#if defined(Q_OS_DARWIN)
60 return new QMacTimeZonePrivate(ianaId);
61#elif defined(Q_OS_ANDROID)
62 return new QAndroidTimeZonePrivate(ianaId);
63#elif defined(Q_OS_UNIX)
64 return new QTzTimeZonePrivate(ianaId);
65#elif QT_CONFIG(icu)
66 return new QIcuTimeZonePrivate(ianaId);
67#elif defined(Q_OS_WIN)
68 return new QWinTimeZonePrivate(ianaId);
69#else
70 return new QUtcTimeZonePrivate(ianaId);
71#endif // System Locales
72#endif // QT_NO_SYSTEMLOCALE
73}
74
75class QTimeZoneSingleton
76{
77public:
78 QTimeZoneSingleton() : backend(newBackendTimeZone()) {}
79
80 // The global_tz is the tz to use in static methods such as availableTimeZoneIds() and
81 // isTimeZoneIdAvailable() and to create named IANA time zones. This is usually the host
82 // system, but may be different if the host resources are insufficient or if
83 // QT_NO_SYSTEMLOCALE is set. A simple UTC backend is used if no alternative is available.
85};
86
87Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
88#endif // feature timezone
89
287#if QT_CONFIG(timezone)
376#endif // timezone backends
377
378QTimeZone::Data::Data() noexcept : d(nullptr)
379{
380 // Assumed by the conversion between spec and mode:
381 static_assert(int(Qt::TimeZone) == 3);
382}
383
384QTimeZone::Data::Data(const Data &other) noexcept
385{
386#if QT_CONFIG(timezone)
387 if (!other.isShort() && other.d)
388 other.d->ref.ref();
389#endif
390 d = other.d;
391}
392
393QTimeZone::Data::Data(QTimeZonePrivate *dptr) noexcept
394 : d(dptr)
395{
396#if QT_CONFIG(timezone)
397 if (d)
398 d->ref.ref();
399#endif
400}
401
402QTimeZone::Data::~Data()
403{
404#if QT_CONFIG(timezone)
405 if (!isShort() && d && !d->ref.deref())
406 delete d;
407 d = nullptr;
408#endif
409}
410
411QTimeZone::Data &QTimeZone::Data::operator=(const QTimeZone::Data &other) noexcept
412{
413#if QT_CONFIG(timezone)
414 if (!other.isShort())
415 return *this = other.d;
416 if (!isShort() && d && !d->ref.deref())
417 delete d;
418#endif
419 d = other.d;
420 return *this;
421}
422
428{
429 // Assumed by (at least) Data::swap() and {copy,move} {assign,construct}:
430 static_assert(sizeof(ShortData) <= sizeof(Data::d));
431 // Needed for ShortData::offset to represent all valid offsets:
432 static_assert(qintptr(1) << (sizeof(void *) * 8 - 2) >= MaxUtcOffsetSecs);
433}
434
435#if QT_CONFIG(timezone)
436QTimeZone::Data &QTimeZone::Data::operator=(QTimeZonePrivate *dptr) noexcept
437{
438 if (!isShort()) {
439 if (d == dptr)
440 return *this;
441 if (d && !d->ref.deref())
442 delete d;
443 }
444 if (dptr)
445 dptr->ref.ref();
446 d = dptr;
447 Q_ASSERT(!isShort());
448 return *this;
449}
450
462QTimeZone::QTimeZone(const QByteArray &ianaId)
463{
464 // Try and see if it's a CLDR UTC offset ID - just as quick by creating as
465 // by looking up.
466 d = new QUtcTimeZonePrivate(ianaId);
467 // If not a CLDR UTC offset ID then try creating it with the system backend.
468 // Relies on backend not creating valid TZ with invalid name.
469 if (!d->isValid()) {
470 if (ianaId.isEmpty())
471 d = newBackendTimeZone();
472 else if (global_tz->backend->isTimeZoneIdAvailable(ianaId))
473 d = newBackendTimeZone(ianaId);
474 // else: No such ID, avoid creating a TZ cache entry for it.
475 }
476 // Can also handle UTC with arbitrary (valid) offset, but only do so as
477 // fall-back, since either of the above may handle it more informatively.
478 if (!d->isValid()) {
481 // Should have abs(offset) < 24 * 60 * 60 = 86400.
482 qint32 seconds = qint32(offset);
483 Q_ASSERT(qint64(seconds) == offset);
484 // NB: this canonicalises the name, so it might not match ianaId
485 d = new QUtcTimeZonePrivate(seconds);
486 }
487 }
488}
489
504QTimeZone::QTimeZone(int offsetSeconds)
505 : d((offsetSeconds >= MinUtcOffsetSecs && offsetSeconds <= MaxUtcOffsetSecs)
506 ? new QUtcTimeZonePrivate(offsetSeconds) : nullptr)
507{
508}
509
533QTimeZone::QTimeZone(const QByteArray &ianaId, int offsetSeconds, const QString &name,
534 const QString &abbreviation, QLocale::Territory territory, const QString &comment)
535 : d(isTimeZoneIdAvailable(ianaId) ? nullptr // Don't let client code hijack a real zone name.
536 : new QUtcTimeZonePrivate(ianaId, offsetSeconds, name, abbreviation, territory, comment))
537{
538}
539
549 : d(&dd)
550{
551}
552
580QTimeZone QTimeZone::asBackendZone() const
581{
582 switch (timeSpec()) {
583 case Qt::TimeZone:
584 return *this;
585 case Qt::LocalTime:
586 return systemTimeZone();
587 case Qt::UTC:
588 return utc();
590 return QTimeZone(*new QUtcTimeZonePrivate(int(d.s.offset)));
591 }
592 return QTimeZone();
593}
594#endif // timezone backends
595
695 : d(other.d)
696{
697}
698
710{
711}
712
725{
726 d = other.d;
727 return *this;
728}
729
747{
748 if (d.isShort())
749 return other.d.isShort() && d.s == other.d.s;
750
751 if (!other.d.isShort()) {
752 if (d.d == other.d.d)
753 return true;
754#if QT_CONFIG(timezone)
755 return d.d && other.d.d && *d.d == *other.d.d;
756#endif
757 }
758
759 return false;
760}
761
770bool QTimeZone::operator!=(const QTimeZone &other) const // ### Qt 7: inline
771{
772 return !(*this == other);
773}
774
780{
781#if QT_CONFIG(timezone)
782 if (!d.isShort())
783 return d.d && d->isValid();
784#endif
785 return d.isShort();
786}
787
788#if QT_CONFIG(timezone)
798QByteArray QTimeZone::id() const
799{
800 if (d.isShort()) {
801 switch (d.s.spec()) {
802 case Qt::UTC:
804 case Qt::LocalTime:
805 return systemTimeZoneId();
807 return QUtcTimeZonePrivate(d.s.offset).id();
808 case Qt::TimeZone:
809 Q_UNREACHABLE();
810 break;
811 }
812 } else if (d.d) {
813 return d->id();
814 }
815 return QByteArray();
816}
817
833QLocale::Territory QTimeZone::territory() const
834{
835 if (d.isShort()) {
836 if (d.s.spec() == Qt::LocalTime)
837 return systemTimeZone().territory();
838 } else if (isValid()) {
839 return d->territory();
840 }
842}
843
844#if QT_DEPRECATED_SINCE(6, 6)
853QLocale::Country QTimeZone::country() const
854{
855 return territory();
856}
857#endif
858
869QString QTimeZone::comment() const
870{
871 if (d.isShort()) {
872 // TODO: anything ? Or just stick with empty string ?
873 } else if (isValid()) {
874 return d->comment();
875 }
876 return QString();
877}
878
895QString QTimeZone::displayName(const QDateTime &atDateTime, NameType nameType,
896 const QLocale &locale) const
897{
898 if (d.isShort()) {
899 switch (d.s.spec()) {
900 case Qt::LocalTime:
901 return systemTimeZone().displayName(atDateTime, nameType, locale);
902 case Qt::UTC:
904 return QUtcTimeZonePrivate(d.s.offset).QTimeZonePrivate::displayName(
905 atDateTime.toMSecsSinceEpoch(), nameType, locale);
906 case Qt::TimeZone:
907 Q_UNREACHABLE();
908 break;
909 }
910 } else if (isValid()) {
911 return d->displayName(atDateTime.toMSecsSinceEpoch(), nameType, locale);
912 }
913
914 return QString();
915}
916
934QString QTimeZone::displayName(TimeType timeType, NameType nameType,
935 const QLocale &locale) const
936{
937 if (d.isShort()) {
938 switch (d.s.spec()) {
939 case Qt::LocalTime:
940 return systemTimeZone().displayName(timeType, nameType, locale);
941 case Qt::UTC:
943 return QUtcTimeZonePrivate(d.s.offset).displayName(timeType, nameType, locale);
944 case Qt::TimeZone:
945 Q_UNREACHABLE();
946 break;
947 }
948 } else if (isValid()) {
949 return d->displayName(timeType, nameType, locale);
950 }
951
952 return QString();
953}
954
967QString QTimeZone::abbreviation(const QDateTime &atDateTime) const
968{
969 if (d.isShort()) {
970 switch (d.s.spec()) {
971 case Qt::LocalTime:
972 return systemTimeZone().abbreviation(atDateTime);
973 case Qt::UTC:
975 return QUtcTimeZonePrivate(d.s.offset).abbreviation(atDateTime.toMSecsSinceEpoch());
976 case Qt::TimeZone:
977 Q_UNREACHABLE();
978 break;
979 }
980 } else if (isValid()) {
981 return d->abbreviation(atDateTime.toMSecsSinceEpoch());
982 }
983
984 return QString();
985}
986
1003int QTimeZone::offsetFromUtc(const QDateTime &atDateTime) const
1004{
1005 if (d.isShort()) {
1006 switch (d.s.spec()) {
1007 case Qt::LocalTime:
1008 return systemTimeZone().offsetFromUtc(atDateTime);
1009 case Qt::UTC:
1010 case Qt::OffsetFromUTC:
1011 return d.s.offset;
1012 case Qt::TimeZone:
1013 Q_UNREACHABLE();
1014 break;
1015 }
1016 } else if (isValid()) {
1017 const int offset = d->offsetFromUtc(atDateTime.toMSecsSinceEpoch());
1019 return offset;
1020 }
1021 return 0;
1022}
1023
1038int QTimeZone::standardTimeOffset(const QDateTime &atDateTime) const
1039{
1040 if (d.isShort()) {
1041 switch (d.s.spec()) {
1042 case Qt::LocalTime:
1043 return systemTimeZone().standardTimeOffset(atDateTime);
1044 case Qt::UTC:
1045 case Qt::OffsetFromUTC:
1046 return d.s.offset;
1047 case Qt::TimeZone:
1048 Q_UNREACHABLE();
1049 break;
1050 }
1051 } else if (isValid()) {
1052 const int offset = d->standardTimeOffset(atDateTime.toMSecsSinceEpoch());
1054 return offset;
1055 }
1056 return 0;
1057}
1058
1073int QTimeZone::daylightTimeOffset(const QDateTime &atDateTime) const
1074{
1075 if (d.isShort()) {
1076 switch (d.s.spec()) {
1077 case Qt::LocalTime:
1078 return systemTimeZone().daylightTimeOffset(atDateTime);
1079 case Qt::UTC:
1080 case Qt::OffsetFromUTC:
1081 return 0;
1082 case Qt::TimeZone:
1083 Q_UNREACHABLE();
1084 break;
1085 }
1086 } else if (hasDaylightTime()) {
1087 const int offset = d->daylightTimeOffset(atDateTime.toMSecsSinceEpoch());
1089 return offset;
1090 }
1091 return 0;
1092}
1093
1102bool QTimeZone::hasDaylightTime() const
1103{
1104 if (d.isShort()) {
1105 switch (d.s.spec()) {
1106 case Qt::LocalTime:
1107 return systemTimeZone().hasDaylightTime();
1108 case Qt::UTC:
1109 case Qt::OffsetFromUTC:
1110 return false;
1111 case Qt::TimeZone:
1112 Q_UNREACHABLE();
1113 break;
1114 }
1115 } else if (isValid()) {
1116 return d->hasDaylightTime();
1117 }
1118 return false;
1119}
1120
1129bool QTimeZone::isDaylightTime(const QDateTime &atDateTime) const
1130{
1131 if (d.isShort()) {
1132 switch (d.s.spec()) {
1133 case Qt::LocalTime:
1134 return systemTimeZone().isDaylightTime(atDateTime);
1135 case Qt::UTC:
1136 case Qt::OffsetFromUTC:
1137 return false;
1138 case Qt::TimeZone:
1139 Q_UNREACHABLE();
1140 break;
1141 }
1142 } else if (hasDaylightTime()) {
1143 return d->isDaylightTime(atDateTime.toMSecsSinceEpoch());
1144 }
1145 return false;
1146}
1147
1161QTimeZone::OffsetData QTimeZone::offsetData(const QDateTime &forDateTime) const
1162{
1163 if (d.isShort()) {
1164 switch (d.s.spec()) {
1165 case Qt::LocalTime:
1166 return systemTimeZone().offsetData(forDateTime);
1167 case Qt::UTC:
1168 case Qt::OffsetFromUTC:
1169 return { abbreviation(forDateTime), forDateTime, int(d.s.offset), int(d.s.offset), 0 };
1170 case Qt::TimeZone:
1171 Q_UNREACHABLE();
1172 break;
1173 }
1174 }
1175 if (isValid())
1176 return QTimeZonePrivate::toOffsetData(d->data(forDateTime.toMSecsSinceEpoch()));
1177
1179}
1180
1192bool QTimeZone::hasTransitions() const
1193{
1194 if (d.isShort()) {
1195 switch (d.s.spec()) {
1196 case Qt::LocalTime:
1197 return systemTimeZone().hasTransitions();
1198 case Qt::UTC:
1199 case Qt::OffsetFromUTC:
1200 return false;
1201 case Qt::TimeZone:
1202 Q_UNREACHABLE();
1203 break;
1204 }
1205 } else if (isValid()) {
1206 return d->hasTransitions();
1207 }
1208 return false;
1209}
1210
1226QTimeZone::OffsetData QTimeZone::nextTransition(const QDateTime &afterDateTime) const
1227{
1228 if (d.isShort()) {
1229 switch (d.s.spec()) {
1230 case Qt::LocalTime:
1231 return systemTimeZone().nextTransition(afterDateTime);
1232 case Qt::UTC:
1233 case Qt::OffsetFromUTC:
1234 break;
1235 case Qt::TimeZone:
1236 Q_UNREACHABLE();
1237 break;
1238 }
1239 } else if (hasTransitions()) {
1240 return QTimeZonePrivate::toOffsetData(d->nextTransition(afterDateTime.toMSecsSinceEpoch()));
1241 }
1242
1244}
1245
1261QTimeZone::OffsetData QTimeZone::previousTransition(const QDateTime &beforeDateTime) const
1262{
1263 if (d.isShort()) {
1264 switch (d.s.spec()) {
1265 case Qt::LocalTime:
1266 return systemTimeZone().previousTransition(beforeDateTime);
1267 case Qt::UTC:
1268 case Qt::OffsetFromUTC:
1269 break;
1270 case Qt::TimeZone:
1271 Q_UNREACHABLE();
1272 break;
1273 }
1274 } else if (hasTransitions()) {
1276 d->previousTransition(beforeDateTime.toMSecsSinceEpoch()));
1277 }
1278
1280}
1281
1292QTimeZone::OffsetDataList QTimeZone::transitions(const QDateTime &fromDateTime,
1293 const QDateTime &toDateTime) const
1294{
1295 OffsetDataList list;
1296 if (d.isShort()) {
1297 switch (d.s.spec()) {
1298 case Qt::LocalTime:
1299 return systemTimeZone().transitions(fromDateTime, toDateTime);
1300 case Qt::UTC:
1301 case Qt::OffsetFromUTC:
1302 break;
1303 case Qt::TimeZone:
1304 Q_UNREACHABLE();
1305 break;
1306 }
1307 } else if (hasTransitions()) {
1308 const QTimeZonePrivate::DataList plist = d->transitions(fromDateTime.toMSecsSinceEpoch(),
1309 toDateTime.toMSecsSinceEpoch());
1310 list.reserve(plist.size());
1311 for (const QTimeZonePrivate::Data &pdata : plist)
1312 list.append(QTimeZonePrivate::toOffsetData(pdata));
1313 }
1314 return list;
1315}
1316
1317// Static methods
1318
1332QByteArray QTimeZone::systemTimeZoneId()
1333{
1334 QByteArray sys = global_tz->backend->systemTimeZoneId();
1335 if (!sys.isEmpty())
1336 return sys;
1337 // The system zone, despite the empty ID, may know its real ID anyway:
1338 auto zone = systemTimeZone();
1339 if (zone.isValid() && !zone.id().isEmpty())
1340 return zone.id();
1341 // TODO: "-00:00", meaning "unspecified local zone" in some RFC, may be more apt.
1342 // If all else fails, guess UTC.
1344}
1345
1358QTimeZone QTimeZone::systemTimeZone()
1359{
1360 return QTimeZone(global_tz->backend->systemTimeZoneId());
1361}
1362
1374QTimeZone QTimeZone::utc()
1375{
1377}
1378
1387bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &ianaId)
1388{
1389#if defined(Q_OS_UNIX) && !(defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN))
1390 // Keep #if-ery consistent with selection of QTzTimeZonePrivate in
1391 // newBackendTimeZone(). Skip the pre-check, as the TZ backend accepts POSIX
1392 // zone IDs, which need not be valid IANA IDs.
1393#else
1394 // isValidId is not strictly required, but faster to weed out invalid
1395 // IDs as availableTimeZoneIds() may be slow
1396 if (!QTimeZonePrivate::isValidId(ianaId))
1397 return false;
1398#endif
1400 || global_tz->backend->isTimeZoneIdAvailable(ianaId);
1401}
1402
1403static QList<QByteArray> set_union(const QList<QByteArray> &l1, const QList<QByteArray> &l2)
1404{
1406 result.reserve(l1.size() + l2.size());
1407 std::set_union(l1.begin(), l1.end(),
1408 l2.begin(), l2.end(),
1409 std::back_inserter(result));
1410 return result;
1411}
1412
1421QList<QByteArray> QTimeZone::availableTimeZoneIds()
1422{
1423 return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(),
1424 global_tz->backend->availableTimeZoneIds());
1425}
1426
1440QList<QByteArray> QTimeZone::availableTimeZoneIds(QLocale::Territory territory)
1441{
1442 return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(territory),
1443 global_tz->backend->availableTimeZoneIds(territory));
1444}
1445
1455QList<QByteArray> QTimeZone::availableTimeZoneIds(int offsetSeconds)
1456{
1457 return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(offsetSeconds),
1458 global_tz->backend->availableTimeZoneIds(offsetSeconds));
1459}
1460
1469QByteArray QTimeZone::ianaIdToWindowsId(const QByteArray &ianaId)
1470{
1472}
1473
1487QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId)
1488{
1490}
1491
1506QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId,
1507 QLocale::Territory territory)
1508{
1509 return QTimeZonePrivate::windowsIdToDefaultIanaId(windowsId, territory);
1510}
1511
1522QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId)
1523{
1524 return QTimeZonePrivate::windowsIdToIanaIds(windowsId);
1525}
1526
1541QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
1542 QLocale::Territory territory)
1543{
1544 return QTimeZonePrivate::windowsIdToIanaIds(windowsId, territory);
1545}
1546
1557#endif // feature timezone
1558
1559template <typename Stream, typename Wrap>
1560void QTimeZone::Data::serialize(Stream &out, const Wrap &wrap) const
1561{
1562 if (isShort()) {
1563 switch (s.spec()) {
1564 case Qt::UTC:
1565 out << wrap("QTimeZone::UTC");
1566 break;
1567 case Qt::LocalTime:
1568 out << wrap("QTimeZone::LocalTime");
1569 break;
1570 case Qt::OffsetFromUTC:
1571 out << wrap("AheadOfUtcBy") << int(s.offset);
1572 break;
1573 case Qt::TimeZone:
1574 Q_UNREACHABLE();
1575 break;
1576 }
1577 return;
1578 }
1579#if QT_CONFIG(timezone)
1580 if constexpr (std::is_same<Stream, QDataStream>::value) {
1581 if (d)
1582 d->serialize(out);
1583 } else {
1584 // QDebug, traditionally gets a QString, hence quotes round the (possibly empty) ID:
1586 }
1587#endif
1588}
1589
1590#ifndef QT_NO_DATASTREAM
1591// Invalid, as an IANA ID: too long, starts with - and has other invalid characters in it
1592static inline QString invalidId() { return QStringLiteral("-No Time Zone Specified!"); }
1593
1595{
1596 const auto toQString = [](const char *text) {
1598 };
1599 if (tz.isValid())
1600 tz.d.serialize(ds, toQString);
1601 else
1602 ds << invalidId();
1603 return ds;
1604}
1605
1607{
1608 QString ianaId;
1609 ds >> ianaId;
1610 // That may be various things other than actual IANA IDs:
1611 if (ianaId == invalidId()) {
1612 tz = QTimeZone();
1613 } else if (ianaId == "OffsetFromUtc"_L1) {
1614 int utcOffset;
1615 QString name;
1616 QString abbreviation;
1617 int territory;
1618 QString comment;
1619 ds >> ianaId >> utcOffset >> name >> abbreviation >> territory >> comment;
1620#if QT_CONFIG(timezone)
1621 // Try creating as a system timezone, which succeeds (producing a valid
1622 // zone) iff ianaId is valid; use this if it is a plain offset from UTC
1623 // zone, with the right offset, ignoring the other data:
1624 tz = QTimeZone(ianaId.toUtf8());
1625 if (!tz.isValid() || tz.hasDaylightTime()
1626 || tz.offsetFromUtc(QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC)) != utcOffset) {
1627 // Construct a custom timezone using the saved values:
1628 tz = QTimeZone(ianaId.toUtf8(), utcOffset, name, abbreviation,
1629 QLocale::Territory(territory), comment);
1630 }
1631#else
1633#endif
1634 } else if (ianaId == "AheadOfUtcBy"_L1) {
1635 int utcOffset;
1636 ds >> utcOffset;
1638 } else if (ianaId == "QTimeZone::UTC"_L1) {
1640 } else if (ianaId == "QTimeZone::LocalTime"_L1) {
1642#if QT_CONFIG(timezone)
1643 } else {
1644 tz = QTimeZone(ianaId.toUtf8());
1645#endif
1646 }
1647 return ds;
1648}
1649#endif // QT_NO_DATASTREAM
1650
1651#ifndef QT_NO_DEBUG_STREAM
1653{
1654 QDebugStateSaver saver(dbg);
1655 const auto asIs = [](const char *text) { return text; };
1656 // TODO Include backend and data version details?
1657 dbg.nospace() << "QTimeZone(";
1658 tz.d.serialize(dbg, asIs);
1659 dbg.nospace() << ')';
1660 return dbg;
1661}
1662#endif
1663
\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:106
\inmodule QtCore\reentrant
Definition qdatastream.h:30
\inmodule QtCore\reentrant
Definition qdatetime.h:257
qint64 toMSecsSinceEpoch() const
static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone)
\inmodule QtCore
\inmodule QtCore
qsizetype size() const noexcept
Definition qlist.h:386
iterator end()
Definition qlist.h:609
iterator begin()
Definition qlist.h:608
void reserve(qsizetype size)
Definition qlist.h:746
@ AnyTerritory
Definition qlocale.h:558
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5857
QByteArray toUtf8() const &
Definition qstring.h:563
static QByteArray utcQByteArray()
static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId)
QByteArray id() const
static QList< QByteArray > windowsIdToIanaIds(const QByteArray &windowsId)
static QTimeZone::OffsetData toOffsetData(const Data &data)
static QByteArray ianaIdToWindowsId(const QByteArray &ianaId)
static QTimeZone::OffsetData invalidOffsetData()
static constexpr qint64 invalidSeconds()
static bool isValidId(const QByteArray &ianaId)
\inmodule QtCore
Definition qtimezone.h:25
static constexpr int MaxUtcOffsetSecs
Definition qtimezone.h:89
~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:129
bool operator!=(const QTimeZone &other) const
Returns true if this time zone is not equal to the other time zone.
constexpr Qt::TimeSpec timeSpec() const noexcept
Definition qtimezone.h:133
bool operator==(const QTimeZone &other) const
Returns true if this time representation is equal to the other.
QList< QByteArray > availableTimeZoneIds() const override
static qint64 offsetFromUtcString(const QByteArray &id)
bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override
QString abbreviation(qint64 atMSecsSinceEpoch) const override
QString displayName(QTimeZone::TimeType timeType, 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
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
GLenum GLuint GLintptr offset
GLuint name
GLbyte GLbyte tz
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QT_BEGIN_NAMESPACE QAsn1Element wrap(quint8 type, const QAsn1Element &child)
#define QStringLiteral(str)
QDataStream & operator>>(QDataStream &ds, QTimeZone &tz)
QDataStream & operator<<(QDataStream &ds, const QTimeZone &tz)
static QString invalidId()
int qint32
Definition qtypes.h:44
long long qint64
Definition qtypes.h:55
ptrdiff_t qintptr
Definition qtypes.h:71
QList< int > list
[14]
QTextStream out(stdout)
[7]
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]