8#include "private/qlocale_tools_p.h"
9#include "private/qlocking_p.h"
11#include <QtCore/QDataStream>
12#include <QtCore/QDateTime>
13#include <QtCore/QDirListing>
14#include <QtCore/QFile>
15#include <QtCore/QCache>
17#include <QtCore/QMutex>
20#include <qplatformdefs.h>
58 if (!tzdir.isEmpty()) {
64 constexpr auto zoneShare =
"/usr/share/zoneinfo/"_L1;
65 if (tzdir != zoneShare && tzdir != zoneShare.chopped(1)) {
71 constexpr auto zoneLib =
"/usr/lib/zoneinfo/"_L1;
72 if (tzdir != zoneLib && tzdir != zoneLib.chopped(1)) {
90 while (!tzif.atEnd()) {
110 zonesHash.
insert(
id, zone);
121 if (!(
info.isFile() ||
info.isSymLink()))
125 if (
info.isDir() ?
name ==
"posix"_L1 ||
name ==
"right"_L1
126 :
name.startsWith(
"posix/"_L1) ||
name.startsWith(
"right/"_L1)) {
133 if (!zonesHash.contains(
id) &&
isTzFile(zoneDir.absoluteFilePath(
name)))
148#define TZ_MAGIC "TZif"
149#define TZ_MAX_TIMES 1200
150#define TZ_MAX_TYPES 256
151#define TZ_MAX_CHARS 50
152#define TZ_MAX_LEAPS 50
202 if (ds.
status() != QDataStream::Ok
209 if (ds.
status() != QDataStream::Ok)
217 if (ds.
status() != QDataStream::Ok
233 QList<QTzTransition> transitions(tzh_timecnt);
237 for (
int i = 0;
i < tzh_timecnt && ds.
status() == QDataStream::Ok; ++
i) {
238 ds >> transitions[
i].tz_time;
239 if (ds.
status() != QDataStream::Ok)
240 transitions.resize(
i);
245 for (
int i = 0;
i < tzh_timecnt && ds.
status() == QDataStream::Ok; ++
i) {
247 transitions[
i].tz_time =
val;
248 if (ds.
status() != QDataStream::Ok)
249 transitions.resize(
i);
254 for (
int i = 0;
i < tzh_timecnt && ds.
status() == QDataStream::Ok; ++
i) {
257 if (ds.
status() == QDataStream::Ok)
258 transitions[
i].tz_typeind = typeind;
266 QList<QTzType>
types(tzh_typecnt);
269 for (
int i = 0;
i < tzh_typecnt && ds.
status() == QDataStream::Ok; ++
i) {
272 ds >>
type.tz_gmtoff;
274 if (ds.
status() == QDataStream::Ok)
277 if (ds.
status() == QDataStream::Ok)
278 ds >>
type.tz_abbrind;
279 if (ds.
status() != QDataStream::Ok)
293 QMap<int, QByteArray>
map;
297 for (
int i = 0;
i < tzh_charcnt && ds.
status() == QDataStream::Ok; ++
i) {
299 if (ds.
status() == QDataStream::Ok)
323 for (
int i = 0;
i < tzh_leapcnt && ds.
status() == QDataStream::Ok; ++
i) {
327 if (ds.
status() == QDataStream::Ok)
332 for (
int i = 0;
i < tzh_leapcnt && ds.
status() == QDataStream::Ok; ++
i) {
336 if (ds.
status() == QDataStream::Ok)
359 for (
int i = 0;
i < tzh_ttisstdcnt && ds.
status() == QDataStream::Ok; ++
i)
363 for (
int i = 0;
i < tzh_ttisgmtcnt && ds.
status() == QDataStream::Ok; ++
i)
376 if (
ch !=
'\n' || ds.
status() != QDataStream::Ok)
379 while (
ch !=
'\n' && ds.
status() == QDataStream::Ok) {
391 else if (dayOfWeek & ~7 || month < 1 || month > 12 || week < 1 || week > 5)
396 if (startDow <= dayOfWeek)
411 if (dateRule.at(0) ==
'M') {
413 QList<QByteArray> dateParts = dateRule.split(
'.');
414 if (dateParts.size() > 2) {
415 Q_ASSERT(!dateParts.at(0).isEmpty());
417 int week =
ok ? dateParts.at(1).toInt(&
ok) : 0;
418 int dow =
ok ? dateParts.at(2).toInt(&
ok) : 0;
422 }
else if (dateRule.at(0) ==
'J') {
426 if (
ok && doy > 0 && doy < 366) {
436 int doy = dateRule.toInt(&
ok);
437 if (
ok && doy >= 0 && doy < 366)
447 int hour, min = 0, sec = 0;
449 const int maxHour = 137;
452 if (!
r.ok() || hour < -maxHour || hour > maxHour ||
r.used > 2)
460 if (!
r.ok() || min < 0 || min > 59 ||
r.used > 2)
469 if (!
r.ok() || sec < 0 || sec > 59 ||
r.used > 2)
479 return (hour * 60 + min) * 60 + sec;
484 return parsePosixTime(timeRule.constBegin(), timeRule.constEnd());
494 }
else if (*
begin ==
'-') {
500 if (
value == INT_MIN)
508 return ch >=
'a' &&
ch <=
'z';
516 InvalidOffset = INT_MIN,
520 int offset = InvalidOffset;
521 bool hasValidOffset() const noexcept {
return offset != InvalidOffset; }
533 static PosixZone parse(
const char *&
pos,
const char *
end);
541PosixZone PosixZone::parse(
const char *&
pos,
const char *
end)
543 static const char offsetChars[] =
"0123456789:";
545 const char *nameBegin =
pos;
552 while (nameEnd <
end && *nameEnd !=
'>') {
563 if (nameEnd - nameBegin < 3)
567 const char *zoneBegin =
pos;
568 const char *zoneEnd =
pos;
569 if (zoneEnd <
end && (zoneEnd[0] ==
'+' || zoneEnd[0] ==
'-'))
571 while (zoneEnd <
end) {
572 if (strchr(offsetChars,
char(*zoneEnd)) ==
nullptr)
597 const auto parts = posixRule.split(
',');
598 const struct {
bool isValid, hasDst; } fail{
false,
false}, good{
true, parts.size() > 1};
600 if (zoneinfo.isEmpty())
603 const char *
begin = zoneinfo.begin();
606 const auto posix = PosixZone::parse(
begin, zoneinfo.end());
607 if (posix.name.isEmpty())
609 if (requireOffset && !posix.hasValidOffset())
614 if (
begin >= zoneinfo.end())
617 if (PosixZone::parse(
begin, zoneinfo.end()).name.isEmpty())
620 if (
begin < zoneinfo.end())
624 if (parts.size() != 3 || parts.at(1).isEmpty() || parts.at(2).isEmpty())
626 for (
int i = 1;
i < 3; ++
i) {
627 const auto tran = parts.at(
i).split(
'/');
630 if (tran.size() > 1) {
631 const auto time = tran.at(1);
641 int startYear,
int endYear,
644 QList<QTimeZonePrivate::Data>
result;
651 QList<QByteArray> parts = posixRule.split(
',');
653 PosixZone stdZone, dstZone;
656 const char *
begin = zoneinfo.constBegin();
658 stdZone = PosixZone::parse(
begin, zoneinfo.constEnd());
659 if (!stdZone.hasValidOffset()) {
661 }
else if (
begin < zoneinfo.constEnd()) {
662 dstZone = PosixZone::parse(
begin, zoneinfo.constEnd());
663 if (!dstZone.hasValidOffset()) {
665 dstZone.offset = stdZone.offset + (60 * 60);
671 if (parts.size() == 1 || !dstZone.hasValidOffset()) {
674 lastTranMSecs, stdZone.offset, stdZone.offset);
677 if (parts.size() < 3 || parts.at(1).isEmpty() || parts.at(2).isEmpty())
681 const int twoOClock = 7200;
682 const auto dstParts = parts.at(1).split(
'/');
687 const auto stdParts = parts.at(2).split(
'/');
691 if (dstDateRule.isEmpty() || stdDateRule.isEmpty() || dstTime == INT_MIN || stdTime == INT_MIN)
697 startYear =
qBound(minYear, startYear, maxYear);
698 endYear =
qBound(minYear, endYear, maxYear);
701 for (
int year = startYear; year <= endYear; ++year) {
710 auto saving = dstZone.dataAtOffset(
dst.toMSecsSinceEpoch() - stdZone.offset * 1000,
715 auto standard = stdZone.dataAt(
std.toMSecsSinceEpoch() - dstZone.offset * 1000);
717 if (year == startYear) {
720 if (saving.atMSecsSinceEpoch < standard.atMSecsSinceEpoch) {
724 saving.atMSecsSinceEpoch = lastTranMSecs;
725 result.emplaceBack(std::move(saving));
732 standard.atMSecsSinceEpoch = lastTranMSecs;
733 result.emplaceBack(std::move(standard));
739 const bool useStd =
std.isValid() &&
std.date().year() == year && !stdZone.name.isEmpty();
740 const bool useDst =
dst.isValid() &&
dst.date().year() == year && !dstZone.name.isEmpty();
741 if (useStd && useDst) {
743 result.emplaceBack(std::move(saving));
744 result.emplaceBack(std::move(standard));
746 result.emplaceBack(std::move(standard));
747 result.emplaceBack(std::move(saving));
750 result.emplaceBack(std::move(standard));
752 result.emplaceBack(std::move(saving));
759QTzTimeZonePrivate::QTzTimeZonePrivate()
760 : QTzTimeZonePrivate(staticSystemTimeZoneId())
764QTzTimeZonePrivate::~QTzTimeZonePrivate()
768QTzTimeZonePrivate *QTzTimeZonePrivate::clone()
const
770 return new QTzTimeZonePrivate(*
this);
776 QTzTimeZoneCacheEntry fetchEntry(
const QByteArray &ianaId);
779 static QTzTimeZoneCacheEntry findEntry(
const QByteArray &ianaId);
780 QCache<QByteArray, QTzTimeZoneCacheEntry> m_cache;
784QTzTimeZoneCacheEntry QTzTimeZoneCache::findEntry(
const QByteArray &ianaId)
786 QTzTimeZoneCacheEntry
ret;
797 ret.m_hasDst = check.hasDst;
798 ret.m_posixRule = ianaId;
809 if (!
ok || ds.status() != QDataStream::Ok)
812 if (ds.status() != QDataStream::Ok)
815 if (ds.status() != QDataStream::Ok)
818 if (ds.status() != QDataStream::Ok)
821 if (ds.status() != QDataStream::Ok)
824 if (ds.status() != QDataStream::Ok)
831 if (!
ok || ds.status() != QDataStream::Ok)
834 if (ds.status() != QDataStream::Ok)
837 if (ds.status() != QDataStream::Ok)
840 if (ds.status() != QDataStream::Ok)
843 if (ds.status() != QDataStream::Ok)
846 if (ds.status() != QDataStream::Ok)
849 if (ds.status() != QDataStream::Ok)
854 if (!posixRule.isEmpty()) {
858 ret.m_posixRule = posixRule;
859 ret.m_hasDst = check.hasDst;
863 const int size = abbrevMap.size();
864 ret.m_abbreviations.clear();
865 ret.m_abbreviations.reserve(
size);
866 QList<int> abbrindList;
867 abbrindList.reserve(
size);
869 ret.m_abbreviations.append(
it.value());
870 abbrindList.append(
it.key());
883 int utcOffset =
ret.m_preZoneRule.stdOffset;
885 if (!
typeList.at(tran.tz_typeind).tz_isdst) {
886 utcOffset =
typeList.at(tran.tz_typeind).tz_gmtoff;
892 const int tranCount = tranList.size();
893 ret.m_tranTimes.reserve(tranCount);
895 int lastDstOff = 3600;
896 for (
int i = 0;
i < tranCount;
i++) {
898 QTzTransitionTime tran;
899 QTzTransitionRule
rule;
903 if (!tz_type.tz_isdst) {
904 utcOffset = tz_type.tz_gmtoff;
905 }
else if (
Q_UNLIKELY(tz_type.tz_gmtoff != utcOffset + lastDstOff)) {
913 const int inferStd = tz_type.tz_gmtoff - lastDstOff;
914 for (
int j =
i + 1;
j < tranCount;
j++) {
916 if (!new_type.tz_isdst) {
917 const int newUtc = new_type.tz_gmtoff;
918 if (newUtc == utcOffset) {
921 }
else if (newUtc == inferStd) {
924 }
else if (tz_type.tz_gmtoff - 3600 == utcOffset) {
926 }
else if (tz_type.tz_gmtoff - 3600 == newUtc) {
930 }
else if (newUtc < tz_type.tz_gmtoff
931 ? (utcOffset >= tz_type.tz_gmtoff
932 ||
qAbs(newUtc - inferStd) <
qAbs(utcOffset - inferStd))
933 : (utcOffset >= tz_type.tz_gmtoff
934 &&
qAbs(newUtc - inferStd) <
qAbs(utcOffset - inferStd))) {
940 lastDstOff = tz_type.tz_gmtoff - utcOffset;
942 rule.stdOffset = utcOffset;
943 rule.dstOffset = tz_type.tz_gmtoff - utcOffset;
944 rule.abbreviationIndex = tz_type.tz_abbrind;
947 int ruleIndex =
ret.m_tranRules.indexOf(
rule);
948 if (ruleIndex == -1) {
949 if (
rule.dstOffset != 0)
951 tran.ruleIndex =
ret.m_tranRules.size();
954 tran.ruleIndex = ruleIndex;
957 tran.atMSecsSinceEpoch = tz_tran.tz_time * 1000;
958 ret.m_tranTimes.append(tran);
969 QTzTimeZoneCacheEntry *
obj = m_cache.object(ianaId);
977 QTzTimeZoneCacheEntry
ret = findEntry(ianaId);
978 auto ptr = std::make_unique<QTzTimeZoneCacheEntry>(
ret);
981 m_cache.insert(ianaId,
ptr.release());
988QTzTimeZonePrivate::QTzTimeZonePrivate(
const QByteArray &ianaId)
990 if (!isTimeZoneIdAvailable(ianaId))
994 if (
entry.m_tranTimes.isEmpty() &&
entry.m_posixRule.isEmpty())
997 cached_data = std::move(
entry);
1000 if (m_id.isEmpty()) {
1010 return tzZones->value(m_id).territory;
1013QString QTzTimeZonePrivate::comment()
const
1018QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
1019 QTimeZone::NameType nameType,
1023 if (nameType != QTimeZone::LongName && isDataLocale(locale)) {
1025 if (tran.atMSecsSinceEpoch != invalidMSecs()) {
1026 if (nameType == QTimeZone::ShortName)
1027 return tran.abbreviation;
1030 return isoOffsetFormat(tran.offsetFromUtc);
1037QString QTzTimeZonePrivate::abbreviation(
qint64 atMSecsSinceEpoch)
const
1039 return data(atMSecsSinceEpoch).abbreviation;
1042int QTzTimeZonePrivate::offsetFromUtc(
qint64 atMSecsSinceEpoch)
const
1045 return tran.offsetFromUtc;
1048int QTzTimeZonePrivate::standardTimeOffset(
qint64 atMSecsSinceEpoch)
const
1050 return data(atMSecsSinceEpoch).standardTimeOffset;
1053int QTzTimeZonePrivate::daylightTimeOffset(
qint64 atMSecsSinceEpoch)
const
1055 return data(atMSecsSinceEpoch).daylightTimeOffset;
1058bool QTzTimeZonePrivate::hasDaylightTime()
const
1060 return cached_data.m_hasDst;
1063bool QTzTimeZonePrivate::isDaylightTime(
qint64 atMSecsSinceEpoch)
const
1065 return (daylightTimeOffset(atMSecsSinceEpoch) != 0);
1070 return dataFromRule(cached_data.m_tranRules.at(tran.ruleIndex), tran.atMSecsSinceEpoch);
1074 qint64 msecsSinceEpoch)
const
1077 msecsSinceEpoch,
rule.stdOffset +
rule.dstOffset,
rule.stdOffset);
1080QList<QTimeZonePrivate::Data> QTzTimeZonePrivate::getPosixTransitions(
qint64 msNear)
const
1084 qint64 atTime = tranCache().isEmpty() ? msNear : tranCache().last().atMSecsSinceEpoch;
1092 if (!cached_data.m_posixRule.isEmpty()
1093 && (tranCache().isEmpty() || tranCache().last().atMSecsSinceEpoch < forMSecsSinceEpoch)) {
1094 QList<QTimeZonePrivate::Data> posixTrans = getPosixTransitions(forMSecsSinceEpoch);
1095 auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
1097 return at.atMSecsSinceEpoch <= forMSecsSinceEpoch;
1100 if (
it > posixTrans.
cbegin() || (tranCache().isEmpty() &&
it < posixTrans.
cend())) {
1106 if (tranCache().isEmpty())
1110 auto last = std::partition_point(tranCache().cbegin(), tranCache().
cend(),
1111 [forMSecsSinceEpoch] (
const QTzTransitionTime &
at) {
1112 return at.atMSecsSinceEpoch <= forMSecsSinceEpoch;
1114 if (last == tranCache().cbegin())
1115 return dataFromRule(cached_data.m_preZoneRule, forMSecsSinceEpoch);
1118 return dataFromRule(cached_data.m_tranRules.at(last->ruleIndex), forMSecsSinceEpoch);
1131 && ((timeType == QTimeZone::DaylightTime) != (tran.daylightTimeOffset == 0));
1137 if (validMatch(tran))
1141 tran = nextTransition(currentMSecs);
1142 if (validMatch(tran))
1148 tran = previousTransition(currentMSecs + 1);
1149 if (tran.atMSecsSinceEpoch != invalidMSecs())
1150 tran = previousTransition(tran.atMSecsSinceEpoch);
1151 if (validMatch(tran))
1157 const auto untilNow = [currentMSecs](
const QTzTransitionTime &
at) {
1158 return at.atMSecsSinceEpoch <= currentMSecs;
1160 auto it = std::partition_point(tranCache().cbegin(), tranCache().
cend(), untilNow);
1163 while (
it != tranCache().cbegin()) {
1165 tran = dataForTzTransition(*
it);
1166 if ((timeType == QTimeZone::DaylightTime) != (tran.daylightTimeOffset == 0))
1173bool QTzTimeZonePrivate::isDataLocale(
const QLocale &locale)
const
1179bool QTzTimeZonePrivate::hasTransitions()
const
1188 if (!cached_data.m_posixRule.isEmpty()
1189 && (tranCache().isEmpty() || tranCache().last().atMSecsSinceEpoch < afterMSecsSinceEpoch)) {
1190 QList<QTimeZonePrivate::Data> posixTrans = getPosixTransitions(afterMSecsSinceEpoch);
1191 auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
1193 return at.atMSecsSinceEpoch <= afterMSecsSinceEpoch;
1200 auto last = std::partition_point(tranCache().cbegin(), tranCache().
cend(),
1201 [afterMSecsSinceEpoch] (
const QTzTransitionTime &
at) {
1202 return at.atMSecsSinceEpoch <= afterMSecsSinceEpoch;
1204 return last != tranCache().
cend() ? dataForTzTransition(*last) :
Data{};
1211 if (!cached_data.m_posixRule.isEmpty()
1212 && (tranCache().isEmpty() || tranCache().last().atMSecsSinceEpoch < beforeMSecsSinceEpoch)) {
1213 QList<QTimeZonePrivate::Data> posixTrans = getPosixTransitions(beforeMSecsSinceEpoch);
1214 auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
1216 return at.atMSecsSinceEpoch < beforeMSecsSinceEpoch;
1221 return tranCache().
isEmpty() ?
Data{} : dataForTzTransition(tranCache().last());
1225 auto last = std::partition_point(tranCache().cbegin(), tranCache().
cend(),
1226 [beforeMSecsSinceEpoch] (
const QTzTransitionTime &
at) {
1227 return at.atMSecsSinceEpoch < beforeMSecsSinceEpoch;
1229 return last > tranCache().cbegin() ? dataForTzTransition(*--last) :
Data{};
1232bool QTzTimeZonePrivate::isTimeZoneIdAvailable(
const QByteArray &ianaId)
const
1241QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds()
const
1243 QList<QByteArray>
result = tzZones->keys();
1248QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds(
QLocale::Territory territory)
const
1251 QList<QByteArray>
result;
1253 if (
it.value().territory == territory)
1283 const StatIdent local = identify(
"/etc/localtime");
1284 const StatIdent
tz = identify(
"/etc/TZ");
1285 const StatIdent timezone = identify(
"/etc/timezone");
1286 if (!m_name.isEmpty() && m_last.isValid()
1287 && (m_last == local || m_last ==
tz || m_last == timezone)) {
1291 m_name = etcLocalTime();
1292 if (!m_name.isEmpty()) {
1299 if (!m_name.isEmpty()) {
1306 m_last = m_name.isEmpty() ? StatIdent() : timezone;
1314 static constexpr unsigned long bad = ~0ul;
1315 unsigned long m_dev, m_ino;
1316 constexpr StatIdent() : m_dev(bad), m_ino(bad) {}
1317 StatIdent(
const QT_STATBUF &
data) : m_dev(
data.st_dev), m_ino(
data.st_ino) {}
1318 bool isValid() {
return m_dev != bad || m_ino != bad; }
1320 {
return other.m_dev == m_dev &&
other.m_ino == m_ino; }
1324 static StatIdent identify(
const char *
path)
1327 return QT_STAT(
path, &
data) == -1 ? StatIdent() : StatIdent(
data);
1335 constexpr auto zoneinfo =
"/zoneinfo/"_L1;
1337 long iteration = getSymloopMax();
1344 int index = tzdir.isEmpty() ? -1 :
path.indexOf(tzdir);
1347 return tail.startsWith(u
'/') ? tail.sliced(1) : tail;
1352 }
while (!
path.isEmpty() && --iteration > 0);
1361 return zone.readAll().trimmed();
1367 static long getSymloopMax()
1374 long result = sysconf(_SC_SYMLOOP_MAX);
1391QByteArray QTzTimeZonePrivate::systemTimeZoneId()
const
1393 return staticSystemTimeZoneId();
1396QByteArray QTzTimeZonePrivate::staticSystemTimeZoneId()
1405 if (ianaId ==
":/etc/localtime")
1408 ianaId = ianaId.
sliced(1);
1411 Q_CONSTINIT
thread_local static ZoneNameReader
reader;
constexpr char at(qsizetype n) const
constexpr QByteArrayView sliced(qsizetype pos) const
bool startsWith(QByteArrayView bv) const
char at(qsizetype i) const
Returns the byte at index position i in the byte array.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
QByteArray sliced(qsizetype pos) const &
void clear()
Clears the contents of the byte array and makes it null.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
\inmodule QtCore\reentrant
Status status() const
Returns the status of the data stream.
qint64 readRawData(char *, qint64 len)
Reads at most len bytes from the stream into s and returns the number of bytes read.
\inmodule QtCore\reentrant
static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone)
static qint64 currentMSecsSinceEpoch() noexcept
\inmodule QtCore \reentrant
int month() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QDate addDays(qint64 days) const
Returns a QDate object containing a date ndays later than the date of this object (or earlier if nday...
int dayOfWeek() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
static bool isLeapYear(int year)
Returns true if the specified year is a leap year in the Gregorian calendar; otherwise returns false.
The QDirListing class provides an STL-style iterator for directory entries.
QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
QString symLinkTarget() const
static QByteArray encodeName(const QString &fileName)
Converts fileName to an 8-bit encoding that you can use in native APIs.
void setFileName(const QString &name)
Sets the name of the file.
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
static QLocale::Territory codeToTerritory(QStringView code) noexcept
void unlock() noexcept
Unlocks this mutex locker.
void relock() noexcept
Relocks an unlocked mutex locker.
const_iterator cend() const noexcept
const_iterator cbegin() const noexcept
constexpr QStringView sliced(qsizetype pos) const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
qsizetype indexOf(QLatin1StringView s, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
QString sliced(qsizetype pos) const &
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString first(qsizetype n) const &
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
QString & insert(qsizetype i, QChar c)
QString trimmed() const &
virtual QString displayName(qint64 atMSecsSinceEpoch, QTimeZone::NameType nameType, const QLocale &locale) const
QTzTimeZoneCacheEntry fetchEntry(const QByteArray &ianaId)
QMap< QString, QString > map
[6]
QSet< QString >::iterator it
const PluginKeyMapConstIterator cend
Q_QML_EXPORT QV4::ReturnedValue locale(QV4::ExecutionEngine *engine, const QString &localeName)
Provides locale specific properties and formatted data.
Combined button and popup list for selecting options.
QImageReader reader("image.png")
[1]
static jboolean cut(JNIEnv *, jobject)
DBusConnection const char * rule
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
static ControlElement< T > * ptr(QWidget *widget)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr T qAbs(const T &t)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei GLenum GLenum * types
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLsizei const GLchar *const * path
GLenum GLenum GLenum input
static const char * typeList[]
bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
#define QStringLiteral(str)
QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
static int parsePosixTime(const char *begin, const char *end)
static QMap< int, QByteArray > parseTzAbbreviations(QDataStream &ds, int tzh_charcnt, const QList< QTzType > &types)
static QTzTimeZoneHash loadTzTimeZones()
static int parsePosixTransitionTime(const QByteArray &timeRule)
static bool isTzFile(const QString &name)
static void parseTzLeapSeconds(QDataStream &ds, int tzh_leapcnt, bool longTran)
static QTzHeader parseTzHeader(QDataStream &ds, bool *ok)
static bool asciiIsLetter(char ch)
static QDate calculateDowDate(int year, int month, int dayOfWeek, int week)
static bool openZoneInfo(const QString &name, QFile *file)
static auto validatePosixRule(const QByteArray &posixRule, bool requireOffset=false)
static QList< QTzType > parseTzIndicators(QDataStream &ds, const QList< QTzType > &types, int tzh_ttisstdcnt, int tzh_ttisgmtcnt)
static QDate calculatePosixDate(const QByteArray &dateRule, int year)
static QList< QTzType > parseTzTypes(QDataStream &ds, int tzh_typecnt)
static QList< QTimeZonePrivate::Data > calculatePosixTransitions(const QByteArray &posixRule, int startYear, int endYear, qint64 lastTranMSecs)
QHash< QByteArray, QTzTimeZone > QTzTimeZoneHash
static int parsePosixOffset(const char *begin, const char *end)
static QList< QTzTransition > parseTzTransitions(QDataStream &ds, int tzh_timecnt, bool longTran)
static QByteArray parseTzPosixRule(QDataStream &ds)
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
QLocale::Territory territory