41 #include "qplatformdefs.h"
50 #include "private/qcalendarmath_p.h"
51 #include "private/qdatetime_p.h"
52 #if QT_CONFIG(datetimeparser)
53 #include "private/qdatetimeparser_p.h"
56 #include "private/qcore_mac_p.h"
58 #include "private/qgregoriancalendar_p.h"
59 #include "private/qnumeric_p.h"
60 #include "private/qstringiterator_p.h"
61 #if QT_CONFIG(timezone)
62 #include "private/qtimezoneprivate_p.h"
96 parts.day = qMin(parts.day, cal.
daysInMonth(parts.month, parts.year));
115 #if QT_CONFIG(textdate)
116 static const char qt_shortMonthNames[][4] = {
117 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
118 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
121 static int fromShortMonthName(
QStringView monthName)
123 for (
unsigned int i = 0;
i <
sizeof(qt_shortMonthNames) /
sizeof(qt_shortMonthNames[0]); ++
i) {
131 #if QT_CONFIG(datestring)
132 struct ParsedRfcDateTime {
140 const char16_t shortDayNames[] =
u"MonTueWedThuFriSatSun";
141 for (
int i = 0;
i < 7;
i++) {
157 auto it = tokens.begin();
158 for (
int i = 0;
i < 6 &&
it != tokens.end(); ++
i, ++
it)
161 if (words.
size() < 3 ||
it != tokens.end())
168 return (
name.length() == 3 &&
name[0].isUpper()
169 &&
name[1].isLower() &&
name[2].isLower());
181 dayName = maybeDayName.
chopped(1);
184 dayName = maybeDayName;
188 if (words.
size() < 3 || words.
size() > 5)
192 int dayIndex, monthIndex;
202 yearIndex = words.
size() > 3 && words.
at(2).contains(colon) ? 3 : 2;
207 if (!isShortName(dayName))
209 dayOfWeek = shortDayFromName(dayName);
214 const int day = words.
at(dayIndex).toInt(&
ok);
217 const int year = words.
at(yearIndex).toInt(&
ok);
221 if (!isShortName(monthName))
223 int month = fromShortMonthName(monthName);
236 if (words.
size() && words.
at(0).contains(colon)) {
239 if (when.
size() < 5 || when[2] != colon
240 || (when.
size() == 8 ? when[5] != colon : when.
size() > 5)) {
260 if (words.
size() || !(zone.
size() == 3 || zone.
size() == 5))
265 else if (zone[0] !=
u'+')
273 offset = (hour * 60 + minute) * 60;
296 #if QT_CONFIG(datestring)
298 static int fromOffsetString(
QStringView offsetString,
bool *valid) noexcept
302 const int size = offsetString.size();
310 const QChar signChar = offsetString[0];
311 if (signChar ==
u'+')
313 else if (signChar ==
u'-')
329 const int hour = hhRef.
toInt(&
ok);
330 if (!
ok || hour > 23)
335 if (!
ok || minute < 0 || minute > 59)
339 return sign * ((hour * 60) + minute) * 60;
640 return firstDay.
daysTo(*
this) + 1;
654 return jd -
first + 1;
747 *yearNumber = thursday.
year();
755 using Bounds = std::numeric_limits<qint64>;
764 return jd > minDay && jd <= maxDay;
765 return jd >= minDay && jd < maxDay;
772 #if QT_CONFIG(timezone)
775 zone =
form.timeZone();
780 #if QT_CONFIG(timezone)
790 when = moment(
QTime(12, 0));
793 when = moment(
QTime(23, 59, 59, 999));
801 while (high > low + 1) {
802 int mid = (high + low) / 2;
842 if (!inDateTimeRange(jd,
true))
847 qWarning() <<
"Called QDate::startOfDay(Qt::TimeZone) on" << *
this;
855 qWarning(
"Ignoring offset (%d seconds) passed with Qt::LocalTime", offsetSeconds);
860 when = toEarliest(*
this, when);
865 #if QT_CONFIG(timezone)
872 if (!inDateTimeRange(jd,
true) || !zone.
isValid())
886 if (
at.isValid() &&
at.date() == *
this)
890 when = toEarliest(*
this, when);
899 #if QT_CONFIG(timezone)
902 zone =
form.timeZone();
907 #if QT_CONFIG(timezone)
917 when = moment(
QTime(12, 0));
920 when = moment(
QTime(0, 0));
928 while (high > low + 1) {
929 int mid = (high + low) / 2;
969 if (!inDateTimeRange(jd,
false))
974 qWarning() <<
"Called QDate::endOfDay(Qt::TimeZone) on" << *
this;
978 return QDateTime(*
this,
QTime(23, 59, 59, 999), spec, offsetSeconds);
982 qWarning(
"Ignoring offset (%d seconds) passed with Qt::LocalTime", offsetSeconds);
987 when = toLatest(*
this, when);
991 #if QT_CONFIG(timezone)
998 if (!inDateTimeRange(jd,
false) || !zone.
isValid())
1012 if (
at.isValid() &&
at.date() == *
this)
1016 when = toLatest(*
this, when);
1021 #if QT_CONFIG(datestring)
1028 if (parts.isValid()) {
1042 if (parts.isValid() && parts.year >= 0 && parts.year <= 9999)
1085 return toStringTextDate(*
this);
1089 return toStringIsoDate(*
this);
1260 if (!parts.isValid())
1264 parts.month += nmonths;
1265 while (parts.month <= 0) {
1270 while (parts.month >
count) {
1271 parts.month -=
count;
1275 return fixedDate(std::move(parts), cal);
1292 if (!parts.isValid())
1296 parts.month += nmonths;
1297 while (parts.month <= 0) {
1301 while (parts.month > 12) {
1307 return fixedDate(std::move(parts));
1330 if (!parts.isValid())
1333 int old_y = parts.year;
1334 parts.year += nyears;
1337 if (!cal.
hasYearZero() && ((old_y > 0) != (parts.year > 0) || !parts.year))
1338 parts.year += nyears > 0 ? +1 : -1;
1340 return fixedDate(std::move(parts), cal);
1353 if (!parts.isValid())
1356 int old_y = parts.year;
1357 parts.year += nyears;
1360 if ((old_y > 0) != (parts.year > 0) || !parts.year)
1361 parts.year += nyears > 0 ? +1 : -1;
1363 return fixedDate(std::move(parts));
1437 #if QT_CONFIG(datestring)
1481 if (
string.isEmpty())
1486 return rfcDateImpl(
string).date;
1492 auto it = tokens.begin();
1493 for (
int i = 0;
i < 4 &&
it != tokens.end(); ++
i, ++
it)
1496 if (parts.
size() != 4 ||
it != tokens.end())
1501 int day =
ok ? parts.
at(2).toInt(&
ok) : 0;
1505 const int month = fromShortMonthName(parts.
at(1));
1513 if (
string.
size() >= 10 &&
string.
at(4).isPunct() &&
string.
at(7).isPunct()
1514 && (
string.
size() == 10 || !
string.
at(10).isDigit())) {
1515 const ParsedInt
year = readInt(
string.
first(4));
1516 const ParsedInt
month = readInt(
string.sliced(5, 2));
1517 const ParsedInt
day = readInt(
string.sliced(8, 2));
1603 #if QT_CONFIG(datetimeparser)
1606 if (dt.parseFormat(
format))
1607 dt.fromString(
string, &
date,
nullptr);
1823 #if QT_CONFIG(datestring)
1848 QString QTime::toString(Qt::DateFormat format) const
1855 return QString::asprintf(
"%02d:%02d:%02d.%03d", hour(), minute(), second(), msec());
2009 return theirSeconds - ourSeconds;
2050 return t.ds() - ds();
2126 #if QT_CONFIG(datestring)
2132 *isMidnight24 =
false;
2138 const int dot =
string.
indexOf(
u'.'),
comma =
string.indexOf(
u',');
2140 tail =
string.
sliced(dot + 1);
2143 string =
string.first(dot);
2144 }
else if (
comma != -1) {
2151 const ParsedInt frac = readInt(tail);
2153 if (tail.
isEmpty() ? dot != -1 ||
comma != -1 : !frac.ok)
2156 double fraction = frac.ok ? frac.value * std::pow(0.1, tail.
size()) : 0.0;
2158 const int size =
string.size();
2162 ParsedInt hour = readInt(
string.
first(2));
2167 if (
string.
size() > 2) {
2168 if (
string[2] ==
u':' &&
string.
size() > 4)
2169 minute = readInt(
string.sliced(3, 2));
2170 if (!minute.ok || minute.value >= 60)
2174 }
else if (frac.ok) {
2175 Q_ASSERT(!(fraction < 0.0) && fraction < 1.0);
2178 fraction -= minute.value;
2182 if (
string.
size() > 5) {
2183 if (
string[5] ==
u':' &&
string.
size() == 8)
2184 second = readInt(
string.sliced(6, 2));
2185 if (!second.ok || second.value >= 60)
2187 }
else if (frac.ok) {
2190 Q_ASSERT(!(fraction < 0.0) && fraction < 1.0);
2193 fraction -= second.value;
2196 Q_ASSERT(!(fraction < 0.0) && fraction < 1.0);
2203 if (isMidnight24 || hour.value < 23 || minute.value < 59 || second.value < 59) {
2205 if (++second.value == 60) {
2207 if (++minute.value == 60) {
2221 if (hour.value == 24 && minute.value == 0 && second.value == 0 && msec == 0) {
2224 *isMidnight24 =
true;
2228 return QTime(hour.value, minute.value, second.value, msec);
2246 if (
string.isEmpty())
2251 return rfcDateImpl(
string).time;
2256 return fromIsoTimeString(
string,
format,
nullptr);
2334 #if QT_CONFIG(datetimeparser)
2337 if (dt.parseFormat(
format))
2338 dt.fromString(
string,
nullptr, &
time);
2379 #if defined(Q_CC_MSVC)
2382 if (_get_tzname(&
s,
name, 512, isDst))
2390 #if QT_CONFIG(datetimeparser)
2401 for (
const auto z : zones) {
2403 if (
name.startsWith(zone))
2416 static constexpr
int tmYearFromQYear(
int year) {
return year - (year < 0 ? 1899 : 1900); }
2417 static constexpr
int qYearFromTmYear(
int year) {
return year + (year < -1899 ? 1899 : 1900); }
2438 static inline bool meansEnd1969(tm *
local)
2445 ||
local->tm_min % 5 != 4
2446 || (
local->tm_year == 69
2448 :
local->tm_mon > 0 ||
local->tm_mday > 1)) {
2495 static inline bool callMkTime(tm *
local, time_t *secs)
2497 constexpr time_t maybeError = -1;
2498 const tm copy = *
local;
2500 bool good = *secs != maybeError || meansEnd1969(
local);
2501 if (copy.tm_isdst >= 0 && (!good ||
local->tm_isdst != copy.tm_isdst)) {
2504 local->tm_isdst = -1;
2506 good = *secs != maybeError || meansEnd1969(
local);
2508 #if defined(Q_OS_WIN)
2512 if (
local->tm_isdst == 0 &&
local->tm_hour != copy.tm_hour) {
2513 local->tm_hour += 2;
2514 if (
local->tm_hour > 23) {
2515 local->tm_hour -= 24;
2517 local->tm_mon + 1, qYearFromTmYear(
local->tm_year))) {
2519 if (++
local->tm_mon > 11) {
2526 local->tm_isdst = 1;
2550 local.tm_mon = mm - 1;
2551 local.tm_year = tmYearFromQYear(yy);
2552 local.tm_isdst = daylightStatus ? int(*daylightStatus) : -1;
2554 time_t secsSinceEpoch;
2555 if (!callMkTime(&
local, &secsSinceEpoch)) {
2571 if (
local.tm_isdst > 0) {
2577 if (daylightStatus) {
2578 *daylightStatus = (
local.tm_isdst == 0
2587 if (secsSinceEpoch < 0 && msec > 0) {
2592 const bool overflow =
2593 mul_overflow(
qint64(secsSinceEpoch),
2594 std::integral_constant<qint64, MSECS_PER_SEC>(), &millis)
2595 || add_overflow(millis, msec, &msec);
2603 static bool qt_localtime(
qint64 msecsSinceEpoch,
QDate *localDate,
QTime *localTime,
2606 const int signFix = msecsSinceEpoch %
MSECS_PER_SEC && msecsSinceEpoch < 0 ? 1 : 0;
2607 const time_t secsSinceEpoch = msecsSinceEpoch /
MSECS_PER_SEC - signFix;
2619 #if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
2622 if (tm *
res = localtime_r(&secsSinceEpoch, &
local)) {
2626 #elif defined(Q_OS_WIN)
2627 if (!localtime_s(&
local, &secsSinceEpoch))
2632 if (tm *
res = localtime(&secsSinceEpoch)) {
2641 if (daylightStatus) {
2642 if (
local.tm_isdst > 0)
2644 else if (
local.tm_isdst < 0)
2651 *localDate =
QDate();
2652 *localTime =
QTime();
2690 if (days < 0 && dayms > 0) {
2694 if (mul_overflow(days, std::integral_constant<qint64, MSECS_PER_DAY>(), &msecs)
2695 || add_overflow(msecs, dayms, &msecs)) {
2696 using Bound = std::numeric_limits<qint64>;
2697 return days < 0 ? Bound::min() : Bound::max();
2730 static auto computeSystemMillisRange()
2732 struct R {
qint64 min, max;
bool minClip, maxClip; };
2733 using Bounds = std::numeric_limits<qint64>;
2735 if constexpr (isNarrow) {
2737 const qint64 msecsMin = -1 - msecsMax;
2739 struct tm
local = {};
2740 local.tm_year = tmYearFromQYear(1901);
2743 local.tm_isdst = -1;
2744 return R{
qMkTime(&
local) == -1 ? 0 : msecsMin, msecsMax,
false,
false};
2746 const struct {
int year;
qint64 millis; } starts[] = {
2766 bool stopMax =
true;
2767 for (
const auto c : ends) {
2768 struct tm
local = {};
2769 local.tm_year = tmYearFromQYear(
c.year);
2774 local.tm_isdst = -1;
2781 bool startMin =
true;
2782 for (
const auto c : starts) {
2784 local.tm_year = tmYearFromQYear(
c.year);
2787 local.tm_isdst = -1;
2789 return R{
c.millis, stop, startMin, stopMax};
2792 return R{0, stop,
false, stopMax};
2813 static inline bool millisInSystemRange(
qint64 millis,
qint64 slack = 0)
2815 static const auto bounds = computeSystemMillisRange();
2816 return (bounds.minClip || millis >= bounds.min - slack)
2817 && (bounds.maxClip || millis <= bounds.max + slack);
2836 static int systemTimeYearMatching(
int year)
2838 #if defined(Q_OS_WIN) || defined(Q_OS_WASM)
2839 static constexpr
int forLeapEarly[] = { 1984, 1996, 1980, 1992, 1976, 1988, 1972 };
2840 static constexpr
int regularEarly[] = { 1978, 1973, 1974, 1975, 1970, 1971, 1977 };
2842 static constexpr
int forLeapEarly[] = { 1928, 1912, 1924, 1908, 1920, 1904, 1916 };
2843 static constexpr
int regularEarly[] = { 1905, 1906, 1907, 1902, 1903, 1909, 1910 };
2845 static constexpr
int forLeapLate[] = { 2012, 2024, 2036, 2020, 2032, 2016, 2028 };
2846 static constexpr
int regularLate[] = { 2034, 2035, 2030, 2031, 2037, 2027, 2033 };
2850 ? (year < 1970 ? forLeapEarly : forLeapLate)
2851 : (year < 1970 ? regularEarly : regularLate))[dow == 7 ? 0 : dow];
2861 if (!millisInSystemRange(msecs)) {
2864 #if QT_CONFIG(timezone)
2867 if (sys.isValid()) {
2868 if (daylightStatus) {
2869 *daylightStatus = sys.d->isDaylightTime(msecs)
2873 if (add_overflow(msecs, sys.d->offsetFromUtc(msecs) *
MSECS_PER_SEC, &msecs))
2875 msecsToTime(msecs, localDate, localTime);
2883 msecsToTime(msecs, &utcDate, &utcTime);
2884 int year, month, day;
2885 utcDate.
getDate(&year, &month, &day);
2887 QDate fakeDate(systemTimeYearMatching(year), month, day);
2889 bool res = qt_localtime(fakeMsecs, localDate, localTime, daylightStatus);
2895 return qt_localtime(msecs, localDate, localTime, daylightStatus);
2912 msecsToTime(localMsecs, &dt, &tm);
2913 const qint64 utcMsecs = qt_mktime(&dt, &tm, daylightStatus, abbreviation, &valid);
2914 if (valid && millisInSystemRange(utcMsecs)) {
2925 #if QT_CONFIG(timezone)
2928 if (sys.isValid()) {
2929 return QDateTimePrivate::zoneMSecsToEpochMSecs(localMsecs, sys, daylightStatus,
2930 localDate, localTime, abbreviation);
2937 msecsToTime(localMsecs, &dt, &tm);
2938 int year, month, day;
2939 dt.
getDate(&year, &month, &day);
2941 QDate fakeDate(systemTimeYearMatching(year), month, day);
2943 const qint64 utcMsecs = qt_mktime(&fakeDate, &tm, daylightStatus, abbreviation, &
ok);
2946 *localDate = fakeDate.
addDays(fakeDiff);
2951 msecsToTime(utcMsecs, &utcDate, &utcTime);
2952 return timeToMSecs(utcDate.
addDays(fakeDiff), utcTime);
2960 static inline bool msecsCanBeSmall(
qint64 msecs)
2962 if (!QDateTimeData::CanBeSmall)
2967 return sd.msecs == msecs;
2970 static constexpr
inline
2971 QDateTimePrivate::StatusFlags mergeSpec(QDateTimePrivate::StatusFlags status,
Qt::TimeSpec spec)
2978 static constexpr
inline Qt::TimeSpec extractSpec(QDateTimePrivate::StatusFlags status)
2984 static constexpr
inline QDateTimePrivate::StatusFlags
2997 static constexpr
inline
3017 static inline QDateTimePrivate::StatusFlags getStatus(
const QDateTimeData &
d)
3029 return extractSpec(getStatus(
d));
3039 const auto status = getStatus(
a);
3040 if (status != getStatus(
b))
3044 switch (extractSpec(status)) {
3057 return a->m_offsetFromUtc ==
b->m_offsetFromUtc;
3067 auto status = getStatus(
d);
3068 Q_ASSERT(extractSpec(status) == spec);
3069 int offsetFromUtc = 0;
3078 const qint64 msecs = getMSecs(
d);
3082 auto dstStatus = extractDaylightStatus(status);
3086 #if QT_CONFIG(timezone)
3088 }
else if (
d->m_timeZone.isValid()) {
3089 epochMSecs = QDateTimePrivate::zoneMSecsToEpochMSecs(
3090 msecs,
d->m_timeZone, &dstStatus, &testDate, &testTime);
3100 if (
ok && timeToMSecs(testDate, testTime) == msecs) {
3101 status = mergeDaylightStatus(status, dstStatus);
3109 d.data.status = status.toInt();
3111 d->m_status = status;
3112 d->m_offsetFromUtc = offsetFromUtc;
3119 auto status = getStatus(
d);
3127 d.data.status = status.toInt();
3129 d->m_status = status;
3135 auto status = getStatus(
d);
3136 auto spec = extractSpec(status);
3141 refreshSimpleDateTime(
d);
3147 refreshZonedDateTime(
d, spec);
3155 auto status = getStatus(
d);
3161 if (offsetSeconds == 0)
3165 qWarning(
"Using TimeZone in setTimeSpec() is unsupported");
3174 status = mergeSpec(status, spec);
3175 if (
d.isShort() && offsetSeconds == 0) {
3176 d.data.status = status.toInt();
3180 d->m_offsetFromUtc = offsetSeconds;
3181 #if QT_CONFIG(timezone)
3194 QDateTimePrivate::StatusFlags newStatus = { };
3212 if (days < 0 && ds > 0) {
3219 if (mul_overflow(days, std::integral_constant<qint64, MSECS_PER_DAY>(), &msecs)
3220 || add_overflow(msecs,
qint64(ds), &msecs)) {
3221 newStatus = QDateTimePrivate::StatusFlags{};
3226 if (msecsCanBeSmall(msecs)) {
3230 d.data.status |= newStatus.toInt();
3240 d->m_status |= newStatus;
3248 auto status = getStatus(
d);
3275 if (CanBeSmall &&
Q_LIKELY(specCanBeSmall(spec))) {
3281 d->m_status = mergeSpec({}, spec);
3290 if (specCanBeSmall(extractSpec(
d->m_status)) && msecsCanBeSmall(
d->m_msecs)) {
3318 if (!
other.isShort()) {
3320 if (specCanBeSmall(extractSpec(
other.d->m_status)) && msecsCanBeSmall(
other.d->m_msecs)) {
3336 inline QDateTime::Data::~Data()
3338 if (!isShort() && !
d->ref.deref())
3342 inline bool QDateTime::Data::isShort()
const
3356 inline void QDateTime::Data::detach()
3359 bool wasShort = isShort();
3364 x->m_msecs =
data.msecs;
3366 if (
d->ref.loadRelaxed() == 1)
3372 x->ref.storeRelaxed(1);
3373 if (!wasShort && !
d->ref.deref())
3401 setTimeSpec(
result, toSpec, offsetSeconds);
3402 setDateTime(
result, toDate, toTime);
3404 refreshSimpleDateTime(
result);
3410 #if QT_CONFIG(timezone)
3418 result.d->m_timeZone = toTimeZone;
3419 setDateTime(
result, toDate, toTime);
3427 DaylightStatus *hint,
3441 : (
data.daylightTimeOffset
3446 *abbreviation = badDateTime ?
QString() :
data.abbreviation;
3451 *zoneDate =
QDate();
3453 *zoneTime =
QTime();
3455 msecsToTime(msecs, zoneDate, zoneTime);
3457 return data.atMSecsSinceEpoch;
3625 #if QT_VERSION >= QT_VERSION_CHECK(7,0,0) || QT_POINTER_SIZE == 8
3627 static_assert(
sizeof(
Data) ==
sizeof(
qint64));
3629 static_assert(
sizeof(
ShortData) >=
sizeof(
void*),
"oops, Data::swap() is broken!");
3653 #if QT_CONFIG(timezone)
3723 auto status = getStatus(
d);
3743 auto status = getStatus(
d);
3755 auto status = getStatus(
d);
3759 msecsToTime(getMSecs(
d), &dt,
nullptr);
3771 auto status = getStatus(
d);
3775 msecsToTime(getMSecs(
d),
nullptr, &tm);
3790 #if QT_CONFIG(timezone)
3805 switch (getSpec(d)) {
3811 if (
d->m_timeZone.isValid())
3812 return d->m_timeZone;
3846 return d->m_offsetFromUtc;
3850 auto spec = getSpec(
d);
3887 switch (getSpec(
d)) {
3893 #if !QT_CONFIG(timezone)
3897 return d->m_timeZone.abbreviation(*
this);
3901 auto status = extractDaylightStatus(getStatus(
d));
3925 switch (getSpec(
d)) {
3930 #if !QT_CONFIG(timezone)
3937 auto status = extractDaylightStatus(getStatus(
d));
3956 checkValidDateTime(
d);
3975 checkValidDateTime(
d);
3998 refreshSimpleDateTime(
d);
4021 refreshSimpleDateTime(
d);
4024 #if QT_CONFIG(timezone)
4036 void QDateTime::setTimeZone(
const QTimeZone &toZone)
4040 d->m_offsetFromUtc = 0;
4041 d->m_timeZone = toZone;
4067 switch (getSpec(
d)) {
4077 auto status = extractDaylightStatus(getStatus(
d));
4087 #if QT_CONFIG(timezone)
4089 if (
d->m_timeZone.isValid())
4134 auto status = getStatus(
d);
4135 const auto spec = extractSpec(status);
4147 auto dst = extractDaylightStatus(status);
4152 setDateTime(
d, dt, tm);
4153 status = getStatus(
d);
4160 #if QT_CONFIG(timezone)
4161 }
else if (spec ==
Qt::TimeZone && (
d.detach(),
d->m_timeZone.isValid())) {
4162 const auto data =
d->m_timeZone.d->data(msecs);
4175 status = mergeDaylightStatus(status,
dst);
4180 if (msecsCanBeSmall(
local) &&
d.isShort()) {
4183 d.data.status = status.toInt();
4205 if (!mul_overflow(secs, std::integral_constant<qint64, MSECS_PER_SEC>(), &msecs)) {
4207 }
else if (
d.isShort()) {
4215 #if QT_CONFIG(datestring)
4247 QString QDateTime::toString(Qt::DateFormat format) const
4261 buf = toStringTextDate(
p.first);
4263 buf.insert(
buf.lastIndexOf(
u' '),
4266 switch (timeSpec()) {
4269 #if QT_CONFIG(timezone)
4271 buf +=
u' ' +
d->m_timeZone.displayName(
4289 buf = toStringIsoDate(
p.first);
4293 switch (getSpec(
d)) {
4298 #if QT_CONFIG(timezone)
4372 auto status = getStatus(
d);
4375 auto spec = extractSpec(status);
4378 refreshSimpleDateTime(
d);
4381 auto dst = extractDaylightStatus(status);
4385 #if QT_CONFIG(timezone)
4387 utc = QDateTimePrivate::zoneMSecsToEpochMSecs(
local,
d.d->m_timeZone, &
dst, &
date, &
time);
4393 status = getStatus(
d);
4403 d.data.status = status.toInt();
4405 d->m_status = status;
4432 massageAdjustedDateTime(dt.d,
p.first.addDays(ndays),
p.second);
4457 massageAdjustedDateTime(dt.d,
p.first.addMonths(nmonths),
p.second);
4482 massageAdjustedDateTime(dt.d,
p.first.addYears(nyears),
p.second);
4499 if (mul_overflow(
s, std::integral_constant<qint64, MSECS_PER_SEC>(), &msecs))
4519 switch (getSpec(
d)) {
4525 }
else if (dt.d.isShort()) {
4535 if (add_overflow(getMSecs(
d), msecs, &msecs)) {
4536 if (dt.d.isShort()) {
4542 }
else if (
d.isShort()) {
4544 if (msecsCanBeSmall(msecs)) {
4545 dt.d.data.msecs =
qintptr(msecs);
4548 dt.d->m_msecs = msecs;
4552 dt.d->m_msecs = msecs;
4647 ret.setTimeSpec(spec);
4670 &&
d->m_offsetFromUtc == offsetSeconds)
4675 ret.setOffsetFromUtc(offsetSeconds);
4682 #if QT_CONFIG(timezone)
4693 if (getSpec(d) ==
Qt::TimeZone &&
d->m_timeZone == timeZone)
4698 ret.setTimeZone(timeZone);
4717 return !
other.isValid();
4718 if (!
other.isValid())
4721 if (usesSameOffset(d,
other.d))
4722 return getMSecs(d) == getMSecs(
other.d);
4764 return other.isValid();
4765 if (!
other.isValid())
4768 if (usesSameOffset(d,
other.d))
4769 return getMSecs(d) < getMSecs(
other.d);
4848 #if defined(Q_OS_WIN)
4849 static inline uint msecsFromDecomposed(
int hour,
int minute,
int sec,
int msec = 0)
4858 return QDate(st.wYear, st.wMonth, st.wDay);
4866 ct.
setHMS(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
4875 QDate d(st.wYear, st.wMonth, st.wDay);
4876 t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
4885 QDate d(st.wYear, st.wMonth, st.wDay);
4886 t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
4896 return msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds) +
4910 #elif defined(Q_OS_UNIX)
4936 gettimeofday(&tv,
nullptr);
4943 gettimeofday(&tv,
nullptr);
4947 #error "What system is this?"
5000 if (secs > maxSeconds || secs < minSeconds)
5005 #if QT_CONFIG(timezone)
5018 dt.setTimeZone(timeZone);
5037 if (secs > maxSeconds || secs < minSeconds)
5043 #if QT_CONFIG(datestring)
5063 if (
string.isEmpty())
5068 const ParsedRfcDateTime rfc = rfcDateImpl(
string);
5070 if (!rfc.date.isValid() || !rfc.time.isValid())
5079 const int size =
string.size();
5093 if (isoString.
size() < 2
5101 isoString = isoString.
sliced(1);
5111 int signIndex = isoString.
size() - 1;
5115 QChar character(isoString[signIndex]);
5116 found = character ==
u'+' || character ==
u'-';
5117 }
while (!found && --signIndex >= 0);
5124 isoString = isoString.
first(signIndex);
5131 bool isMidnight24 =
false;
5143 auto it = tokens.begin();
5144 for (
int i = 0;
i < 6 &&
it != tokens.end(); ++
i, ++
it)
5149 if (parts.
count() < 5 ||
it != tokens.end())
5156 if (parts.
at(3).contains(
u':'))
5158 else if (parts.
at(4).contains(
u':'))
5164 int day = parts.
at(2).toInt(&
ok);
5165 int year =
ok ? parts.
at(yearPart).toInt(&
ok) : 0;
5166 int month = fromShortMonthName(parts.
at(1));
5167 if (!
ok || year == 0 || day == 0 || month < 1)
5178 if (parts.
count() == 5)
5278 #if QT_CONFIG(datetimeparser)
5283 if (dt.parseFormat(
format) && (dt.fromString(
string, &datetime) || !datetime.
isValid()))
5324 #ifndef QT_NO_DATASTREAM
5355 date.jd = (jd != 0 ? jd : QDate::nullJd());
5399 time.mds = (ds == 0) ? QTime::NullTime :
int(ds);
5418 dateAndTime = getDateTime(
dateTime.d);
5422 #if QT_CONFIG(timezone)
5439 dateAndTime = getDateTime(
dateTime.d);
5459 dateAndTime = getDateTime(
dateTime.d);
5482 #if QT_CONFIG(timezone)
5489 in >> dt >> tm >> ts;
5494 #if QT_CONFIG(timezone)
5506 in >> dt >> tm >> ts;
5514 in >> dt >> tm >> ts;
5524 #if QT_CONFIG(timezone)
5552 #if !defined(QT_NO_DEBUG_STREAM) && QT_CONFIG(datestring)
5580 dbg.
nospace() <<
"QDateTime(";
5583 dbg.
noquote() <<
date.toString(
u"yyyy-MM-dd HH:mm:ss.zzz t")
5589 dbg.
space() <<
date.offsetFromUtc() <<
's';
5592 #if QT_CONFIG(timezone)
5618 return key.isValid() ?
qHash(
key.toMSecsSinceEpoch(), seed) : seed;
5629 return qHash(
key.toJulianDay(), seed);
5640 return qHash(
key.msecsSinceStartOfDay(), seed);
small capitals from c petite p scientific f u
small capitals from c petite p scientific i
[1]
The QCalendar class describes calendar systems.
QDate dateFromParts(int year, int month, int day) const
QString monthName(const QLocale &locale, int month, int year=Unspecified, QLocale::FormatType format=QLocale::LongFormat) const
YearMonthDay partsFromDate(QDate date) const
int monthsInYear(int year) const
int dayOfWeek(QDate date) const
int daysInMonth(int month, int year=Unspecified) const
int daysInYear(int year) const
The QChar class provides a 16-bit Unicode character.
constexpr bool isDigit() const noexcept
The QDataStream class provides serialization of binary data to a QIODevice.
operator>>(QDataStream &ds, qfloat16 &f)
operator<<(QDataStream &ds, qfloat16 f)
The QDate class provides date functions.
int weekNumber(int *yearNum=nullptr) const
qint64 daysTo(QDate d) const
constexpr bool isValid() const
constexpr qint64 toJulianDay() const
static constexpr QDate fromJulianDay(qint64 jd_)
QDate addDays(qint64 days) const
QDate addYears(int years) const
QDateTime endOfDay(Qt::TimeSpec spec=Qt::LocalTime, int offsetSeconds=0) const
constexpr bool isNull() const
QDate addMonths(int months) const
QDateTime startOfDay(Qt::TimeSpec spec=Qt::LocalTime, int offsetSeconds=0) const
void getDate(int *year, int *month, int *day) const
static QDate currentDate()
bool setDate(int year, int month, int day)
static bool isLeapYear(int year)
The QDateTime class provides date and time functions.
void setOffsetFromUtc(int offsetSeconds)
int offsetFromUtc() const
static QDateTime currentDateTime()
QDateTime toTimeSpec(Qt::TimeSpec spec) const
void setMSecsSinceEpoch(qint64 msecs)
qint64 toMSecsSinceEpoch() const
qint64 secsTo(const QDateTime &) const
QDateTime addMSecs(qint64 msecs) const
QDateTime addMonths(int months) const
QDateTime & operator=(const QDateTime &other) noexcept
static QDateTime fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec=Qt::LocalTime, int offsetFromUtc=0)
qint64 msecsTo(const QDateTime &) const
QString timeZoneAbbreviation() const
QDateTime addSecs(qint64 secs) const
static qint64 currentSecsSinceEpoch() noexcept
void setTimeSpec(Qt::TimeSpec spec)
Qt::TimeSpec timeSpec() const
bool isDaylightTime() const
static QDateTime currentDateTimeUtc()
QDateTime toOffsetFromUtc(int offsetSeconds) const
static QDateTime fromSecsSinceEpoch(qint64 secs, Qt::TimeSpec spec=Qt::LocalTime, int offsetFromUtc=0)
qint64 daysTo(const QDateTime &) const
static qint64 currentMSecsSinceEpoch() noexcept
qint64 toSecsSinceEpoch() const
QDateTime addYears(int years) const
QDateTime addDays(qint64 days) const
void setSecsSinceEpoch(qint64 secs)
QDateTime::ShortData QDateTimeShortData
static qint64 localMSecsToEpochMSecs(qint64 localMsecs, DaylightStatus *daylightStatus, QDate *localDate=nullptr, QTime *localTime=nullptr, QString *abbreviation=nullptr)
static bool epochMSecsToLocalTime(qint64 msecs, QDate *localDate, QTime *localTime, DaylightStatus *daylightStatus=nullptr)
static QDateTime::Data create(QDate toDate, QTime toTime, Qt::TimeSpec toSpec, int offsetSeconds)
QDateTime::Data QDateTimeData
The QDebug class provides an output stream for debugging information.
Convenience class for custom QDebug operators.
template< typename Enum > size_t qHash(QFlags< Enum > flags, size_t seed=0) noexcept
static int yearStartWeekDay(int year)
static int monthLength(int month, int year)
static bool leapTest(int year)
static bool julianFromParts(int year, int month, int day, qint64 *jd)
static QCalendar::YearMonthDay partsFromJulian(qint64 jd)
static bool validParts(int year, int month, int day)
static int weekDayOfJulian(qint64 jd)
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
QString dayName(int, FormatType format=LongFormat) const
QString toString(qlonglong i) const
The QString class provides a Unicode character string.
qulonglong toULongLong(bool *ok=nullptr, int base=10) const
static QString fromLocal8Bit(QByteArrayView ba)
static QString static QString asprintf(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
The QStringView class provides a unified view on UTF-16 strings with a read-only subset of the QStrin...
bool startsWith(QStringView s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
constexpr QChar front() const
constexpr void chop(qsizetype n) noexcept
constexpr bool isEmpty() const noexcept
constexpr qsizetype size() const noexcept
constexpr QStringView first(qsizetype n) const noexcept
constexpr QStringView chopped(qsizetype n) const noexcept
bool endsWith(QStringView s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
int toInt(bool *ok=nullptr, int base=10) const
constexpr QStringView last(qsizetype n) const noexcept
constexpr QStringView sliced(qsizetype pos) const noexcept
qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
The QTime class provides clock time functions.
int secsTo(QTime t) const
constexpr bool isNull() const
static QTime currentTime()
QTime addMSecs(int ms) const
static constexpr QTime fromMSecsSinceStartOfDay(int msecs)
int msecsTo(QTime t) const
bool setHMS(int h, int m, int s, int ms=0)
constexpr int msecsSinceStartOfDay() const
QTime addSecs(int secs) const
The QTimeZone class converts between UTC and local time in a specific time zone.
OffsetData previousTransition(const QDateTime &beforeDateTime) const
static QTimeZone systemTimeZone()
bool hasTransitions() const
OffsetData nextTransition(const QDateTime &afterDateTime) const
Data dataForLocalTime(qint64 forLocalMSecs, int hint) const
virtual int offsetFromUtc(qint64 atMSecsSinceEpoch) const
static constexpr qint64 invalidSeconds()
constexpr size_type size() const noexcept
void remove(qsizetype i, qsizetype n=1)
iterator erase(const_iterator begin, const_iterator end)
const T & at(qsizetype idx) const
T & emplace_back(Args &&...args)
iterator begin() noexcept
constexpr Int qMod(Int a, unsigned b)
std::chrono::milliseconds ms
std::pair< T1, T2 > QPair
constexpr qint64 MSECS_PER_SEC
constexpr qint64 TIME_T_MAX
constexpr qint64 MSECS_PER_HOUR
constexpr qint64 JULIAN_DAY_FOR_EPOCH
QDateTimePrivate::QDateTimeShortData ShortData
constexpr qint64 SECS_PER_MIN
QDateTimePrivate::QDateTimeData QDateTimeData
constexpr QT_BEGIN_NAMESPACE qint64 SECS_PER_DAY
constexpr qint64 MSECS_PER_MIN
constexpr qint64 SECS_PER_HOUR
constexpr qint64 MSECS_PER_DAY
EGLOutputLayerEXT EGLint EGLAttrib value
int qRound(qfloat16 d) noexcept
time_t qMkTime(struct tm *when)
unsigned long long quint64
QT_BEGIN_NAMESPACE typedef signed char qint8
std::enable_if_t< std::is_unsigned_v< T >, bool > qAddOverflow(T v1, T v2, T *r)
GLboolean GLboolean GLboolean b
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLint GLsizei GLsizei GLenum format
GLfloat GLfloat GLfloat GLfloat h
int QT_PREPEND_NAMESPACE(QSharedMemoryPrivate)
QTextStream out(stdout)
[7]
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
QThreadStorage< int * > dummy[8]