summaryrefslogtreecommitdiffstats
path: root/src/corelib/time
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/time')
-rw-r--r--src/corelib/time/qcalendar.cpp4
-rw-r--r--src/corelib/time/qdatetime.cpp15
-rw-r--r--src/corelib/time/qtimezoneprivate_p.h10
-rw-r--r--src/corelib/time/qtimezoneprivate_tz.cpp28
4 files changed, 41 insertions, 16 deletions
diff --git a/src/corelib/time/qcalendar.cpp b/src/corelib/time/qcalendar.cpp
index 62b32370e1..076b401c56 100644
--- a/src/corelib/time/qcalendar.cpp
+++ b/src/corelib/time/qcalendar.cpp
@@ -1296,3 +1296,7 @@ QStringList QCalendar::availableCalendars()
}
QT_END_NAMESPACE
+
+#ifndef QT_BOOTSTRAPPED
+#include "moc_qcalendar.cpp"
+#endif
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index ec12569e3f..c30fd046a4 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -75,6 +75,7 @@
#include "qcalendar.h"
#include "qgregoriancalendar_p.h"
+#include "private/qnumeric_p.h"
QT_BEGIN_NAMESPACE
@@ -1429,9 +1430,11 @@ QDate QDate::addDays(qint64 ndays) const
if (isNull())
return QDate();
- // Due to limits on minJd() and maxJd() we know that any overflow
- // will be invalid and caught by fromJulianDay().
- return fromJulianDay(jd + ndays);
+ qint64 r;
+ if (Q_UNLIKELY(add_overflow(jd, ndays, &r)))
+ return QDate();
+ else
+ return fromJulianDay(r);
}
/*!
@@ -4548,9 +4551,9 @@ static inline void massageAdjustedDateTime(const QDateTimeData &d, QDate *date,
QDateTimePrivate::DaylightStatus status = QDateTimePrivate::UnknownDaylightTime;
localMSecsToEpochMSecs(timeToMSecs(*date, *time), &status, date, time);
#if QT_CONFIG(timezone)
- } else if (spec == Qt::TimeZone && d->m_timeZone.isValid()) {
+ } else if (spec == Qt::TimeZone && d.d->m_timeZone.isValid()) {
QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(*date, *time),
- d->m_timeZone,
+ d.d->m_timeZone,
QDateTimePrivate::UnknownDaylightTime,
date, time);
#endif // timezone
diff --git a/src/corelib/time/qtimezoneprivate_p.h b/src/corelib/time/qtimezoneprivate_p.h
index 62cd32c898..eb847b80f5 100644
--- a/src/corelib/time/qtimezoneprivate_p.h
+++ b/src/corelib/time/qtimezoneprivate_p.h
@@ -243,6 +243,7 @@ public:
QIcuTimeZonePrivate *clone() const override;
+ using QTimeZonePrivate::displayName;
QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType,
const QLocale &locale) const override;
QString abbreviation(qint64 atMSecsSinceEpoch) const override;
@@ -345,12 +346,17 @@ public:
QList<QByteArray> availableTimeZoneIds(QLocale::Country country) const override;
private:
- void init(const QByteArray &ianaId);
+ static QByteArray staticSystemTimeZoneId();
QVector<QTimeZonePrivate::Data> getPosixTransitions(qint64 msNear) const;
Data dataForTzTransition(QTzTransitionTime tran) const;
#if QT_CONFIG(icu)
- mutable QSharedDataPointer<QTimeZonePrivate> m_icu;
+# ifdef __cpp_lib_is_final
+ static_assert(std::is_final<QIcuTimeZonePrivate>::value,
+ "if QIcuTimeZonePrivate isn't final, we may need to specialize "
+ "QExplicitlySharedDataPointer::clone() to call QTimeZonePrivate::clone()");
+# endif
+ mutable QExplicitlySharedDataPointer<const QIcuTimeZonePrivate> m_icu;
#endif
QTzTimeZoneCacheEntry cached_data;
QVector<QTzTransitionTime> tranCache() const { return cached_data.m_tranTimes; }
diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp
index b1611d7ddb..55914cc7da 100644
--- a/src/corelib/time/qtimezoneprivate_tz.cpp
+++ b/src/corelib/time/qtimezoneprivate_tz.cpp
@@ -42,6 +42,7 @@
#include "qtimezone.h"
#include "qtimezoneprivate_p.h"
#include "private/qlocale_tools_p.h"
+#include "private/qlocking_p.h"
#include <QtCore/QDataStream>
#include <QtCore/QDateTime>
@@ -62,6 +63,10 @@
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(icu)
+static QBasicMutex s_icu_mutex;
+#endif
+
/*
Private
@@ -654,14 +659,8 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
// Create the system default time zone
QTzTimeZonePrivate::QTzTimeZonePrivate()
+ : QTzTimeZonePrivate(staticSystemTimeZoneId())
{
- init(systemTimeZoneId());
-}
-
-// Create a named time zone
-QTzTimeZonePrivate::QTzTimeZonePrivate(const QByteArray &ianaId)
-{
- init(ianaId);
}
QTzTimeZonePrivate::~QTzTimeZonePrivate()
@@ -670,6 +669,9 @@ QTzTimeZonePrivate::~QTzTimeZonePrivate()
QTzTimeZonePrivate *QTzTimeZonePrivate::clone() const
{
+#if QT_CONFIG(icu)
+ const auto lock = qt_scoped_lock(s_icu_mutex);
+#endif
return new QTzTimeZonePrivate(*this);
}
@@ -872,7 +874,8 @@ QTzTimeZoneCacheEntry QTzTimeZoneCache::fetchEntry(const QByteArray &ianaId)
return ret;
}
-void QTzTimeZonePrivate::init(const QByteArray &ianaId)
+// Create a named time zone
+QTzTimeZonePrivate::QTzTimeZonePrivate(const QByteArray &ianaId)
{
static QTzTimeZoneCache tzCache;
auto entry = tzCache.fetchEntry(ianaId);
@@ -913,12 +916,14 @@ QString QTzTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
const QLocale &locale) const
{
#if QT_CONFIG(icu)
+ auto lock = qt_unique_lock(s_icu_mutex);
if (!m_icu)
m_icu = new QIcuTimeZonePrivate(m_id);
// TODO small risk may not match if tran times differ due to outdated files
// TODO Some valid TZ names are not valid ICU names, use translation table?
if (m_icu->isValid())
return m_icu->displayName(atMSecsSinceEpoch, nameType, locale);
+ lock.unlock();
#else
Q_UNUSED(nameType)
Q_UNUSED(locale)
@@ -932,12 +937,14 @@ QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
const QLocale &locale) const
{
#if QT_CONFIG(icu)
+ auto lock = qt_unique_lock(s_icu_mutex);
if (!m_icu)
m_icu = new QIcuTimeZonePrivate(m_id);
// TODO small risk may not match if tran times differ due to outdated files
// TODO Some valid TZ names are not valid ICU names, use translation table?
if (m_icu->isValid())
return m_icu->displayName(timeType, nameType, locale);
+ lock.unlock();
#else
Q_UNUSED(timeType)
Q_UNUSED(nameType)
@@ -1285,6 +1292,11 @@ private:
QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
{
+ return staticSystemTimeZoneId();
+}
+
+QByteArray QTzTimeZonePrivate::staticSystemTimeZoneId()
+{
// Check TZ env var first, if not populated try find it
QByteArray ianaId = qgetenv("TZ");