summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qdatetime.cpp5685
-rw-r--r--src/corelib/tools/qdatetime.h426
-rw-r--r--src/corelib/tools/qdatetime_p.h151
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp2047
-rw-r--r--src/corelib/tools/qdatetimeparser_p.h310
-rw-r--r--src/corelib/tools/qlocale.cpp2
-rw-r--r--src/corelib/tools/qtimezone.cpp997
-rw-r--r--src/corelib/tools/qtimezone.h188
-rw-r--r--src/corelib/tools/qtimezoneprivate.cpp926
-rw-r--r--src/corelib/tools/qtimezoneprivate_android.cpp257
-rw-r--r--src/corelib/tools/qtimezoneprivate_data_p.h1257
-rw-r--r--src/corelib/tools/qtimezoneprivate_icu.cpp508
-rw-r--r--src/corelib/tools/qtimezoneprivate_mac.mm333
-rw-r--r--src/corelib/tools/qtimezoneprivate_p.h493
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp1155
-rw-r--r--src/corelib/tools/qtimezoneprivate_win.cpp927
-rw-r--r--src/corelib/tools/tools.pri30
17 files changed, 1 insertions, 15691 deletions
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
deleted file mode 100644
index 9220d210f1..0000000000
--- a/src/corelib/tools/qdatetime.cpp
+++ /dev/null
@@ -1,5685 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-#include "private/qdatetime_p.h"
-#if QT_CONFIG(datetimeparser)
-#include "private/qdatetimeparser_p.h"
-#endif
-
-#include "qdatastream.h"
-#include "qset.h"
-#include "qlocale.h"
-#include "qdatetime.h"
-#if QT_CONFIG(timezone)
-#include "qtimezoneprivate_p.h"
-#endif
-#include "qregexp.h"
-#include "qdebug.h"
-#ifndef Q_OS_WIN
-#include <locale.h>
-#endif
-
-#include <cmath>
-#ifdef Q_CC_MINGW
-# include <unistd.h> // Define _POSIX_THREAD_SAFE_FUNCTIONS to obtain localtime_r()
-#endif
-#include <time.h>
-#ifdef Q_OS_WIN
-# include <qt_windows.h>
-# ifdef Q_OS_WINRT
-# include "qfunctions_winrt.h"
-# endif
-#endif
-
-#if defined(Q_OS_MAC)
-#include <private/qcore_mac_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-/*****************************************************************************
- Date/Time Constants
- *****************************************************************************/
-
-enum {
- SECS_PER_DAY = 86400,
- MSECS_PER_DAY = 86400000,
- SECS_PER_HOUR = 3600,
- MSECS_PER_HOUR = 3600000,
- SECS_PER_MIN = 60,
- MSECS_PER_MIN = 60000,
- TIME_T_MAX = 2145916799, // int maximum 2037-12-31T23:59:59 UTC
- JULIAN_DAY_FOR_EPOCH = 2440588 // result of julianDayFromDate(1970, 1, 1)
-};
-
-/*****************************************************************************
- QDate static helper functions
- *****************************************************************************/
-
-static inline QDate fixedDate(int y, int m, int d)
-{
- QDate result(y, m, 1);
- result.setDate(y, m, qMin(d, result.daysInMonth()));
- return result;
-}
-
-/*
- Division, rounding down (rather than towards zero).
-
- From C++11 onwards, integer division is defined to round towards zero, so we
- can rely on that when implementing this. This is only used with denominator b
- > 0, so we only have to treat negative numerator, a, specially.
- */
-static inline qint64 floordiv(qint64 a, int b)
-{
- return (a - (a < 0 ? b - 1 : 0)) / b;
-}
-
-static inline int floordiv(int a, int b)
-{
- return (a - (a < 0 ? b - 1 : 0)) / b;
-}
-
-static inline qint64 julianDayFromDate(int year, int month, int day)
-{
- // Adjust for no year 0
- if (year < 0)
- ++year;
-
-/*
- * Math from The Calendar FAQ at http://www.tondering.dk/claus/cal/julperiod.php
- * This formula is correct for all julian days, when using mathematical integer
- * division (round to negative infinity), not c++11 integer division (round to zero)
- */
- int a = floordiv(14 - month, 12);
- qint64 y = (qint64)year + 4800 - a;
- int m = month + 12 * a - 3;
- return day + floordiv(153 * m + 2, 5) + 365 * y + floordiv(y, 4) - floordiv(y, 100) + floordiv(y, 400) - 32045;
-}
-
-struct ParsedDate
-{
- int year, month, day;
-};
-
-// prevent this function from being inlined into all 10 users
-Q_NEVER_INLINE
-static ParsedDate getDateFromJulianDay(qint64 julianDay)
-{
-/*
- * Math from The Calendar FAQ at http://www.tondering.dk/claus/cal/julperiod.php
- * This formula is correct for all julian days, when using mathematical integer
- * division (round to negative infinity), not c++11 integer division (round to zero)
- */
- qint64 a = julianDay + 32044;
- qint64 b = floordiv(4 * a + 3, 146097);
- int c = a - floordiv(146097 * b, 4);
-
- int d = floordiv(4 * c + 3, 1461);
- int e = c - floordiv(1461 * d, 4);
- int m = floordiv(5 * e + 2, 153);
-
- int day = e - floordiv(153 * m + 2, 5) + 1;
- int month = m + 3 - 12 * floordiv(m, 10);
- int year = 100 * b + d - 4800 + floordiv(m, 10);
-
- // Adjust for no year 0
- if (year <= 0)
- --year ;
-
- return { year, month, day };
-}
-
-/*****************************************************************************
- Date/Time formatting helper functions
- *****************************************************************************/
-
-#if QT_CONFIG(textdate)
-static const char qt_shortMonthNames[][4] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-};
-
-static int qt_monthNumberFromShortName(QStringRef shortName)
-{
- for (unsigned int i = 0; i < sizeof(qt_shortMonthNames) / sizeof(qt_shortMonthNames[0]); ++i) {
- if (shortName == QLatin1String(qt_shortMonthNames[i], 3))
- return i + 1;
- }
- return -1;
-}
-static int qt_monthNumberFromShortName(const QString &shortName)
-{ return qt_monthNumberFromShortName(QStringRef(&shortName)); }
-
-static int fromShortMonthName(const QStringRef &monthName)
-{
- // Assume that English monthnames are the default
- int month = qt_monthNumberFromShortName(monthName);
- if (month != -1)
- return month;
- // If English names can't be found, search the localized ones
- for (int i = 1; i <= 12; ++i) {
- if (monthName == QLocale::system().monthName(i, QLocale::ShortFormat))
- return i;
- }
- return -1;
-}
-#endif // textdate
-
-#if QT_CONFIG(datestring)
-struct ParsedRfcDateTime {
- QDate date;
- QTime time;
- int utcOffset;
-};
-
-static ParsedRfcDateTime rfcDateImpl(const QString &s)
-{
- ParsedRfcDateTime result;
-
- // Matches "Wdy, dd Mon yyyy HH:mm:ss ±hhmm" (Wdy, being optional)
- QRegExp rex(QStringLiteral("^(?:[A-Z][a-z]+,)?[ \\t]*(\\d{1,2})[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d)(?::(\\d\\d))?)?[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?"));
- if (s.indexOf(rex) == 0) {
- const QStringList cap = rex.capturedTexts();
- result.date = QDate(cap[3].toInt(), qt_monthNumberFromShortName(cap[2]), cap[1].toInt());
- if (!cap[4].isEmpty())
- result.time = QTime(cap[4].toInt(), cap[5].toInt(), cap[6].toInt());
- const bool positiveOffset = (cap[7] == QLatin1String("+"));
- const int hourOffset = cap[8].toInt();
- const int minOffset = cap[9].toInt();
- result.utcOffset = ((hourOffset * 60 + minOffset) * (positiveOffset ? 60 : -60));
- } else {
- // Matches "Wdy Mon dd HH:mm:ss yyyy"
- QRegExp rex(QStringLiteral("^[A-Z][a-z]+[ \\t]+([A-Z][a-z]+)[ \\t]+(\\d\\d)(?:[ \\t]+(\\d\\d):(\\d\\d):(\\d\\d))?[ \\t]+(\\d\\d\\d\\d)[ \\t]*(?:([+-])(\\d\\d)(\\d\\d))?"));
- if (s.indexOf(rex) == 0) {
- const QStringList cap = rex.capturedTexts();
- result.date = QDate(cap[6].toInt(), qt_monthNumberFromShortName(cap[1]), cap[2].toInt());
- if (!cap[3].isEmpty())
- result.time = QTime(cap[3].toInt(), cap[4].toInt(), cap[5].toInt());
- const bool positiveOffset = (cap[7] == QLatin1String("+"));
- const int hourOffset = cap[8].toInt();
- const int minOffset = cap[9].toInt();
- result.utcOffset = ((hourOffset * 60 + minOffset) * (positiveOffset ? 60 : -60));
- }
- }
-
- return result;
-}
-#endif // datestring
-
-// Return offset in [+-]HH:mm format
-static QString toOffsetString(Qt::DateFormat format, int offset)
-{
- return QString::asprintf("%c%02d%s%02d",
- offset >= 0 ? '+' : '-',
- qAbs(offset) / SECS_PER_HOUR,
- // Qt::ISODate puts : between the hours and minutes, but Qt:TextDate does not:
- format == Qt::TextDate ? "" : ":",
- (qAbs(offset) / 60) % 60);
-}
-
-#if QT_CONFIG(datestring)
-// Parse offset in [+-]HH[[:]mm] format
-static int fromOffsetString(const QStringRef &offsetString, bool *valid) noexcept
-{
- *valid = false;
-
- const int size = offsetString.size();
- if (size < 2 || size > 6)
- return 0;
-
- // sign will be +1 for a positive and -1 for a negative offset
- int sign;
-
- // First char must be + or -
- const QChar signChar = offsetString.at(0);
- if (signChar == QLatin1Char('+'))
- sign = 1;
- else if (signChar == QLatin1Char('-'))
- sign = -1;
- else
- return 0;
-
- // Split the hour and minute parts
- const QStringRef time = offsetString.mid(1);
- int hhLen = time.indexOf(QLatin1Char(':'));
- int mmIndex;
- if (hhLen == -1)
- mmIndex = hhLen = 2; // [+-]HHmm or [+-]HH format
- else
- mmIndex = hhLen + 1;
-
- const QStringRef hhRef = time.left(hhLen);
- bool ok = false;
- const int hour = hhRef.toInt(&ok);
- if (!ok)
- return 0;
-
- const QStringRef mmRef = time.mid(mmIndex);
- const int minute = mmRef.isEmpty() ? 0 : mmRef.toInt(&ok);
- if (!ok || minute < 0 || minute > 59)
- return 0;
-
- *valid = true;
- return sign * ((hour * 60) + minute) * 60;
-}
-#endif // datestring
-
-static constexpr int daysInUsualMonth(int month) // (February isn't usual.)
-{
- // Long if odd up to July = 7, or if even from 8 = August onwards:
- return Q_ASSERT(month != 2 && month > 0 && month <= 12), 30 | ((month & 1) ^ (month >> 3));
-}
-
-/*****************************************************************************
- QDate member functions
- *****************************************************************************/
-
-/*!
- \since 4.5
-
- \enum QDate::MonthNameType
-
- This enum describes the types of the string representation used
- for the month name.
-
- \value DateFormat This type of name can be used for date-to-string formatting.
- \value StandaloneFormat This type is used when you need to enumerate months or weekdays.
- Usually standalone names are represented in singular forms with
- capitalized first letter.
-*/
-
-/*!
- \class QDate
- \inmodule QtCore
- \reentrant
- \brief The QDate class provides date functions.
-
-
- A QDate object encodes a calendar date, i.e. year, month, and day numbers,
- in the proleptic Gregorian calendar by default. It can read the current date
- from the system clock. It provides functions for comparing dates, and for
- manipulating dates. For example, it is possible to add and subtract days,
- months, and years to dates.
-
- A QDate object is typically created by giving the year, month, and day
- numbers explicitly. Note that QDate interprets two digit years as presented,
- i.e., as years 0 through 99, without adding any offset. A QDate can also be
- constructed with the static function currentDate(), which creates a QDate
- object containing the system clock's date. An explicit date can also be set
- using setDate(). The fromString() function returns a QDate given a string
- and a date format which is used to interpret the date within the string.
-
- The year(), month(), and day() functions provide access to the
- year, month, and day numbers. Also, dayOfWeek() and dayOfYear()
- functions are provided. The same information is provided in
- textual format by the toString(), shortDayName(), longDayName(),
- shortMonthName(), and longMonthName() functions.
-
- QDate provides a full set of operators to compare two QDate
- objects where smaller means earlier, and larger means later.
-
- You can increment (or decrement) a date by a given number of days
- using addDays(). Similarly you can use addMonths() and addYears().
- The daysTo() function returns the number of days between two
- dates.
-
- The daysInMonth() and daysInYear() functions return how many days
- there are in this date's month and year, respectively. The
- isLeapYear() function indicates whether a date is in a leap year.
-
- \section1 Remarks
-
- \section2 No Year 0
-
- There is no year 0. Dates in that year are considered invalid. The year -1
- is the year "1 before Christ" or "1 before current era." The day before 1
- January 1 CE, QDate(1, 1, 1), is 31 December 1 BCE, QDate(-1, 12, 31).
-
- \section2 Range of Valid Dates
-
- Dates are stored internally as a Julian Day number, an integer count of
- every day in a contiguous range, with 24 November 4714 BCE in the Gregorian
- calendar being Julian Day 0 (1 January 4713 BCE in the Julian calendar).
- As well as being an efficient and accurate way of storing an absolute date,
- it is suitable for converting a Date into other calendar systems such as
- Hebrew, Islamic or Chinese. The Julian Day number can be obtained using
- QDate::toJulianDay() and can be set using QDate::fromJulianDay().
-
- The range of dates able to be stored by QDate as a Julian Day number is
- for technical reasons limited to between -784350574879 and 784354017364,
- which means from before 2 billion BCE to after 2 billion CE.
-
- \sa QTime, QDateTime, QDateEdit, QDateTimeEdit, QCalendarWidget
-*/
-
-/*!
- \fn QDate::QDate()
-
- Constructs a null date. Null dates are invalid.
-
- \sa isNull(), isValid()
-*/
-
-/*!
- Constructs a date with year \a y, month \a m and day \a d.
-
- If the specified date is invalid, the date is not set and
- isValid() returns \c false.
-
- \warning Years 1 to 99 are interpreted as is. Year 0 is invalid.
-
- \sa isValid()
-*/
-
-QDate::QDate(int y, int m, int d)
-{
- setDate(y, m, d);
-}
-
-
-/*!
- \fn bool QDate::isNull() const
-
- Returns \c true if the date is null; otherwise returns \c false. A null
- date is invalid.
-
- \note The behavior of this function is equivalent to isValid().
-
- \sa isValid()
-*/
-
-/*!
- \fn bool QDate::isValid() const
-
- Returns \c true if this date is valid; otherwise returns \c false.
-
- \sa isNull()
-*/
-
-/*!
- Returns the year of this date. Negative numbers indicate years
- before 1 CE, such that year -44 is 44 BCE.
-
- Returns 0 if the date is invalid.
-
- \sa month(), day()
-*/
-
-int QDate::year() const
-{
- if (isNull())
- return 0;
-
- return getDateFromJulianDay(jd).year;
-}
-
-/*!
- Returns the number corresponding to the month of this date, using
- the following convention:
-
- \list
- \li 1 = "January"
- \li 2 = "February"
- \li 3 = "March"
- \li 4 = "April"
- \li 5 = "May"
- \li 6 = "June"
- \li 7 = "July"
- \li 8 = "August"
- \li 9 = "September"
- \li 10 = "October"
- \li 11 = "November"
- \li 12 = "December"
- \endlist
-
- Returns 0 if the date is invalid.
-
- \sa year(), day()
-*/
-
-int QDate::month() const
-{
- if (isNull())
- return 0;
-
- return getDateFromJulianDay(jd).month;
-}
-
-/*!
- Returns the day of the month (1 to 31) of this date.
-
- Returns 0 if the date is invalid.
-
- \sa year(), month(), dayOfWeek()
-*/
-
-int QDate::day() const
-{
- if (isNull())
- return 0;
-
- return getDateFromJulianDay(jd).day;
-}
-
-/*!
- Returns the weekday (1 = Monday to 7 = Sunday) for this date.
-
- Returns 0 if the date is invalid.
-
- \sa day(), dayOfYear(), Qt::DayOfWeek
-*/
-
-int QDate::dayOfWeek() const
-{
- if (isNull())
- return 0;
-
- if (jd >= 0)
- return (jd % 7) + 1;
- else
- return ((jd + 1) % 7) + 7;
-}
-
-/*!
- Returns the day of the year (1 to 365 or 366 on leap years) for
- this date.
-
- Returns 0 if the date is invalid.
-
- \sa day(), dayOfWeek()
-*/
-
-int QDate::dayOfYear() const
-{
- if (isNull())
- return 0;
-
- return jd - julianDayFromDate(year(), 1, 1) + 1;
-}
-
-/*!
- Returns the number of days in the month (28 to 31) for this date.
-
- Returns 0 if the date is invalid.
-
- \sa day(), daysInYear()
-*/
-
-int QDate::daysInMonth() const
-{
- if (isNull())
- return 0;
-
- const ParsedDate pd = getDateFromJulianDay(jd);
- if (pd.month == 2)
- return isLeapYear(pd.year) ? 29 : 28;
-
- return daysInUsualMonth(pd.month);
-}
-
-/*!
- Returns the number of days in the year (365 or 366) for this date.
-
- Returns 0 if the date is invalid.
-
- \sa day(), daysInMonth()
-*/
-
-int QDate::daysInYear() const
-{
- if (isNull())
- return 0;
-
- return isLeapYear(getDateFromJulianDay(jd).year) ? 366 : 365;
-}
-
-/*!
- Returns the week number (1 to 53), and stores the year in
- *\a{yearNumber} unless \a yearNumber is null (the default).
-
- Returns 0 if the date is invalid.
-
- In accordance with ISO 8601, weeks start on Monday and the first
- Thursday of a year is always in week 1 of that year. Most years
- have 52 weeks, but some have 53.
-
- *\a{yearNumber} is not always the same as year(). For example, 1
- January 2000 has week number 52 in the year 1999, and 31 December
- 2002 has week number 1 in the year 2003.
-
- \sa isValid()
-*/
-
-int QDate::weekNumber(int *yearNumber) const
-{
- if (!isValid())
- return 0;
-
- int year = QDate::year();
- int yday = dayOfYear();
- int wday = dayOfWeek();
-
- int week = (yday - wday + 10) / 7;
-
- if (week == 0) {
- // last week of previous year
- --year;
- week = (yday + 365 + (QDate::isLeapYear(year) ? 1 : 0) - wday + 10) / 7;
- Q_ASSERT(week == 52 || week == 53);
- } else if (week == 53) {
- // maybe first week of next year
- int w = (yday - 365 - (QDate::isLeapYear(year) ? 1 : 0) - wday + 10) / 7;
- if (w > 0) {
- ++year;
- week = w;
- }
- Q_ASSERT(week == 53 || week == 1);
- }
-
- if (yearNumber != 0)
- *yearNumber = year;
- return week;
-}
-
-static bool inDateTimeRange(qint64 jd, bool start)
-{
- using Bounds = std::numeric_limits<qint64>;
- if (jd < Bounds::min() + JULIAN_DAY_FOR_EPOCH)
- return false;
- jd -= JULIAN_DAY_FOR_EPOCH;
- const qint64 maxDay = Bounds::max() / MSECS_PER_DAY;
- const qint64 minDay = Bounds::min() / MSECS_PER_DAY - 1;
- // (Divisions rounded towards zero, as MSECS_PER_DAY has factors other than two.)
- // Range includes start of last day and end of first:
- if (start)
- return jd > minDay && jd <= maxDay;
- return jd >= minDay && jd < maxDay;
-}
-
-static QDateTime toEarliest(const QDate &day, const QDateTime &form)
-{
- const Qt::TimeSpec spec = form.timeSpec();
- const int offset = (spec == Qt::OffsetFromUTC) ? form.offsetFromUtc() : 0;
-#if QT_CONFIG(timezone)
- QTimeZone zone;
- if (spec == Qt::TimeZone)
- zone = form.timeZone();
-#endif
- auto moment = [=](QTime time) {
- switch (spec) {
- case Qt::OffsetFromUTC: return QDateTime(day, time, spec, offset);
-#if QT_CONFIG(timezone)
- case Qt::TimeZone: return QDateTime(day, time, zone);
-#endif
- default: return QDateTime(day, time, spec);
- }
- };
- // Longest routine time-zone transition is 2 hours:
- QDateTime when = moment(QTime(2, 0));
- if (!when.isValid()) {
- // Noon should be safe ...
- when = moment(QTime(12, 0));
- if (!when.isValid()) {
- // ... unless it's a 24-hour jump (moving the date-line)
- when = moment(QTime(23, 59, 59, 999));
- if (!when.isValid())
- return QDateTime();
- }
- }
- int high = when.time().msecsSinceStartOfDay() / 60000;
- int low = 0;
- // Binary chop to the right minute
- while (high > low + 1) {
- int mid = (high + low) / 2;
- QDateTime probe = moment(QTime(mid / 60, mid % 60));
- if (probe.isValid() && probe.date() == day) {
- high = mid;
- when = probe;
- } else {
- low = mid;
- }
- }
- return when;
-}
-
-/*!
- \since 5.14
- \fn QDateTime QDate::startOfDay(Qt::TimeSpec spec, int offsetSeconds) const
- \fn QDateTime QDate::startOfDay(const QTimeZone &zone) const
-
- Returns the start-moment of the day. Usually, this shall be midnight at the
- start of the day: however, if a time-zone transition causes the given date
- to skip over that midnight (e.g. a DST spring-forward skipping from the end
- of the previous day to 01:00 of the new day), the actual earliest time in
- the day is returned. This can only arise when the start-moment is specified
- in terms of a time-zone (by passing its QTimeZone as \a zone) or in terms of
- local time (by passing Qt::LocalTime as \a spec; this is its default).
-
- The \a offsetSeconds is ignored unless \a spec is Qt::OffsetFromUTC, when it
- gives the implied zone's offset from UTC. As UTC and such zones have no
- transitions, the start of the day is QTime(0, 0) in these cases.
-
- In the rare case of a date that was entirely skipped (this happens when a
- zone east of the international date-line switches to being west of it), the
- return shall be invalid. Passing Qt::TimeZone as \a spec (instead of
- passing a QTimeZone) or passing an invalid time-zone as \a zone will also
- produce an invalid result, as shall dates that start outside the range
- representable by QDateTime.
-
- \sa endOfDay()
-*/
-QDateTime QDate::startOfDay(Qt::TimeSpec spec, int offsetSeconds) const
-{
- if (!inDateTimeRange(jd, true))
- return QDateTime();
-
- switch (spec) {
- case Qt::TimeZone: // should pass a QTimeZone instead of Qt::TimeZone
- qWarning() << "Called QDate::startOfDay(Qt::TimeZone) on" << *this;
- return QDateTime();
- case Qt::OffsetFromUTC:
- case Qt::UTC:
- return QDateTime(*this, QTime(0, 0), spec, offsetSeconds);
-
- case Qt::LocalTime:
- if (offsetSeconds)
- qWarning("Ignoring offset (%d seconds) passed with Qt::LocalTime", offsetSeconds);
- break;
- }
- QDateTime when(*this, QTime(0, 0), spec);
- if (!when.isValid())
- when = toEarliest(*this, when);
-
- return when.isValid() ? when : QDateTime();
-}
-
-#if QT_CONFIG(timezone)
-/*!
- \overload
- \since 5.14
-*/
-QDateTime QDate::startOfDay(const QTimeZone &zone) const
-{
- if (!inDateTimeRange(jd, true) || !zone.isValid())
- return QDateTime();
-
- QDateTime when(*this, QTime(0, 0), zone);
- if (when.isValid())
- return when;
-
- // The start of the day must have fallen in a spring-forward's gap; find the spring-forward:
- if (zone.hasTransitions()) {
- QTimeZone::OffsetData tran = zone.previousTransition(QDateTime(*this, QTime(23, 59, 59, 999), zone));
- const QDateTime &at = tran.atUtc.toTimeZone(zone);
- if (at.isValid() && at.date() == *this)
- return at;
- }
-
- when = toEarliest(*this, when);
- return when.isValid() ? when : QDateTime();
-}
-#endif // timezone
-
-static QDateTime toLatest(const QDate &day, const QDateTime &form)
-{
- const Qt::TimeSpec spec = form.timeSpec();
- const int offset = (spec == Qt::OffsetFromUTC) ? form.offsetFromUtc() : 0;
-#if QT_CONFIG(timezone)
- QTimeZone zone;
- if (spec == Qt::TimeZone)
- zone = form.timeZone();
-#endif
- auto moment = [=](QTime time) {
- switch (spec) {
- case Qt::OffsetFromUTC: return QDateTime(day, time, spec, offset);
-#if QT_CONFIG(timezone)
- case Qt::TimeZone: return QDateTime(day, time, zone);
-#endif
- default: return QDateTime(day, time, spec);
- }
- };
- // Longest routine time-zone transition is 2 hours:
- QDateTime when = moment(QTime(21, 59, 59, 999));
- if (!when.isValid()) {
- // Noon should be safe ...
- when = moment(QTime(12, 0));
- if (!when.isValid()) {
- // ... unless it's a 24-hour jump (moving the date-line)
- when = moment(QTime(0, 0));
- if (!when.isValid())
- return QDateTime();
- }
- }
- int high = 24 * 60;
- int low = when.time().msecsSinceStartOfDay() / 60000;
- // Binary chop to the right minute
- while (high > low + 1) {
- int mid = (high + low) / 2;
- QDateTime probe = moment(QTime(mid / 60, mid % 60, 59, 999));
- if (probe.isValid() && probe.date() == day) {
- low = mid;
- when = probe;
- } else {
- high = mid;
- }
- }
- return when;
-}
-
-/*!
- \since 5.14
- \fn QDateTime QDate::endOfDay(Qt::TimeSpec spec, int offsetSeconds) const
- \fn QDateTime QDate::endOfDay(const QTimeZone &zone) const
-
- Returns the end-moment of the day. Usually, this is one millisecond before
- the midnight at the end of the day: however, if a time-zone transition
- causes the given date to skip over that midnight (e.g. a DST spring-forward
- skipping from just before 23:00 to the start of the next day), the actual
- latest time in the day is returned. This can only arise when the
- start-moment is specified in terms of a time-zone (by passing its QTimeZone
- as \a zone) or in terms of local time (by passing Qt::LocalTime as \a spec;
- this is its default).
-
- The \a offsetSeconds is ignored unless \a spec is Qt::OffsetFromUTC, when it
- gives the implied zone's offset from UTC. As UTC and such zones have no
- transitions, the end of the day is QTime(23, 59, 59, 999) in these cases.
-
- In the rare case of a date that was entirely skipped (this happens when a
- zone east of the international date-line switches to being west of it), the
- return shall be invalid. Passing Qt::TimeZone as \a spec (instead of
- passing a QTimeZone) will also produce an invalid result, as shall dates
- that end outside the range representable by QDateTime.
-
- \sa startOfDay()
-*/
-QDateTime QDate::endOfDay(Qt::TimeSpec spec, int offsetSeconds) const
-{
- if (!inDateTimeRange(jd, false))
- return QDateTime();
-
- switch (spec) {
- case Qt::TimeZone: // should pass a QTimeZone instead of Qt::TimeZone
- qWarning() << "Called QDate::endOfDay(Qt::TimeZone) on" << *this;
- return QDateTime();
- case Qt::UTC:
- case Qt::OffsetFromUTC:
- return QDateTime(*this, QTime(23, 59, 59, 999), spec, offsetSeconds);
-
- case Qt::LocalTime:
- if (offsetSeconds)
- qWarning("Ignoring offset (%d seconds) passed with Qt::LocalTime", offsetSeconds);
- break;
- }
- QDateTime when(*this, QTime(23, 59, 59, 999), spec);
- if (!when.isValid())
- when = toLatest(*this, when);
- return when.isValid() ? when : QDateTime();
-}
-
-#if QT_CONFIG(timezone)
-/*!
- \overload
- \since 5.14
-*/
-QDateTime QDate::endOfDay(const QTimeZone &zone) const
-{
- if (!inDateTimeRange(jd, false) || !zone.isValid())
- return QDateTime();
-
- QDateTime when(*this, QTime(23, 59, 59, 999), zone);
- if (when.isValid())
- return when;
-
- // The end of the day must have fallen in a spring-forward's gap; find the spring-forward:
- if (zone.hasTransitions()) {
- QTimeZone::OffsetData tran = zone.nextTransition(QDateTime(*this, QTime(0, 0), zone));
- const QDateTime &at = tran.atUtc.toTimeZone(zone);
- if (at.isValid() && at.date() == *this)
- return at;
- }
-
- when = toLatest(*this, when);
- return when.isValid() ? when : QDateTime();
-}
-#endif // timezone
-
-#if QT_DEPRECATED_SINCE(5, 11) && QT_CONFIG(textdate)
-
-/*!
- \since 4.5
- \deprecated
-
- Returns the short name of the \a month for the representation specified
- by \a type.
-
- The months are enumerated using the following convention:
-
- \list
- \li 1 = "Jan"
- \li 2 = "Feb"
- \li 3 = "Mar"
- \li 4 = "Apr"
- \li 5 = "May"
- \li 6 = "Jun"
- \li 7 = "Jul"
- \li 8 = "Aug"
- \li 9 = "Sep"
- \li 10 = "Oct"
- \li 11 = "Nov"
- \li 12 = "Dec"
- \endlist
-
- The month names will be localized according to the system's
- locale settings, i.e. using QLocale::system().
-
- Returns an empty string if the date is invalid.
-
- \sa toString(), longMonthName(), shortDayName(), longDayName()
-*/
-
-QString QDate::shortMonthName(int month, QDate::MonthNameType type)
-{
- switch (type) {
- case QDate::DateFormat:
- return QLocale::system().monthName(month, QLocale::ShortFormat);
- case QDate::StandaloneFormat:
- return QLocale::system().standaloneMonthName(month, QLocale::ShortFormat);
- }
- return QString();
-}
-
-/*!
- \since 4.5
- \deprecated
-
- Returns the long name of the \a month for the representation specified
- by \a type.
-
- The months are enumerated using the following convention:
-
- \list
- \li 1 = "January"
- \li 2 = "February"
- \li 3 = "March"
- \li 4 = "April"
- \li 5 = "May"
- \li 6 = "June"
- \li 7 = "July"
- \li 8 = "August"
- \li 9 = "September"
- \li 10 = "October"
- \li 11 = "November"
- \li 12 = "December"
- \endlist
-
- The month names will be localized according to the system's
- locale settings, i.e. using QLocale::system().
-
- Returns an empty string if the date is invalid.
-
- \sa toString(), shortMonthName(), shortDayName(), longDayName()
-*/
-
-QString QDate::longMonthName(int month, MonthNameType type)
-{
- switch (type) {
- case QDate::DateFormat:
- return QLocale::system().monthName(month, QLocale::LongFormat);
- case QDate::StandaloneFormat:
- return QLocale::system().standaloneMonthName(month, QLocale::LongFormat);
- }
- return QString();
-}
-
-/*!
- \since 4.5
- \deprecated
-
- Returns the short name of the \a weekday for the representation specified
- by \a type.
-
- The days are enumerated using the following convention:
-
- \list
- \li 1 = "Mon"
- \li 2 = "Tue"
- \li 3 = "Wed"
- \li 4 = "Thu"
- \li 5 = "Fri"
- \li 6 = "Sat"
- \li 7 = "Sun"
- \endlist
-
- The day names will be localized according to the system's
- locale settings, i.e. using QLocale::system().
-
- Returns an empty string if the date is invalid.
-
- \sa toString(), shortMonthName(), longMonthName(), longDayName()
-*/
-
-QString QDate::shortDayName(int weekday, MonthNameType type)
-{
- switch (type) {
- case QDate::DateFormat:
- return QLocale::system().dayName(weekday, QLocale::ShortFormat);
- case QDate::StandaloneFormat:
- return QLocale::system().standaloneDayName(weekday, QLocale::ShortFormat);
- }
- return QString();
-}
-
-/*!
- \since 4.5
- \deprecated
-
- Returns the long name of the \a weekday for the representation specified
- by \a type.
-
- The days are enumerated using the following convention:
-
- \list
- \li 1 = "Monday"
- \li 2 = "Tuesday"
- \li 3 = "Wednesday"
- \li 4 = "Thursday"
- \li 5 = "Friday"
- \li 6 = "Saturday"
- \li 7 = "Sunday"
- \endlist
-
- The day names will be localized according to the system's
- locale settings, i.e. using QLocale::system().
-
- Returns an empty string if the date is invalid.
-
- \sa toString(), shortDayName(), shortMonthName(), longMonthName()
-*/
-
-QString QDate::longDayName(int weekday, MonthNameType type)
-{
- switch (type) {
- case QDate::DateFormat:
- return QLocale::system().dayName(weekday, QLocale::LongFormat);
- case QDate::StandaloneFormat:
- return QLocale::system().standaloneDayName(weekday, QLocale::LongFormat);
- }
- return QString();
-}
-#endif // textdate && deprecated
-
-#if QT_CONFIG(datestring)
-
-#if QT_CONFIG(textdate)
-static QString toStringTextDate(QDate date)
-{
- const ParsedDate pd = getDateFromJulianDay(date.toJulianDay());
- static const QLatin1Char sp(' ');
- return QLocale::system().dayName(date.dayOfWeek(), QLocale::ShortFormat) + sp
- + QLocale::system().monthName(pd.month, QLocale::ShortFormat) + sp
- + QString::number(pd.day) + sp
- + QString::number(pd.year);
-}
-#endif // textdate
-
-static QString toStringIsoDate(qint64 jd)
-{
- const ParsedDate pd = getDateFromJulianDay(jd);
- if (pd.year >= 0 && pd.year <= 9999)
- return QString::asprintf("%04d-%02d-%02d", pd.year, pd.month, pd.day);
- else
- return QString();
-}
-
-/*!
- \fn QString QDate::toString(Qt::DateFormat format) const
-
- \overload
-
- Returns the date as a string. The \a format parameter determines
- the format of the string.
-
- If the \a format is Qt::TextDate, the string is formatted in
- the default way. QDate::shortDayName() and QDate::shortMonthName()
- are used to generate the string, so the day and month names will
- be localized names using the system locale, i.e. QLocale::system(). An
- example of this formatting is "Sat May 20 1995".
-
- If the \a format is Qt::ISODate, the string format corresponds
- to the ISO 8601 extended specification for representations of
- dates and times, taking the form yyyy-MM-dd, where yyyy is the
- year, MM is the month of the year (between 01 and 12), and dd is
- the day of the month between 01 and 31.
-
- If the \a format is Qt::SystemLocaleShortDate or
- Qt::SystemLocaleLongDate, the string format depends on the locale
- settings of the system. Identical to calling
- QLocale::system().toString(date, QLocale::ShortFormat) or
- QLocale::system().toString(date, QLocale::LongFormat).
-
- If the \a format is Qt::DefaultLocaleShortDate or
- Qt::DefaultLocaleLongDate, the string format depends on the
- default application locale. This is the locale set with
- QLocale::setDefault(), or the system locale if no default locale
- has been set. Identical to calling
- \l {QLocale::toString()}{QLocale().toString(date, QLocale::ShortFormat) } or
- \l {QLocale::toString()}{QLocale().toString(date, QLocale::LongFormat)}.
-
- If the \a format is Qt::RFC2822Date, the string is formatted in
- an \l{RFC 2822} compatible way. An example of this formatting is
- "20 May 1995".
-
- If the date is invalid, an empty string will be returned.
-
- \warning The Qt::ISODate format is only valid for years in the
- range 0 to 9999. This restriction may apply to locale-aware
- formats as well, depending on the locale settings.
-
- \sa fromString(), shortDayName(), shortMonthName(), QLocale::toString()
-*/
-QString QDate::toString(Qt::DateFormat format) const
-{
- if (!isValid())
- return QString();
-
- switch (format) {
- case Qt::SystemLocaleDate:
- case Qt::SystemLocaleShortDate:
- return QLocale::system().toString(*this, QLocale::ShortFormat);
- case Qt::SystemLocaleLongDate:
- return QLocale::system().toString(*this, QLocale::LongFormat);
- case Qt::LocaleDate:
- case Qt::DefaultLocaleShortDate:
- return QLocale().toString(*this, QLocale::ShortFormat);
- case Qt::DefaultLocaleLongDate:
- return QLocale().toString(*this, QLocale::LongFormat);
- case Qt::RFC2822Date:
- return QLocale::c().toString(*this, QStringViewLiteral("dd MMM yyyy"));
- default:
-#if QT_CONFIG(textdate)
- case Qt::TextDate:
- return toStringTextDate(*this);
-#endif
- case Qt::ISODate:
- case Qt::ISODateWithMs:
- return toStringIsoDate(jd);
- }
-}
-
-/*!
- \fn QString QDate::toString(const QString &format) const
- \fn QString QDate::toString(QStringView format) const
-
- Returns the date as a string. The \a format parameter determines
- the format of the result string.
-
- These expressions may be used:
-
- \table
- \header \li Expression \li Output
- \row \li d \li the day as number without a leading zero (1 to 31)
- \row \li dd \li the day as number with a leading zero (01 to 31)
- \row \li ddd
- \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li dddd
- \li the long localized day name (e.g. 'Monday' to 'Sunday').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li M \li the month as number without a leading zero (1 to 12)
- \row \li MM \li the month as number with a leading zero (01 to 12)
- \row \li MMM
- \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li MMMM
- \li the long localized month name (e.g. 'January' to 'December').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li yy \li the year as two digit number (00 to 99)
- \row \li yyyy \li the year as four digit number. If the year is negative,
- a minus sign is prepended in addition.
- \endtable
-
- Any sequence of characters enclosed in single quotes will be included
- verbatim in the output string (stripped of the quotes), even if it contains
- formatting characters. Two consecutive single quotes ("''") are replaced by
- a single quote in the output. All other characters in the format string are
- included verbatim in the output string.
-
- Formats without separators (e.g. "ddMM") are supported but must be used with
- care, as the resulting strings aren't always reliably readable (e.g. if "dM"
- produces "212" it could mean either the 2nd of December or the 21st of
- February).
-
- Example format strings (assuming that the QDate is the 20 July
- 1969):
-
- \table
- \header \li Format \li Result
- \row \li dd.MM.yyyy \li 20.07.1969
- \row \li ddd MMMM d yy \li Sun July 20 69
- \row \li 'The day is' dddd \li The day is Sunday
- \endtable
-
- If the datetime is invalid, an empty string will be returned.
-
- \sa fromString(), QDateTime::toString(), QTime::toString(), QLocale::toString()
-
-*/
-QString QDate::toString(QStringView format) const
-{
- return QLocale::system().toString(*this, format); // QLocale::c() ### Qt6
-}
-
-#if QT_STRINGVIEW_LEVEL < 2
-QString QDate::toString(const QString &format) const
-{
- return toString(qToStringViewIgnoringNull(format));
-}
-#endif
-
-#endif // datestring
-
-/*!
- \fn bool QDate::setYMD(int y, int m, int d)
-
- \deprecated in 5.0, use setDate() instead.
-
- Sets the date's year \a y, month \a m, and day \a d.
-
- If \a y is in the range 0 to 99, it is interpreted as 1900 to
- 1999.
- Returns \c false if the date is invalid.
-
- Use setDate() instead.
-*/
-
-/*!
- \since 4.2
-
- Sets the date's \a year, \a month, and \a day. Returns \c true if
- the date is valid; otherwise returns \c false.
-
- If the specified date is invalid, the QDate object is set to be
- invalid.
-
- \sa isValid()
-*/
-bool QDate::setDate(int year, int month, int day)
-{
- if (isValid(year, month, day))
- jd = julianDayFromDate(year, month, day);
- else
- jd = nullJd();
-
- return isValid();
-}
-
-/*!
- \since 4.5
-
- Extracts the date's year, month, and day, and assigns them to
- *\a year, *\a month, and *\a day. The pointers may be null.
-
- Returns 0 if the date is invalid.
-
- \note In Qt versions prior to 5.7, this function is marked as non-\c{const}.
-
- \sa year(), month(), day(), isValid()
-*/
-void QDate::getDate(int *year, int *month, int *day) const
-{
- ParsedDate pd = { 0, 0, 0 };
- if (isValid())
- pd = getDateFromJulianDay(jd);
-
- if (year)
- *year = pd.year;
- if (month)
- *month = pd.month;
- if (day)
- *day = pd.day;
-}
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-/*!
- \overload
- \internal
-*/
-void QDate::getDate(int *year, int *month, int *day)
-{
- qAsConst(*this).getDate(year, month, day);
-}
-#endif // < Qt 6
-
-/*!
- Returns a QDate object containing a date \a ndays later than the
- date of this object (or earlier if \a ndays is negative).
-
- Returns a null date if the current date is invalid or the new date is
- out of range.
-
- \sa addMonths(), addYears(), daysTo()
-*/
-
-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);
-}
-
-/*!
- Returns a QDate object containing a date \a nmonths later than the
- date of this object (or earlier if \a nmonths is negative).
-
- \note If the ending day/month combination does not exist in the
- resulting month/year, this function will return a date that is the
- latest valid date.
-
- \sa addDays(), addYears()
-*/
-
-QDate QDate::addMonths(int nmonths) const
-{
- if (!isValid())
- return QDate();
- if (!nmonths)
- return *this;
-
- int old_y, y, m, d;
- {
- const ParsedDate pd = getDateFromJulianDay(jd);
- y = pd.year;
- m = pd.month;
- d = pd.day;
- }
- old_y = y;
-
- bool increasing = nmonths > 0;
-
- while (nmonths != 0) {
- if (nmonths < 0 && nmonths + 12 <= 0) {
- y--;
- nmonths+=12;
- } else if (nmonths < 0) {
- m+= nmonths;
- nmonths = 0;
- if (m <= 0) {
- --y;
- m += 12;
- }
- } else if (nmonths - 12 >= 0) {
- y++;
- nmonths -= 12;
- } else if (m == 12) {
- y++;
- m = 0;
- } else {
- m += nmonths;
- nmonths = 0;
- if (m > 12) {
- ++y;
- m -= 12;
- }
- }
- }
-
- // was there a sign change?
- if ((old_y > 0 && y <= 0) ||
- (old_y < 0 && y >= 0))
- // yes, adjust the date by +1 or -1 years
- y += increasing ? +1 : -1;
-
- return fixedDate(y, m, d);
-}
-
-/*!
- Returns a QDate object containing a date \a nyears later than the
- date of this object (or earlier if \a nyears is negative).
-
- \note If the ending day/month combination does not exist in the
- resulting year (i.e., if the date was Feb 29 and the final year is
- not a leap year), this function will return a date that is the
- latest valid date (that is, Feb 28).
-
- \sa addDays(), addMonths()
-*/
-
-QDate QDate::addYears(int nyears) const
-{
- if (!isValid())
- return QDate();
-
- ParsedDate pd = getDateFromJulianDay(jd);
-
- int old_y = pd.year;
- pd.year += nyears;
-
- // was there a sign change?
- if ((old_y > 0 && pd.year <= 0) ||
- (old_y < 0 && pd.year >= 0))
- // yes, adjust the date by +1 or -1 years
- pd.year += nyears > 0 ? +1 : -1;
-
- return fixedDate(pd.year, pd.month, pd.day);
-}
-
-/*!
- Returns the number of days from this date to \a d (which is
- negative if \a d is earlier than this date).
-
- Returns 0 if either date is invalid.
-
- Example:
- \snippet code/src_corelib_tools_qdatetime.cpp 0
-
- \sa addDays()
-*/
-
-qint64 QDate::daysTo(const QDate &d) const
-{
- if (isNull() || d.isNull())
- return 0;
-
- // Due to limits on minJd() and maxJd() we know this will never overflow
- return d.jd - jd;
-}
-
-
-/*!
- \fn bool QDate::operator==(const QDate &d) const
-
- Returns \c true if this date is equal to \a d; otherwise returns
- false.
-
-*/
-
-/*!
- \fn bool QDate::operator!=(const QDate &d) const
-
- Returns \c true if this date is different from \a d; otherwise
- returns \c false.
-*/
-
-/*!
- \fn bool QDate::operator<(const QDate &d) const
-
- Returns \c true if this date is earlier than \a d; otherwise returns
- false.
-*/
-
-/*!
- \fn bool QDate::operator<=(const QDate &d) const
-
- Returns \c true if this date is earlier than or equal to \a d;
- otherwise returns \c false.
-*/
-
-/*!
- \fn bool QDate::operator>(const QDate &d) const
-
- Returns \c true if this date is later than \a d; otherwise returns
- false.
-*/
-
-/*!
- \fn bool QDate::operator>=(const QDate &d) const
-
- Returns \c true if this date is later than or equal to \a d;
- otherwise returns \c false.
-*/
-
-/*!
- \fn QDate::currentDate()
- Returns the current date, as reported by the system clock.
-
- \sa QTime::currentTime(), QDateTime::currentDateTime()
-*/
-
-#if QT_CONFIG(datestring)
-/*!
- Returns the QDate represented by the \a string, using the
- \a format given, or an invalid date if the string cannot be
- parsed.
-
- Note for Qt::TextDate: It is recommended that you use the
- English short month names (e.g. "Jan"). Although localized month
- names can also be used, they depend on the user's locale settings.
-
- \sa toString(), QLocale::toDate()
-*/
-
-QDate QDate::fromString(const QString &string, Qt::DateFormat format)
-{
- if (string.isEmpty())
- return QDate();
-
- switch (format) {
- case Qt::SystemLocaleDate:
- case Qt::SystemLocaleShortDate:
- return QLocale::system().toDate(string, QLocale::ShortFormat);
- case Qt::SystemLocaleLongDate:
- return QLocale::system().toDate(string, QLocale::LongFormat);
- case Qt::LocaleDate:
- case Qt::DefaultLocaleShortDate:
- return QLocale().toDate(string, QLocale::ShortFormat);
- case Qt::DefaultLocaleLongDate:
- return QLocale().toDate(string, QLocale::LongFormat);
- case Qt::RFC2822Date:
- return rfcDateImpl(string).date;
- default:
-#if QT_CONFIG(textdate)
- case Qt::TextDate: {
- QVector<QStringRef> parts = string.splitRef(QLatin1Char(' '), QString::SkipEmptyParts);
-
- if (parts.count() != 4)
- return QDate();
-
- QStringRef monthName = parts.at(1);
- const int month = fromShortMonthName(monthName);
- if (month == -1) {
- // Month name matches neither English nor other localised name.
- return QDate();
- }
-
- bool ok = false;
- int year = parts.at(3).toInt(&ok);
- if (!ok)
- return QDate();
-
- return QDate(year, month, parts.at(2).toInt());
- }
-#endif // textdate
- case Qt::ISODate: {
- // Semi-strict parsing, must be long enough and have non-numeric separators
- if (string.size() < 10 || string.at(4).isDigit() || string.at(7).isDigit()
- || (string.size() > 10 && string.at(10).isDigit())) {
- return QDate();
- }
- const int year = string.midRef(0, 4).toInt();
- if (year <= 0 || year > 9999)
- return QDate();
- return QDate(year, string.midRef(5, 2).toInt(), string.midRef(8, 2).toInt());
- }
- }
- return QDate();
-}
-
-/*!
- Returns the QDate represented by the \a string, using the \a
- format given, or an invalid date if the string cannot be parsed.
-
- These expressions may be used for the format:
-
- \table
- \header \li Expression \li Output
- \row \li d \li The day as a number without a leading zero (1 to 31)
- \row \li dd \li The day as a number with a leading zero (01 to 31)
- \row \li ddd
- \li The abbreviated localized day name (e.g. 'Mon' to 'Sun').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li dddd
- \li The long localized day name (e.g. 'Monday' to 'Sunday').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li M \li The month as a number without a leading zero (1 to 12)
- \row \li MM \li The month as a number with a leading zero (01 to 12)
- \row \li MMM
- \li The abbreviated localized month name (e.g. 'Jan' to 'Dec').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li MMMM
- \li The long localized month name (e.g. 'January' to 'December').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li yy \li The year as two digit number (00 to 99)
- \row \li yyyy \li The year as four digit number. If the year is negative,
- a minus sign is prepended in addition.
- \endtable
-
- All other input characters will be treated as text. Any sequence
- of characters that are enclosed in single quotes will also be
- treated as text and will not be used as an expression. For example:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 1
-
- If the format is not satisfied, an invalid QDate is returned. The
- expressions that don't expect leading zeroes (d, M) will be
- greedy. This means that they will use two digits even if this
- will put them outside the accepted range of values and leaves too
- few digits for other sections. For example, the following format
- string could have meant January 30 but the M will grab two
- digits, resulting in an invalid date:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 2
-
- For any field that is not represented in the format the following
- defaults are used:
-
- \table
- \header \li Field \li Default value
- \row \li Year \li 1900
- \row \li Month \li 1
- \row \li Day \li 1
- \endtable
-
- The following examples demonstrate the default values:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 3
-
- \sa toString(), QDateTime::fromString(), QTime::fromString(),
- QLocale::toDate()
-*/
-
-QDate QDate::fromString(const QString &string, const QString &format)
-{
- QDate date;
-#if QT_CONFIG(datetimeparser)
- QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
- // dt.setDefaultLocale(QLocale::c()); ### Qt 6
- if (dt.parseFormat(format))
- dt.fromString(string, &date, 0);
-#else
- Q_UNUSED(string);
- Q_UNUSED(format);
-#endif
- return date;
-}
-#endif // datestring
-
-/*!
- \overload
-
- Returns \c true if the specified date (\a year, \a month, and \a
- day) is valid; otherwise returns \c false.
-
- Example:
- \snippet code/src_corelib_tools_qdatetime.cpp 4
-
- \sa isNull(), setDate()
-*/
-
-bool QDate::isValid(int year, int month, int day)
-{
- // There is no year 0 in the Gregorian calendar.
- return year && day > 0 && month > 0 && month <= 12 &&
- day <= (month == 2 ? isLeapYear(year) ? 29 : 28 : daysInUsualMonth(month));
-}
-
-/*!
- \fn bool QDate::isLeapYear(int year)
-
- Returns \c true if the specified \a year is a leap year; otherwise
- returns \c false.
-*/
-
-bool QDate::isLeapYear(int y)
-{
- // No year 0 in Gregorian calendar, so -1, -5, -9 etc are leap years
- if ( y < 1)
- ++y;
-
- return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
-}
-
-/*! \fn static QDate QDate::fromJulianDay(qint64 jd)
-
- Converts the Julian day \a jd to a QDate.
-
- \sa toJulianDay()
-*/
-
-/*! \fn int QDate::toJulianDay() const
-
- Converts the date to a Julian day.
-
- \sa fromJulianDay()
-*/
-
-/*****************************************************************************
- QTime member functions
- *****************************************************************************/
-
-/*!
- \class QTime
- \inmodule QtCore
- \reentrant
-
- \brief The QTime class provides clock time functions.
-
-
- A QTime object contains a clock time, which it can express as the numbers of
- hours, minutes, seconds, and milliseconds since midnight. It provides
- functions for comparing times and for manipulating a time by adding a number
- of milliseconds.
-
- QTime uses the 24-hour clock format; it has no concept of AM/PM.
- Unlike QDateTime, QTime knows nothing about time zones or
- daylight-saving time (DST).
-
- A QTime object is typically created either by giving the number
- of hours, minutes, seconds, and milliseconds explicitly, or by
- using the static function currentTime(), which creates a QTime
- object that contains the system's local time. Note that the
- accuracy depends on the accuracy of the underlying operating
- system; not all systems provide 1-millisecond accuracy.
-
- The hour(), minute(), second(), and msec() functions provide
- access to the number of hours, minutes, seconds, and milliseconds
- of the time. The same information is provided in textual format by
- the toString() function.
-
- The addSecs() and addMSecs() functions provide the time a given
- number of seconds or milliseconds later than a given time.
- Correspondingly, the number of seconds or milliseconds
- between two times can be found using secsTo() or msecsTo().
-
- QTime provides a full set of operators to compare two QTime
- objects; an earlier time is considered smaller than a later one;
- if A.msecsTo(B) is positive, then A < B.
-
- \sa QDate, QDateTime
-*/
-
-/*!
- \fn QTime::QTime()
-
- Constructs a null time object. For a null time, isNull() returns \c true and
- isValid() returns \c false. If you need a zero time, use QTime(0, 0). For
- the start of a day, see QDate::startOfDay().
-
- \sa isNull(), isValid()
-*/
-
-/*!
- Constructs a time with hour \a h, minute \a m, seconds \a s and
- milliseconds \a ms.
-
- \a h must be in the range 0 to 23, \a m and \a s must be in the
- range 0 to 59, and \a ms must be in the range 0 to 999.
-
- \sa isValid()
-*/
-
-QTime::QTime(int h, int m, int s, int ms)
-{
- setHMS(h, m, s, ms);
-}
-
-
-/*!
- \fn bool QTime::isNull() const
-
- Returns \c true if the time is null (i.e., the QTime object was
- constructed using the default constructor); otherwise returns
- false. A null time is also an invalid time.
-
- \sa isValid()
-*/
-
-/*!
- Returns \c true if the time is valid; otherwise returns \c false. For example,
- the time 23:30:55.746 is valid, but 24:12:30 is invalid.
-
- \sa isNull()
-*/
-
-bool QTime::isValid() const
-{
- return mds > NullTime && mds < MSECS_PER_DAY;
-}
-
-
-/*!
- Returns the hour part (0 to 23) of the time.
-
- Returns -1 if the time is invalid.
-
- \sa minute(), second(), msec()
-*/
-
-int QTime::hour() const
-{
- if (!isValid())
- return -1;
-
- return ds() / MSECS_PER_HOUR;
-}
-
-/*!
- Returns the minute part (0 to 59) of the time.
-
- Returns -1 if the time is invalid.
-
- \sa hour(), second(), msec()
-*/
-
-int QTime::minute() const
-{
- if (!isValid())
- return -1;
-
- return (ds() % MSECS_PER_HOUR) / MSECS_PER_MIN;
-}
-
-/*!
- Returns the second part (0 to 59) of the time.
-
- Returns -1 if the time is invalid.
-
- \sa hour(), minute(), msec()
-*/
-
-int QTime::second() const
-{
- if (!isValid())
- return -1;
-
- return (ds() / 1000)%SECS_PER_MIN;
-}
-
-/*!
- Returns the millisecond part (0 to 999) of the time.
-
- Returns -1 if the time is invalid.
-
- \sa hour(), minute(), second()
-*/
-
-int QTime::msec() const
-{
- if (!isValid())
- return -1;
-
- return ds() % 1000;
-}
-
-#if QT_CONFIG(datestring)
-/*!
- \overload
-
- Returns the time as a string. The \a format parameter determines
- the format of the string.
-
- If \a format is Qt::TextDate, the string format is HH:mm:ss;
- e.g. 1 second before midnight would be "23:59:59".
-
- If \a format is Qt::ISODate, the string format corresponds to the
- ISO 8601 extended specification for representations of dates,
- represented by HH:mm:ss. To include milliseconds in the ISO 8601
- date, use the \a format Qt::ISODateWithMs, which corresponds to
- HH:mm:ss.zzz.
-
- If the \a format is Qt::SystemLocaleShortDate or
- Qt::SystemLocaleLongDate, the string format depends on the locale
- settings of the system. Identical to calling
- QLocale::system().toString(time, QLocale::ShortFormat) or
- QLocale::system().toString(time, QLocale::LongFormat).
-
- If the \a format is Qt::DefaultLocaleShortDate or
- Qt::DefaultLocaleLongDate, the string format depends on the
- default application locale. This is the locale set with
- QLocale::setDefault(), or the system locale if no default locale
- has been set. Identical to calling
-
- \l {QLocale::toString()}{QLocale().toString(time, QLocale::ShortFormat)} or
- \l {QLocale::toString()}{QLocale().toString(time, QLocale::LongFormat)}.
-
- If the \a format is Qt::RFC2822Date, the string is formatted in
- an \l{RFC 2822} compatible way. An example of this formatting is
- "23:59:20".
-
- If the time is invalid, an empty string will be returned.
-
- \sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString()
-*/
-
-QString QTime::toString(Qt::DateFormat format) const
-{
- if (!isValid())
- return QString();
-
- switch (format) {
- case Qt::SystemLocaleDate:
- case Qt::SystemLocaleShortDate:
- return QLocale::system().toString(*this, QLocale::ShortFormat);
- case Qt::SystemLocaleLongDate:
- return QLocale::system().toString(*this, QLocale::LongFormat);
- case Qt::LocaleDate:
- case Qt::DefaultLocaleShortDate:
- return QLocale().toString(*this, QLocale::ShortFormat);
- case Qt::DefaultLocaleLongDate:
- return QLocale().toString(*this, QLocale::LongFormat);
- case Qt::ISODateWithMs:
- return QString::asprintf("%02d:%02d:%02d.%03d", hour(), minute(), second(), msec());
- case Qt::RFC2822Date:
- case Qt::ISODate:
- case Qt::TextDate:
- default:
- return QString::asprintf("%02d:%02d:%02d", hour(), minute(), second());
- }
-}
-
-/*!
- \fn QString QTime::toString(const QString &format) const
- \fn QString QTime::toString(QStringView format) const
-
- Returns the time as a string. The \a format parameter determines
- the format of the result string.
-
- These expressions may be used:
-
- \table
- \header \li Expression \li Output
- \row \li h
- \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \li hh
- \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \li H
- \li the hour without a leading zero (0 to 23, even with AM/PM display)
- \row \li HH
- \li the hour with a leading zero (00 to 23, even with AM/PM display)
- \row \li m \li the minute without a leading zero (0 to 59)
- \row \li mm \li the minute with a leading zero (00 to 59)
- \row \li s \li the whole second, without any leading zero (0 to 59)
- \row \li ss \li the whole second, with a leading zero where applicable (00 to 59)
- \row \li z \li the fractional part of the second, to go after a decimal
- point, without trailing zeroes (0 to 999). Thus "\c{s.z}"
- reports the seconds to full available (millisecond) precision
- without trailing zeroes.
- \row \li zzz \li the fractional part of the second, to millisecond
- precision, including trailing zeroes where applicable (000 to 999).
- \row \li AP or A
- \li use AM/PM display. \e A/AP will be replaced by either
- QLocale::amText() or QLocale::pmText().
- \row \li ap or a
- \li use am/pm display. \e a/ap will be replaced by a lower-case version of
- QLocale::amText() or QLocale::pmText().
- \row \li t \li the timezone (for example "CEST")
- \endtable
-
- Any sequence of characters enclosed in single quotes will be included
- verbatim in the output string (stripped of the quotes), even if it contains
- formatting characters. Two consecutive single quotes ("''") are replaced by
- a single quote in the output. All other characters in the format string are
- included verbatim in the output string.
-
- Formats without separators (e.g. "ddMM") are supported but must be used with
- care, as the resulting strings aren't always reliably readable (e.g. if "dM"
- produces "212" it could mean either the 2nd of December or the 21st of
- February).
-
- Example format strings (assuming that the QTime is 14:13:09.042 and the system
- locale is \c{en_US})
-
- \table
- \header \li Format \li Result
- \row \li hh:mm:ss.zzz \li 14:13:09.042
- \row \li h:m:s ap \li 2:13:9 pm
- \row \li H:m:s a \li 14:13:9 pm
- \endtable
-
- If the time is invalid, an empty string will be returned.
- If \a format is empty, the default format "hh:mm:ss" is used.
-
- \sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString()
-*/
-QString QTime::toString(QStringView format) const
-{
- return QLocale::system().toString(*this, format); // QLocale::c() ### Qt6
-}
-
-#if QT_STRINGVIEW_VERSION < 2
-QString QTime::toString(const QString &format) const
-{
- return toString(qToStringViewIgnoringNull(format));
-}
-#endif
-
-#endif // datestring
-
-/*!
- Sets the time to hour \a h, minute \a m, seconds \a s and
- milliseconds \a ms.
-
- \a h must be in the range 0 to 23, \a m and \a s must be in the
- range 0 to 59, and \a ms must be in the range 0 to 999.
- Returns \c true if the set time is valid; otherwise returns \c false.
-
- \sa isValid()
-*/
-
-bool QTime::setHMS(int h, int m, int s, int ms)
-{
- if (!isValid(h,m,s,ms)) {
- mds = NullTime; // make this invalid
- return false;
- }
- mds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;
- return true;
-}
-
-/*!
- Returns a QTime object containing a time \a s seconds later
- than the time of this object (or earlier if \a s is negative).
-
- Note that the time will wrap if it passes midnight.
-
- Returns a null time if this time is invalid.
-
- Example:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 5
-
- \sa addMSecs(), secsTo(), QDateTime::addSecs()
-*/
-
-QTime QTime::addSecs(int s) const
-{
- s %= SECS_PER_DAY;
- return addMSecs(s * 1000);
-}
-
-/*!
- Returns the number of seconds from this time to \a t.
- If \a t is earlier than this time, the number of seconds returned
- is negative.
-
- Because QTime measures time within a day and there are 86400
- seconds in a day, the result is always between -86400 and 86400.
-
- secsTo() does not take into account any milliseconds.
-
- Returns 0 if either time is invalid.
-
- \sa addSecs(), QDateTime::secsTo()
-*/
-
-int QTime::secsTo(const QTime &t) const
-{
- if (!isValid() || !t.isValid())
- return 0;
-
- // Truncate milliseconds as we do not want to consider them.
- int ourSeconds = ds() / 1000;
- int theirSeconds = t.ds() / 1000;
- return theirSeconds - ourSeconds;
-}
-
-/*!
- Returns a QTime object containing a time \a ms milliseconds later
- than the time of this object (or earlier if \a ms is negative).
-
- Note that the time will wrap if it passes midnight. See addSecs()
- for an example.
-
- Returns a null time if this time is invalid.
-
- \sa addSecs(), msecsTo(), QDateTime::addMSecs()
-*/
-
-QTime QTime::addMSecs(int ms) const
-{
- QTime t;
- if (isValid()) {
- if (ms < 0) {
- // %,/ not well-defined for -ve, so always work with +ve.
- int negdays = (MSECS_PER_DAY - ms) / MSECS_PER_DAY;
- t.mds = (ds() + ms + negdays * MSECS_PER_DAY) % MSECS_PER_DAY;
- } else {
- t.mds = (ds() + ms) % MSECS_PER_DAY;
- }
- }
- return t;
-}
-
-/*!
- Returns the number of milliseconds from this time to \a t.
- If \a t is earlier than this time, the number of milliseconds returned
- is negative.
-
- Because QTime measures time within a day and there are 86400
- seconds in a day, the result is always between -86400000 and
- 86400000 ms.
-
- Returns 0 if either time is invalid.
-
- \sa secsTo(), addMSecs(), QDateTime::msecsTo()
-*/
-
-int QTime::msecsTo(const QTime &t) const
-{
- if (!isValid() || !t.isValid())
- return 0;
- return t.ds() - ds();
-}
-
-
-/*!
- \fn bool QTime::operator==(const QTime &t) const
-
- Returns \c true if this time is equal to \a t; otherwise returns \c false.
-*/
-
-/*!
- \fn bool QTime::operator!=(const QTime &t) const
-
- Returns \c true if this time is different from \a t; otherwise returns \c false.
-*/
-
-/*!
- \fn bool QTime::operator<(const QTime &t) const
-
- Returns \c true if this time is earlier than \a t; otherwise returns \c false.
-*/
-
-/*!
- \fn bool QTime::operator<=(const QTime &t) const
-
- Returns \c true if this time is earlier than or equal to \a t;
- otherwise returns \c false.
-*/
-
-/*!
- \fn bool QTime::operator>(const QTime &t) const
-
- Returns \c true if this time is later than \a t; otherwise returns \c false.
-*/
-
-/*!
- \fn bool QTime::operator>=(const QTime &t) const
-
- Returns \c true if this time is later than or equal to \a t;
- otherwise returns \c false.
-*/
-
-/*!
- \fn QTime QTime::fromMSecsSinceStartOfDay(int msecs)
-
- Returns a new QTime instance with the time set to the number of \a msecs
- since the start of the day, i.e. since 00:00:00.
-
- If \a msecs falls outside the valid range an invalid QTime will be returned.
-
- \sa msecsSinceStartOfDay()
-*/
-
-/*!
- \fn int QTime::msecsSinceStartOfDay() const
-
- Returns the number of msecs since the start of the day, i.e. since 00:00:00.
-
- \sa fromMSecsSinceStartOfDay()
-*/
-
-/*!
- \fn QTime::currentTime()
-
- Returns the current time as reported by the system clock.
-
- Note that the accuracy depends on the accuracy of the underlying
- operating system; not all systems provide 1-millisecond accuracy.
-*/
-
-#if QT_CONFIG(datestring)
-
-static QTime fromIsoTimeString(const QStringRef &string, Qt::DateFormat format, bool *isMidnight24)
-{
- if (isMidnight24)
- *isMidnight24 = false;
-
- const int size = string.size();
- if (size < 5)
- return QTime();
-
- bool ok = false;
- int hour = string.mid(0, 2).toInt(&ok);
- if (!ok)
- return QTime();
- const int minute = string.mid(3, 2).toInt(&ok);
- if (!ok)
- return QTime();
- int second = 0;
- int msec = 0;
-
- if (size == 5) {
- // HH:mm format
- second = 0;
- msec = 0;
- } else if (string.at(5) == QLatin1Char(',') || string.at(5) == QLatin1Char('.')) {
- if (format == Qt::TextDate)
- return QTime();
- // ISODate HH:mm.ssssss format
- // We only want 5 digits worth of fraction of minute. This follows the existing
- // behavior that determines how milliseconds are read; 4 millisecond digits are
- // read and then rounded to 3. If we read at most 5 digits for fraction of minute,
- // the maximum amount of millisecond digits it will expand to once converted to
- // seconds is 4. E.g. 12:34,99999 will expand to 12:34:59.9994. The milliseconds
- // will then be rounded up AND clamped to 999.
-
- const QStringRef minuteFractionStr = string.mid(6, 5);
- const long minuteFractionInt = minuteFractionStr.toLong(&ok);
- if (!ok)
- return QTime();
- const float minuteFraction = double(minuteFractionInt) / (std::pow(double(10), minuteFractionStr.count()));
-
- const float secondWithMs = minuteFraction * 60;
- const float secondNoMs = std::floor(secondWithMs);
- const float secondFraction = secondWithMs - secondNoMs;
- second = secondNoMs;
- msec = qMin(qRound(secondFraction * 1000.0), 999);
- } else {
- // HH:mm:ss or HH:mm:ss.zzz
- second = string.mid(6, 2).toInt(&ok);
- if (!ok)
- return QTime();
- if (size > 8 && (string.at(8) == QLatin1Char(',') || string.at(8) == QLatin1Char('.'))) {
- const QStringRef msecStr(string.mid(9, 4));
- int msecInt = msecStr.isEmpty() ? 0 : msecStr.toInt(&ok);
- if (!ok)
- return QTime();
- const double secondFraction(msecInt / (std::pow(double(10), msecStr.count())));
- msec = qMin(qRound(secondFraction * 1000.0), 999);
- }
- }
-
- const bool isISODate = format == Qt::ISODate || format == Qt::ISODateWithMs;
- if (isISODate && hour == 24 && minute == 0 && second == 0 && msec == 0) {
- if (isMidnight24)
- *isMidnight24 = true;
- hour = 0;
- }
-
- return QTime(hour, minute, second, msec);
-}
-
-/*!
- Returns the time represented in the \a string as a QTime using the
- \a format given, or an invalid time if this is not possible.
-
- Note that fromString() uses a "C" locale encoded string to convert
- milliseconds to a float value. If the default locale is not "C",
- this may result in two conversion attempts (if the conversion
- fails for the default locale). This should be considered an
- implementation detail.
-
- \sa toString(), QLocale::toTime()
-*/
-QTime QTime::fromString(const QString &string, Qt::DateFormat format)
-{
- if (string.isEmpty())
- return QTime();
-
- switch (format) {
- case Qt::SystemLocaleDate:
- case Qt::SystemLocaleShortDate:
- return QLocale::system().toTime(string, QLocale::ShortFormat);
- case Qt::SystemLocaleLongDate:
- return QLocale::system().toTime(string, QLocale::LongFormat);
- case Qt::LocaleDate:
- case Qt::DefaultLocaleShortDate:
- return QLocale().toTime(string, QLocale::ShortFormat);
- case Qt::DefaultLocaleLongDate:
- return QLocale().toTime(string, QLocale::LongFormat);
- case Qt::RFC2822Date:
- return rfcDateImpl(string).time;
- case Qt::ISODate:
- case Qt::ISODateWithMs:
- case Qt::TextDate:
- default:
- return fromIsoTimeString(QStringRef(&string), format, 0);
- }
-}
-
-/*!
- Returns the QTime represented by the \a string, using the \a
- format given, or an invalid time if the string cannot be parsed.
-
- These expressions may be used for the format:
-
- \table
- \header \li Expression \li Output
- \row \li h
- \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \li hh
- \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \li m \li the minute without a leading zero (0 to 59)
- \row \li mm \li the minute with a leading zero (00 to 59)
- \row \li s \li the whole second, without any leading zero (0 to 59)
- \row \li ss \li the whole second, with a leading zero where applicable (00 to 59)
- \row \li z \li the fractional part of the second, to go after a decimal
- point, without trailing zeroes (0 to 999). Thus "\c{s.z}"
- reports the seconds to full available (millisecond) precision
- without trailing zeroes.
- \row \li zzz \li the fractional part of the second, to millisecond
- precision, including trailing zeroes where applicable (000 to 999).
- \row \li AP
- \li interpret as an AM/PM time. \e AP must be either "AM" or "PM".
- \row \li ap
- \li Interpret as an AM/PM time. \e ap must be either "am" or "pm".
- \endtable
-
- All other input characters will be treated as text. Any sequence
- of characters that are enclosed in single quotes will also be
- treated as text and not be used as an expression.
-
- \snippet code/src_corelib_tools_qdatetime.cpp 6
-
- If the format is not satisfied, an invalid QTime is returned.
- Expressions that do not expect leading zeroes to be given (h, m, s
- and z) are greedy. This means that they will use two digits even if
- this puts them outside the range of accepted values and leaves too
- few digits for other sections. For example, the following string
- could have meant 00:07:10, but the m will grab two digits, resulting
- in an invalid time:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 7
-
- Any field that is not represented in the format will be set to zero.
- For example:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 8
-
- \sa toString(), QDateTime::fromString(), QDate::fromString(),
- QLocale::toTime()
-*/
-
-QTime QTime::fromString(const QString &string, const QString &format)
-{
- QTime time;
-#if QT_CONFIG(datetimeparser)
- QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
- // dt.setDefaultLocale(QLocale::c()); ### Qt 6
- if (dt.parseFormat(format))
- dt.fromString(string, 0, &time);
-#else
- Q_UNUSED(string);
- Q_UNUSED(format);
-#endif
- return time;
-}
-
-#endif // datestring
-
-
-/*!
- \overload
-
- Returns \c true if the specified time is valid; otherwise returns
- false.
-
- The time is valid if \a h is in the range 0 to 23, \a m and
- \a s are in the range 0 to 59, and \a ms is in the range 0 to 999.
-
- Example:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 9
-*/
-
-bool QTime::isValid(int h, int m, int s, int ms)
-{
- return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
-}
-
-#if QT_DEPRECATED_SINCE(5, 14) // ### Qt 6: remove
-/*!
- Sets this time to the current time. This is practical for timing:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 10
-
- \sa restart(), elapsed(), currentTime()
-*/
-
-void QTime::start()
-{
- *this = currentTime();
-}
-
-/*!
- Sets this time to the current time and returns the number of
- milliseconds that have elapsed since the last time start() or
- restart() was called.
-
- This function is guaranteed to be atomic and is thus very handy
- for repeated measurements. Call start() to start the first
- measurement, and restart() for each later measurement.
-
- Note that the counter wraps to zero 24 hours after the last call
- to start() or restart().
-
- \warning If the system's clock setting has been changed since the
- last time start() or restart() was called, the result is
- undefined. This can happen when daylight-saving time is turned on
- or off.
-
- \sa start(), elapsed(), currentTime()
-*/
-
-int QTime::restart()
-{
- QTime t = currentTime();
- int n = msecsTo(t);
- if (n < 0) // passed midnight
- n += 86400*1000;
- *this = t;
- return n;
-}
-
-/*!
- Returns the number of milliseconds that have elapsed since the
- last time start() or restart() was called.
-
- Note that the counter wraps to zero 24 hours after the last call
- to start() or restart.
-
- Note that the accuracy depends on the accuracy of the underlying
- operating system; not all systems provide 1-millisecond accuracy.
-
- \warning If the system's clock setting has been changed since the
- last time start() or restart() was called, the result is
- undefined. This can happen when daylight-saving time is turned on
- or off.
-
- \sa start(), restart()
-*/
-
-int QTime::elapsed() const
-{
- int n = msecsTo(currentTime());
- if (n < 0) // passed midnight
- n += 86400 * 1000;
- return n;
-}
-#endif // Use QElapsedTimer instead !
-
-/*****************************************************************************
- QDateTime static helper functions
- *****************************************************************************/
-
-// get the types from QDateTime (through QDateTimePrivate)
-typedef QDateTimePrivate::QDateTimeShortData ShortData;
-typedef QDateTimePrivate::QDateTimeData QDateTimeData;
-
-// Returns the platform variant of timezone, i.e. the standard time offset
-// The timezone external variable is documented as always holding the
-// Standard Time offset as seconds west of Greenwich, i.e. UTC+01:00 is -3600
-// Note this may not be historicaly accurate.
-// Relies on tzset, mktime, or localtime having been called to populate timezone
-static int qt_timezone()
-{
-#if defined(_MSC_VER)
- long offset;
- _get_timezone(&offset);
- return offset;
-#elif defined(Q_OS_BSD4) && !defined(Q_OS_DARWIN)
- time_t clock = time(NULL);
- struct tm t;
- localtime_r(&clock, &t);
- // QTBUG-36080 Workaround for systems without the POSIX timezone
- // variable. This solution is not very efficient but fixing it is up to
- // the libc implementations.
- //
- // tm_gmtoff has some important differences compared to the timezone
- // variable:
- // - It returns the number of seconds east of UTC, and we want the
- // number of seconds west of UTC.
- // - It also takes DST into account, so we need to adjust it to always
- // get the Standard Time offset.
- return -t.tm_gmtoff + (t.tm_isdst ? (long)SECS_PER_HOUR : 0L);
-#elif defined(Q_OS_INTEGRITY)
- return 0;
-#else
- return timezone;
-#endif // Q_OS_WIN
-}
-
-// Returns the tzname, assume tzset has been called already
-static QString qt_tzname(QDateTimePrivate::DaylightStatus daylightStatus)
-{
- int isDst = (daylightStatus == QDateTimePrivate::DaylightTime) ? 1 : 0;
-#if defined(Q_CC_MSVC)
- size_t s = 0;
- char name[512];
- if (_get_tzname(&s, name, 512, isDst))
- return QString();
- return QString::fromLocal8Bit(name);
-#else
- return QString::fromLocal8Bit(tzname[isDst]);
-#endif // Q_OS_WIN
-}
-
-#if QT_CONFIG(datetimeparser) && QT_CONFIG(timezone)
-/*
- \internal
- Implemented here to share qt_tzname()
-*/
-int QDateTimeParser::startsWithLocalTimeZone(const QStringRef name)
-{
- QDateTimePrivate::DaylightStatus zones[2] = {
- QDateTimePrivate::StandardTime,
- QDateTimePrivate::DaylightTime
- };
- for (const auto z : zones) {
- QString zone(qt_tzname(z));
- if (name.startsWith(zone))
- return zone.size();
- }
- return 0;
-}
-#endif // datetimeparser && timezone
-
-// Calls the platform variant of mktime for the given date, time and daylightStatus,
-// and updates the date, time, daylightStatus and abbreviation with the returned values
-// If the date falls outside the 1970 to 2037 range supported by mktime / time_t
-// then null date/time will be returned, you should adjust the date first if
-// you need a guaranteed result.
-static qint64 qt_mktime(QDate *date, QTime *time, QDateTimePrivate::DaylightStatus *daylightStatus,
- QString *abbreviation, bool *ok = 0)
-{
- const qint64 msec = time->msec();
- int yy, mm, dd;
- date->getDate(&yy, &mm, &dd);
-
- // All other platforms provide standard C library time functions
- tm local;
- memset(&local, 0, sizeof(local)); // tm_[wy]day plus any non-standard fields
- local.tm_sec = time->second();
- local.tm_min = time->minute();
- local.tm_hour = time->hour();
- local.tm_mday = dd;
- local.tm_mon = mm - 1;
- local.tm_year = yy - 1900;
- if (daylightStatus)
- local.tm_isdst = int(*daylightStatus);
- else
- local.tm_isdst = -1;
-
-#if defined(Q_OS_WIN)
- int hh = local.tm_hour;
-#endif // Q_OS_WIN
- time_t secsSinceEpoch = qMkTime(&local);
- if (secsSinceEpoch != time_t(-1)) {
- *date = QDate(local.tm_year + 1900, local.tm_mon + 1, local.tm_mday);
- *time = QTime(local.tm_hour, local.tm_min, local.tm_sec, msec);
-#if defined(Q_OS_WIN)
- // Windows mktime for the missing hour subtracts 1 hour from the time
- // instead of adding 1 hour. If time differs and is standard time then
- // this has happened, so add 2 hours to the time and 1 hour to the msecs
- if (local.tm_isdst == 0 && local.tm_hour != hh) {
- if (time->hour() >= 22)
- *date = date->addDays(1);
- *time = time->addSecs(2 * SECS_PER_HOUR);
- secsSinceEpoch += SECS_PER_HOUR;
- local.tm_isdst = 1;
- }
-#endif // Q_OS_WIN
- if (local.tm_isdst >= 1) {
- if (daylightStatus)
- *daylightStatus = QDateTimePrivate::DaylightTime;
- if (abbreviation)
- *abbreviation = qt_tzname(QDateTimePrivate::DaylightTime);
- } else if (local.tm_isdst == 0) {
- if (daylightStatus)
- *daylightStatus = QDateTimePrivate::StandardTime;
- if (abbreviation)
- *abbreviation = qt_tzname(QDateTimePrivate::StandardTime);
- } else {
- if (daylightStatus)
- *daylightStatus = QDateTimePrivate::UnknownDaylightTime;
- if (abbreviation)
- *abbreviation = qt_tzname(QDateTimePrivate::StandardTime);
- }
- if (ok)
- *ok = true;
- } else {
- *date = QDate();
- *time = QTime();
- if (daylightStatus)
- *daylightStatus = QDateTimePrivate::UnknownDaylightTime;
- if (abbreviation)
- *abbreviation = QString();
- if (ok)
- *ok = false;
- }
-
- return ((qint64)secsSinceEpoch * 1000) + msec;
-}
-
-// Calls the platform variant of localtime for the given msecs, and updates
-// the date, time, and DST status with the returned values.
-static bool qt_localtime(qint64 msecsSinceEpoch, QDate *localDate, QTime *localTime,
- QDateTimePrivate::DaylightStatus *daylightStatus)
-{
- const time_t secsSinceEpoch = msecsSinceEpoch / 1000;
- const int msec = msecsSinceEpoch % 1000;
-
- tm local;
- bool valid = false;
-
- // localtime() is specified to work as if it called tzset().
- // localtime_r() does not have this constraint, so make an explicit call.
- // The explicit call should also request the timezone info be re-parsed.
- qTzSet();
-#if QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
- // Use the reentrant version of localtime() where available
- // as is thread-safe and doesn't use a shared static data area
- tm *res = 0;
- res = localtime_r(&secsSinceEpoch, &local);
- if (res)
- valid = true;
-#elif defined(Q_CC_MSVC)
- if (!_localtime64_s(&local, &secsSinceEpoch))
- valid = true;
-#else
- // Returns shared static data which may be overwritten at any time
- // So copy the result asap
- tm *res = 0;
- res = localtime(&secsSinceEpoch);
- if (res) {
- local = *res;
- valid = true;
- }
-#endif
- if (valid) {
- *localDate = QDate(local.tm_year + 1900, local.tm_mon + 1, local.tm_mday);
- *localTime = QTime(local.tm_hour, local.tm_min, local.tm_sec, msec);
- if (daylightStatus) {
- if (local.tm_isdst > 0)
- *daylightStatus = QDateTimePrivate::DaylightTime;
- else if (local.tm_isdst < 0)
- *daylightStatus = QDateTimePrivate::UnknownDaylightTime;
- else
- *daylightStatus = QDateTimePrivate::StandardTime;
- }
- return true;
- } else {
- *localDate = QDate();
- *localTime = QTime();
- if (daylightStatus)
- *daylightStatus = QDateTimePrivate::UnknownDaylightTime;
- return false;
- }
-}
-
-// Converts an msecs value into a date and time
-static void msecsToTime(qint64 msecs, QDate *date, QTime *time)
-{
- qint64 jd = JULIAN_DAY_FOR_EPOCH;
- qint64 ds = 0;
-
- if (msecs >= MSECS_PER_DAY || msecs <= -MSECS_PER_DAY) {
- jd += msecs / MSECS_PER_DAY;
- msecs %= MSECS_PER_DAY;
- }
-
- if (msecs < 0) {
- ds = MSECS_PER_DAY - msecs - 1;
- jd -= ds / MSECS_PER_DAY;
- ds = ds % MSECS_PER_DAY;
- ds = MSECS_PER_DAY - ds - 1;
- } else {
- ds = msecs;
- }
-
- if (date)
- *date = QDate::fromJulianDay(jd);
- if (time)
- *time = QTime::fromMSecsSinceStartOfDay(ds);
-}
-
-// Converts a date/time value into msecs
-static qint64 timeToMSecs(const QDate &date, const QTime &time)
-{
- return ((date.toJulianDay() - JULIAN_DAY_FOR_EPOCH) * MSECS_PER_DAY)
- + time.msecsSinceStartOfDay();
-}
-
-// Convert an MSecs Since Epoch into Local Time
-static bool epochMSecsToLocalTime(qint64 msecs, QDate *localDate, QTime *localTime,
- QDateTimePrivate::DaylightStatus *daylightStatus = 0)
-{
- if (msecs < 0) {
- // Docs state any LocalTime before 1970-01-01 will *not* have any Daylight Time applied
- // Instead just use the standard offset from UTC to convert to UTC time
- qTzSet();
- msecsToTime(msecs - qt_timezone() * 1000, localDate, localTime);
- if (daylightStatus)
- *daylightStatus = QDateTimePrivate::StandardTime;
- return true;
- } else if (msecs > (qint64(TIME_T_MAX) * 1000)) {
- // Docs state any LocalTime after 2037-12-31 *will* have any DST applied
- // but this may fall outside the supported time_t range, so need to fake it.
- // Use existing method to fake the conversion, but this is deeply flawed as it may
- // apply the conversion from the wrong day number, e.g. if rule is last Sunday of month
- // TODO Use QTimeZone when available to apply the future rule correctly
- QDate utcDate;
- QTime utcTime;
- msecsToTime(msecs, &utcDate, &utcTime);
- int year, month, day;
- utcDate.getDate(&year, &month, &day);
- // 2037 is not a leap year, so make sure date isn't Feb 29
- if (month == 2 && day == 29)
- --day;
- QDate fakeDate(2037, month, day);
- qint64 fakeMsecs = QDateTime(fakeDate, utcTime, Qt::UTC).toMSecsSinceEpoch();
- bool res = qt_localtime(fakeMsecs, localDate, localTime, daylightStatus);
- *localDate = localDate->addDays(fakeDate.daysTo(utcDate));
- return res;
- } else {
- // Falls inside time_t suported range so can use localtime
- return qt_localtime(msecs, localDate, localTime, daylightStatus);
- }
-}
-
-// Convert a LocalTime expressed in local msecs encoding and the corresponding
-// DST status into a UTC epoch msecs. Optionally populate the returned
-// values from mktime for the adjusted local date and time.
-static qint64 localMSecsToEpochMSecs(qint64 localMsecs,
- QDateTimePrivate::DaylightStatus *daylightStatus,
- QDate *localDate = 0, QTime *localTime = 0,
- QString *abbreviation = 0)
-{
- QDate dt;
- QTime tm;
- msecsToTime(localMsecs, &dt, &tm);
-
- const qint64 msecsMax = qint64(TIME_T_MAX) * 1000;
-
- if (localMsecs <= qint64(MSECS_PER_DAY)) {
-
- // Docs state any LocalTime before 1970-01-01 will *not* have any DST applied
-
- // First, if localMsecs is within +/- 1 day of minimum time_t try mktime in case it does
- // fall after minimum and needs proper DST conversion
- if (localMsecs >= -qint64(MSECS_PER_DAY)) {
- bool valid;
- qint64 utcMsecs = qt_mktime(&dt, &tm, daylightStatus, abbreviation, &valid);
- if (valid && utcMsecs >= 0) {
- // mktime worked and falls in valid range, so use it
- if (localDate)
- *localDate = dt;
- if (localTime)
- *localTime = tm;
- return utcMsecs;
- }
- } else {
- // If we don't call mktime then need to call tzset to get offset
- qTzSet();
- }
- // Time is clearly before 1970-01-01 so just use standard offset to convert
- qint64 utcMsecs = localMsecs + qt_timezone() * 1000;
- if (localDate || localTime)
- msecsToTime(localMsecs, localDate, localTime);
- if (daylightStatus)
- *daylightStatus = QDateTimePrivate::StandardTime;
- if (abbreviation)
- *abbreviation = qt_tzname(QDateTimePrivate::StandardTime);
- return utcMsecs;
-
- } else if (localMsecs >= msecsMax - MSECS_PER_DAY) {
-
- // Docs state any LocalTime after 2037-12-31 *will* have any DST applied
- // but this may fall outside the supported time_t range, so need to fake it.
-
- // First, if localMsecs is within +/- 1 day of maximum time_t try mktime in case it does
- // fall before maximum and can use proper DST conversion
- if (localMsecs <= msecsMax + MSECS_PER_DAY) {
- bool valid;
- qint64 utcMsecs = qt_mktime(&dt, &tm, daylightStatus, abbreviation, &valid);
- if (valid && utcMsecs <= msecsMax) {
- // mktime worked and falls in valid range, so use it
- if (localDate)
- *localDate = dt;
- if (localTime)
- *localTime = tm;
- return utcMsecs;
- }
- }
- // Use existing method to fake the conversion, but this is deeply flawed as it may
- // apply the conversion from the wrong day number, e.g. if rule is last Sunday of month
- // TODO Use QTimeZone when available to apply the future rule correctly
- int year, month, day;
- dt.getDate(&year, &month, &day);
- // 2037 is not a leap year, so make sure date isn't Feb 29
- if (month == 2 && day == 29)
- --day;
- QDate fakeDate(2037, month, day);
- qint64 fakeDiff = fakeDate.daysTo(dt);
- qint64 utcMsecs = qt_mktime(&fakeDate, &tm, daylightStatus, abbreviation);
- if (localDate)
- *localDate = fakeDate.addDays(fakeDiff);
- if (localTime)
- *localTime = tm;
- QDate utcDate;
- QTime utcTime;
- msecsToTime(utcMsecs, &utcDate, &utcTime);
- utcDate = utcDate.addDays(fakeDiff);
- utcMsecs = timeToMSecs(utcDate, utcTime);
- return utcMsecs;
-
- } else {
-
- // Clearly falls inside 1970-2037 suported range so can use mktime
- qint64 utcMsecs = qt_mktime(&dt, &tm, daylightStatus, abbreviation);
- if (localDate)
- *localDate = dt;
- if (localTime)
- *localTime = tm;
- return utcMsecs;
-
- }
-}
-
-static inline bool specCanBeSmall(Qt::TimeSpec spec)
-{
- return spec == Qt::LocalTime || spec == Qt::UTC;
-}
-
-static inline bool msecsCanBeSmall(qint64 msecs)
-{
- if (!QDateTimeData::CanBeSmall)
- return false;
-
- ShortData sd;
- sd.msecs = qintptr(msecs);
- return sd.msecs == msecs;
-}
-
-static Q_DECL_CONSTEXPR inline
-QDateTimePrivate::StatusFlags mergeSpec(QDateTimePrivate::StatusFlags status, Qt::TimeSpec spec)
-{
- return QDateTimePrivate::StatusFlags((status & ~QDateTimePrivate::TimeSpecMask) |
- (int(spec) << QDateTimePrivate::TimeSpecShift));
-}
-
-static Q_DECL_CONSTEXPR inline Qt::TimeSpec extractSpec(QDateTimePrivate::StatusFlags status)
-{
- return Qt::TimeSpec((status & QDateTimePrivate::TimeSpecMask) >> QDateTimePrivate::TimeSpecShift);
-}
-
-// Set the Daylight Status if LocalTime set via msecs
-static Q_DECL_RELAXED_CONSTEXPR inline QDateTimePrivate::StatusFlags
-mergeDaylightStatus(QDateTimePrivate::StatusFlags sf, QDateTimePrivate::DaylightStatus status)
-{
- sf &= ~QDateTimePrivate::DaylightMask;
- if (status == QDateTimePrivate::DaylightTime) {
- sf |= QDateTimePrivate::SetToDaylightTime;
- } else if (status == QDateTimePrivate::StandardTime) {
- sf |= QDateTimePrivate::SetToStandardTime;
- }
- return sf;
-}
-
-// Get the DST Status if LocalTime set via msecs
-static Q_DECL_RELAXED_CONSTEXPR inline
-QDateTimePrivate::DaylightStatus extractDaylightStatus(QDateTimePrivate::StatusFlags status)
-{
- if (status & QDateTimePrivate::SetToDaylightTime)
- return QDateTimePrivate::DaylightTime;
- if (status & QDateTimePrivate::SetToStandardTime)
- return QDateTimePrivate::StandardTime;
- return QDateTimePrivate::UnknownDaylightTime;
-}
-
-static inline qint64 getMSecs(const QDateTimeData &d)
-{
- if (d.isShort()) {
- // same as, but producing better code
- //return d.data.msecs;
- return qintptr(d.d) >> 8;
- }
- return d->m_msecs;
-}
-
-static inline QDateTimePrivate::StatusFlags getStatus(const QDateTimeData &d)
-{
- if (d.isShort()) {
- // same as, but producing better code
- //return StatusFlag(d.data.status);
- return QDateTimePrivate::StatusFlag(qintptr(d.d) & 0xFF);
- }
- return d->m_status;
-}
-
-static inline Qt::TimeSpec getSpec(const QDateTimeData &d)
-{
- return extractSpec(getStatus(d));
-}
-
-#if QT_CONFIG(timezone)
-void QDateTimePrivate::setUtcOffsetByTZ(qint64 atMSecsSinceEpoch)
-{
- m_offsetFromUtc = m_timeZone.d->offsetFromUtc(atMSecsSinceEpoch);
-}
-#endif
-
-// Refresh the LocalTime validity and offset
-static void refreshDateTime(QDateTimeData &d)
-{
- auto status = getStatus(d);
- const auto spec = extractSpec(status);
- const qint64 msecs = getMSecs(d);
- qint64 epochMSecs = 0;
- int offsetFromUtc = 0;
- QDate testDate;
- QTime testTime;
- Q_ASSERT(spec == Qt::TimeZone || spec == Qt::LocalTime);
-
-#if QT_CONFIG(timezone)
- // If not valid time zone then is invalid
- if (spec == Qt::TimeZone) {
- if (!d->m_timeZone.isValid()) {
- status &= ~QDateTimePrivate::ValidDateTime;
- } else {
- epochMSecs = QDateTimePrivate::zoneMSecsToEpochMSecs(msecs, d->m_timeZone, extractDaylightStatus(status), &testDate, &testTime);
- d->setUtcOffsetByTZ(epochMSecs);
- }
- }
-#endif // timezone
-
- // If not valid date and time then is invalid
- if (!(status & QDateTimePrivate::ValidDate) || !(status & QDateTimePrivate::ValidTime)) {
- status &= ~QDateTimePrivate::ValidDateTime;
- if (status & QDateTimePrivate::ShortData) {
- d.data.status = status;
- } else {
- d->m_status = status;
- d->m_offsetFromUtc = 0;
- }
- return;
- }
-
- // We have a valid date and time and a Qt::LocalTime or Qt::TimeZone that needs calculating
- // LocalTime and TimeZone might fall into a "missing" DST transition hour
- // Calling toEpochMSecs will adjust the returned date/time if it does
- if (spec == Qt::LocalTime) {
- auto dstStatus = extractDaylightStatus(status);
- epochMSecs = localMSecsToEpochMSecs(msecs, &dstStatus, &testDate, &testTime);
- }
- if (timeToMSecs(testDate, testTime) == msecs) {
- status |= QDateTimePrivate::ValidDateTime;
- // Cache the offset to use in offsetFromUtc()
- offsetFromUtc = (msecs - epochMSecs) / 1000;
- } else {
- status &= ~QDateTimePrivate::ValidDateTime;
- }
-
- if (status & QDateTimePrivate::ShortData) {
- d.data.status = status;
- } else {
- d->m_status = status;
- d->m_offsetFromUtc = offsetFromUtc;
- }
-}
-
-// Check the UTC / offsetFromUTC validity
-static void checkValidDateTime(QDateTimeData &d)
-{
- auto status = getStatus(d);
- auto spec = extractSpec(status);
- switch (spec) {
- case Qt::OffsetFromUTC:
- case Qt::UTC:
- // for these, a valid date and a valid time imply a valid QDateTime
- if ((status & QDateTimePrivate::ValidDate) && (status & QDateTimePrivate::ValidTime))
- status |= QDateTimePrivate::ValidDateTime;
- else
- status &= ~QDateTimePrivate::ValidDateTime;
- if (status & QDateTimePrivate::ShortData)
- d.data.status = status;
- else
- d->m_status = status;
- break;
- case Qt::TimeZone:
- case Qt::LocalTime:
- // for these, we need to check whether the timezone is valid and whether
- // the time is valid in that timezone. Expensive, but no other option.
- refreshDateTime(d);
- break;
- }
-}
-
-static void setTimeSpec(QDateTimeData &d, Qt::TimeSpec spec, int offsetSeconds)
-{
- auto status = getStatus(d);
- status &= ~(QDateTimePrivate::ValidDateTime | QDateTimePrivate::DaylightMask |
- QDateTimePrivate::TimeSpecMask);
-
- switch (spec) {
- case Qt::OffsetFromUTC:
- if (offsetSeconds == 0)
- spec = Qt::UTC;
- break;
- case Qt::TimeZone:
- // Use system time zone instead
- spec = Qt::LocalTime;
- Q_FALLTHROUGH();
- case Qt::UTC:
- case Qt::LocalTime:
- offsetSeconds = 0;
- break;
- }
-
- status = mergeSpec(status, spec);
- if (d.isShort() && offsetSeconds == 0) {
- d.data.status = status;
- } else {
- d.detach();
- d->m_status = status & ~QDateTimePrivate::ShortData;
- d->m_offsetFromUtc = offsetSeconds;
-#if QT_CONFIG(timezone)
- d->m_timeZone = QTimeZone();
-#endif // timezone
- }
-}
-
-static void setDateTime(QDateTimeData &d, const QDate &date, const QTime &time)
-{
- // If the date is valid and the time is not we set time to 00:00:00
- QTime useTime = time;
- if (!useTime.isValid() && date.isValid())
- useTime = QTime::fromMSecsSinceStartOfDay(0);
-
- QDateTimePrivate::StatusFlags newStatus = 0;
-
- // Set date value and status
- qint64 days = 0;
- if (date.isValid()) {
- days = date.toJulianDay() - JULIAN_DAY_FOR_EPOCH;
- newStatus = QDateTimePrivate::ValidDate;
- }
-
- // Set time value and status
- int ds = 0;
- if (useTime.isValid()) {
- ds = useTime.msecsSinceStartOfDay();
- newStatus |= QDateTimePrivate::ValidTime;
- }
-
- // Set msecs serial value
- qint64 msecs = (days * MSECS_PER_DAY) + ds;
- if (d.isShort()) {
- // let's see if we can keep this short
- if (msecsCanBeSmall(msecs)) {
- // yes, we can
- d.data.msecs = qintptr(msecs);
- d.data.status &= ~(QDateTimePrivate::ValidityMask | QDateTimePrivate::DaylightMask);
- d.data.status |= newStatus;
- } else {
- // nope...
- d.detach();
- }
- }
- if (!d.isShort()) {
- d.detach();
- d->m_msecs = msecs;
- d->m_status &= ~(QDateTimePrivate::ValidityMask | QDateTimePrivate::DaylightMask);
- d->m_status |= newStatus;
- }
-
- // Set if date and time are valid
- checkValidDateTime(d);
-}
-
-static QPair<QDate, QTime> getDateTime(const QDateTimeData &d)
-{
- QPair<QDate, QTime> result;
- qint64 msecs = getMSecs(d);
- auto status = getStatus(d);
- msecsToTime(msecs, &result.first, &result.second);
-
- if (!status.testFlag(QDateTimePrivate::ValidDate))
- result.first = QDate();
-
- if (!status.testFlag(QDateTimePrivate::ValidTime))
- result.second = QTime();
-
- return result;
-}
-
-/*****************************************************************************
- QDateTime::Data member functions
- *****************************************************************************/
-
-inline QDateTime::Data::Data()
-{
- // default-constructed data has a special exception:
- // it can be small even if CanBeSmall == false
- // (optimization so we don't allocate memory in the default constructor)
- quintptr value = quintptr(mergeSpec(QDateTimePrivate::ShortData, Qt::LocalTime));
- d = reinterpret_cast<QDateTimePrivate *>(value);
-}
-
-inline QDateTime::Data::Data(Qt::TimeSpec spec)
-{
- if (CanBeSmall && Q_LIKELY(specCanBeSmall(spec))) {
- d = reinterpret_cast<QDateTimePrivate *>(quintptr(mergeSpec(QDateTimePrivate::ShortData, spec)));
- } else {
- // the structure is too small, we need to detach
- d = new QDateTimePrivate;
- d->ref.ref();
- d->m_status = mergeSpec(0, spec);
- }
-}
-
-inline QDateTime::Data::Data(const Data &other)
- : d(other.d)
-{
- if (!isShort()) {
- // check if we could shrink
- if (specCanBeSmall(extractSpec(d->m_status)) && msecsCanBeSmall(d->m_msecs)) {
- ShortData sd;
- sd.msecs = qintptr(d->m_msecs);
- sd.status = d->m_status | QDateTimePrivate::ShortData;
- data = sd;
- } else {
- // no, have to keep it big
- d->ref.ref();
- }
- }
-}
-
-inline QDateTime::Data::Data(Data &&other)
- : d(other.d)
-{
- // reset the other to a short state
- Data dummy;
- Q_ASSERT(dummy.isShort());
- other.d = dummy.d;
-}
-
-inline QDateTime::Data &QDateTime::Data::operator=(const Data &other)
-{
- if (d == other.d)
- return *this;
-
- auto x = d;
- d = other.d;
- if (!other.isShort()) {
- // check if we could shrink
- if (specCanBeSmall(extractSpec(other.d->m_status)) && msecsCanBeSmall(other.d->m_msecs)) {
- ShortData sd;
- sd.msecs = qintptr(other.d->m_msecs);
- sd.status = other.d->m_status | QDateTimePrivate::ShortData;
- data = sd;
- } else {
- // no, have to keep it big
- other.d->ref.ref();
- }
- }
-
- if (!(quintptr(x) & QDateTimePrivate::ShortData) && !x->ref.deref())
- delete x;
- return *this;
-}
-
-inline QDateTime::Data::~Data()
-{
- if (!isShort() && !d->ref.deref())
- delete d;
-}
-
-inline bool QDateTime::Data::isShort() const
-{
- bool b = quintptr(d) & QDateTimePrivate::ShortData;
-
- // sanity check:
- Q_ASSERT(b || (d->m_status & QDateTimePrivate::ShortData) == 0);
-
- // even if CanBeSmall = false, we have short data for a default-constructed
- // QDateTime object. But it's unlikely.
- if (CanBeSmall)
- return Q_LIKELY(b);
- return Q_UNLIKELY(b);
-}
-
-inline void QDateTime::Data::detach()
-{
- QDateTimePrivate *x;
- bool wasShort = isShort();
- if (wasShort) {
- // force enlarging
- x = new QDateTimePrivate;
- x->m_status = QDateTimePrivate::StatusFlag(data.status & ~QDateTimePrivate::ShortData);
- x->m_msecs = data.msecs;
- } else {
- if (d->ref.load() == 1)
- return;
-
- x = new QDateTimePrivate(*d);
- }
-
- x->ref.store(1);
- if (!wasShort && !d->ref.deref())
- delete d;
- d = x;
-}
-
-inline const QDateTimePrivate *QDateTime::Data::operator->() const
-{
- Q_ASSERT(!isShort());
- return d;
-}
-
-inline QDateTimePrivate *QDateTime::Data::operator->()
-{
- // should we attempt to detach here?
- Q_ASSERT(!isShort());
- Q_ASSERT(d->ref.load() == 1);
- return d;
-}
-
-/*****************************************************************************
- QDateTimePrivate member functions
- *****************************************************************************/
-
-Q_NEVER_INLINE
-QDateTime::Data QDateTimePrivate::create(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec,
- int offsetSeconds)
-{
- QDateTime::Data result(toSpec);
- setTimeSpec(result, toSpec, offsetSeconds);
- setDateTime(result, toDate, toTime);
- return result;
-}
-
-#if QT_CONFIG(timezone)
-inline QDateTime::Data QDateTimePrivate::create(const QDate &toDate, const QTime &toTime,
- const QTimeZone &toTimeZone)
-{
- QDateTime::Data result(Qt::TimeZone);
- Q_ASSERT(!result.isShort());
-
- result.d->m_status = mergeSpec(result.d->m_status, Qt::TimeZone);
- result.d->m_timeZone = toTimeZone;
- setDateTime(result, toDate, toTime);
- return result;
-}
-
-// Convert a TimeZone time expressed in zone msecs encoding into a UTC epoch msecs
-// DST transitions are disambiguated by hint.
-inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QTimeZone &zone,
- DaylightStatus hint,
- QDate *zoneDate, QTime *zoneTime)
-{
- // Get the effective data from QTimeZone
- QTimeZonePrivate::Data data = zone.d->dataForLocalTime(zoneMSecs, int(hint));
- // Docs state any time before 1970-01-01 will *not* have any DST applied
- // but all affected times afterwards will have DST applied.
- if (data.atMSecsSinceEpoch < 0) {
- msecsToTime(zoneMSecs, zoneDate, zoneTime);
- return zoneMSecs - data.standardTimeOffset * 1000;
- } else {
- msecsToTime(data.atMSecsSinceEpoch + data.offsetFromUtc * 1000, zoneDate, zoneTime);
- return data.atMSecsSinceEpoch;
- }
-}
-#endif // timezone
-
-/*****************************************************************************
- QDateTime member functions
- *****************************************************************************/
-
-/*!
- \class QDateTime
- \inmodule QtCore
- \ingroup shared
- \reentrant
- \brief The QDateTime class provides date and time functions.
-
-
- A QDateTime object encodes a calendar date and a clock time (a
- "datetime"). It combines features of the QDate and QTime classes.
- It can read the current datetime from the system clock. It
- provides functions for comparing datetimes and for manipulating a
- datetime by adding a number of seconds, days, months, or years.
-
- A QDateTime object is typically created either by giving a date
- and time explicitly in the constructor, or by using the static
- function currentDateTime() that returns a QDateTime object set
- to the system clock's time. The date and time can be changed with
- setDate() and setTime(). A datetime can also be set using the
- setTime_t() function that takes a POSIX-standard "number of
- seconds since 00:00:00 on January 1, 1970" value. The fromString()
- function returns a QDateTime, given a string and a date format
- used to interpret the date within the string.
-
- The date() and time() functions provide access to the date and
- time parts of the datetime. The same information is provided in
- textual format by the toString() function.
-
- QDateTime provides a full set of operators to compare two
- QDateTime objects, where smaller means earlier and larger means
- later.
-
- You can increment (or decrement) a datetime by a given number of
- milliseconds using addMSecs(), seconds using addSecs(), or days
- using addDays(). Similarly, you can use addMonths() and addYears().
- The daysTo() function returns the number of days between two datetimes,
- secsTo() returns the number of seconds between two datetimes, and
- msecsTo() returns the number of milliseconds between two datetimes.
-
- QDateTime can store datetimes as \l{Qt::LocalTime}{local time} or
- as \l{Qt::UTC}{UTC}. QDateTime::currentDateTime() returns a
- QDateTime expressed as local time; use toUTC() to convert it to
- UTC. You can also use timeSpec() to find out if a QDateTime
- object stores a UTC time or a local time. Operations such as
- addSecs() and secsTo() are aware of daylight-saving time (DST).
-
- \note QDateTime does not account for leap seconds.
-
- \section1 Remarks
-
- \section2 No Year 0
-
- There is no year 0. Dates in that year are considered invalid. The
- year -1 is the year "1 before Christ" or "1 before current era."
- The day before 1 January 1 CE is 31 December 1 BCE.
-
- \section2 Range of Valid Dates
-
- The range of valid values able to be stored in QDateTime is dependent on
- the internal storage implementation. QDateTime is currently stored in a
- qint64 as a serial msecs value encoding the date and time. This restricts
- the date range to about +/- 292 million years, compared to the QDate range
- of +/- 2 billion years. Care must be taken when creating a QDateTime with
- extreme values that you do not overflow the storage. The exact range of
- supported values varies depending on the Qt::TimeSpec and time zone.
-
- \section2 Use of System Timezone
-
- QDateTime uses the system's time zone information to determine the
- offset of local time from UTC. If the system is not configured
- correctly or not up-to-date, QDateTime will give wrong results as
- well.
-
- \section2 Daylight-Saving Time (DST)
-
- QDateTime takes into account the system's time zone information
- when dealing with DST. On modern Unix systems, this means it
- applies the correct historical DST data whenever possible. On
- Windows, where the system doesn't support historical DST data,
- historical accuracy is not maintained with respect to DST.
-
- The range of valid dates taking DST into account is 1970-01-01 to
- the present, and rules are in place for handling DST correctly
- until 2037-12-31, but these could change. For dates falling
- outside that range, QDateTime makes a \e{best guess} using the
- rules for year 1970 or 2037, but we can't guarantee accuracy. This
- means QDateTime doesn't take into account changes in a locale's
- time zone before 1970, even if the system's time zone database
- supports that information.
-
- QDateTime takes into consideration the Standard Time to Daylight-Saving Time
- transition. For example if the transition is at 2am and the clock goes
- forward to 3am, then there is a "missing" hour from 02:00:00 to 02:59:59.999
- which QDateTime considers to be invalid. Any date maths performed
- will take this missing hour into account and return a valid result.
-
- \section2 Offset From UTC
-
- A Qt::TimeSpec of Qt::OffsetFromUTC is also supported. This allows you
- to define a QDateTime relative to UTC at a fixed offset of a given number
- of seconds from UTC. For example, an offset of +3600 seconds is one hour
- ahead of UTC and is usually written in ISO standard notation as
- "UTC+01:00". Daylight-Saving Time never applies with this TimeSpec.
-
- There is no explicit size restriction to the offset seconds, but there is
- an implicit limit imposed when using the toString() and fromString()
- methods which use a format of [+|-]hh:mm, effectively limiting the range
- to +/- 99 hours and 59 minutes and whole minutes only. Note that currently
- no time zone lies outside the range of +/- 14 hours.
-
- \section2 Time Zone Support
-
- A Qt::TimeSpec of Qt::TimeZone is also supported in conjunction with the
- QTimeZone class. This allows you to define a datetime in a named time zone
- adhering to a consistent set of daylight-saving transition rules. For
- example a time zone of "Europe/Berlin" will apply the daylight-saving
- rules as used in Germany since 1970. Note that the transition rules
- applied depend on the platform support. See the QTimeZone documentation
- for more details.
-
- \sa QDate, QTime, QDateTimeEdit, QTimeZone
-*/
-
-/*!
- Constructs a null datetime (i.e. null date and null time). A null
- datetime is invalid, since the date is invalid.
-
- \sa isValid()
-*/
-QDateTime::QDateTime() noexcept(Data::CanBeSmall)
-{
-}
-
-
-/*!
- Constructs a datetime with the given \a date, a valid
- time(00:00:00.000), and sets the timeSpec() to Qt::LocalTime.
-*/
-
-QDateTime::QDateTime(const QDate &date)
- : d(QDateTimePrivate::create(date, QTime(0, 0), Qt::LocalTime, 0))
-{
-}
-
-/*!
- Constructs a datetime with the given \a date and \a time, using
- the time specification defined by \a spec.
-
- If \a date is valid and \a time is not, the time will be set to midnight.
-
- If \a spec is Qt::OffsetFromUTC then it will be set to Qt::UTC, i.e. an
- offset of 0 seconds. To create a Qt::OffsetFromUTC datetime use the
- correct constructor.
-
- If \a spec is Qt::TimeZone then the spec will be set to Qt::LocalTime,
- i.e. the current system time zone. To create a Qt::TimeZone datetime
- use the correct constructor.
-*/
-
-QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec)
- : d(QDateTimePrivate::create(date, time, spec, 0))
-{
-}
-
-/*!
- \since 5.2
-
- Constructs a datetime with the given \a date and \a time, using
- the time specification defined by \a spec and \a offsetSeconds seconds.
-
- If \a date is valid and \a time is not, the time will be set to midnight.
-
- If the \a spec is not Qt::OffsetFromUTC then \a offsetSeconds will be ignored.
-
- If the \a spec is Qt::OffsetFromUTC and \a offsetSeconds is 0 then the
- timeSpec() will be set to Qt::UTC, i.e. an offset of 0 seconds.
-
- If \a spec is Qt::TimeZone then the spec will be set to Qt::LocalTime,
- i.e. the current system time zone. To create a Qt::TimeZone datetime
- use the correct constructor.
-*/
-
-QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds)
- : d(QDateTimePrivate::create(date, time, spec, offsetSeconds))
-{
-}
-
-#if QT_CONFIG(timezone)
-/*!
- \since 5.2
-
- Constructs a datetime with the given \a date and \a time, using
- the Time Zone specified by \a timeZone.
-
- If \a date is valid and \a time is not, the time will be set to 00:00:00.
-
- If \a timeZone is invalid then the datetime will be invalid.
-*/
-
-QDateTime::QDateTime(const QDate &date, const QTime &time, const QTimeZone &timeZone)
- : d(QDateTimePrivate::create(date, time, timeZone))
-{
-}
-#endif // timezone
-
-/*!
- Constructs a copy of the \a other datetime.
-*/
-QDateTime::QDateTime(const QDateTime &other) noexcept
- : d(other.d)
-{
-}
-
-/*!
- \since 5.8
- Moves the content of the temporary \a other datetime to this object and
- leaves \a other in an unspecified (but proper) state.
-*/
-QDateTime::QDateTime(QDateTime &&other) noexcept
- : d(std::move(other.d))
-{
-}
-
-/*!
- Destroys the datetime.
-*/
-QDateTime::~QDateTime()
-{
-}
-
-/*!
- Makes a copy of the \a other datetime and returns a reference to the
- copy.
-*/
-
-QDateTime &QDateTime::operator=(const QDateTime &other) noexcept
-{
- d = other.d;
- return *this;
-}
-/*!
- \fn void QDateTime::swap(QDateTime &other)
- \since 5.0
-
- Swaps this datetime with \a other. This operation is very fast
- and never fails.
-*/
-
-/*!
- Returns \c true if both the date and the time are null; otherwise
- returns \c false. A null datetime is invalid.
-
- \sa QDate::isNull(), QTime::isNull(), isValid()
-*/
-
-bool QDateTime::isNull() const
-{
- auto status = getStatus(d);
- return !status.testFlag(QDateTimePrivate::ValidDate) &&
- !status.testFlag(QDateTimePrivate::ValidTime);
-}
-
-/*!
- Returns \c true if both the date and the time are valid and they are valid in
- the current Qt::TimeSpec, otherwise returns \c false.
-
- If the timeSpec() is Qt::LocalTime or Qt::TimeZone then the date and time are
- checked to see if they fall in the Standard Time to Daylight-Saving Time transition
- hour, i.e. if the transition is at 2am and the clock goes forward to 3am
- then the time from 02:00:00 to 02:59:59.999 is considered to be invalid.
-
- \sa QDate::isValid(), QTime::isValid()
-*/
-
-bool QDateTime::isValid() const
-{
- auto status = getStatus(d);
- return status & QDateTimePrivate::ValidDateTime;
-}
-
-/*!
- Returns the date part of the datetime.
-
- \sa setDate(), time(), timeSpec()
-*/
-
-QDate QDateTime::date() const
-{
- auto status = getStatus(d);
- if (!status.testFlag(QDateTimePrivate::ValidDate))
- return QDate();
- QDate dt;
- msecsToTime(getMSecs(d), &dt, 0);
- return dt;
-}
-
-/*!
- Returns the time part of the datetime.
-
- \sa setTime(), date(), timeSpec()
-*/
-
-QTime QDateTime::time() const
-{
- auto status = getStatus(d);
- if (!status.testFlag(QDateTimePrivate::ValidTime))
- return QTime();
- QTime tm;
- msecsToTime(getMSecs(d), 0, &tm);
- return tm;
-}
-
-/*!
- Returns the time specification of the datetime.
-
- \sa setTimeSpec(), date(), time(), Qt::TimeSpec
-*/
-
-Qt::TimeSpec QDateTime::timeSpec() const
-{
- return getSpec(d);
-}
-
-#if QT_CONFIG(timezone)
-/*!
- \since 5.2
-
- Returns the time zone of the datetime.
-
- If the timeSpec() is Qt::LocalTime then an instance of the current system
- time zone will be returned. Note however that if you copy this time zone
- the instance will not remain in sync if the system time zone changes.
-
- \sa setTimeZone(), Qt::TimeSpec
-*/
-
-QTimeZone QDateTime::timeZone() const
-{
- switch (getSpec(d)) {
- case Qt::UTC:
- return QTimeZone::utc();
- case Qt::OffsetFromUTC:
- return QTimeZone(d->m_offsetFromUtc);
- case Qt::TimeZone:
- Q_ASSERT(d->m_timeZone.isValid());
- return d->m_timeZone;
- case Qt::LocalTime:
- return QTimeZone::systemTimeZone();
- }
- return QTimeZone();
-}
-#endif // timezone
-
-/*!
- \since 5.2
-
- Returns the current Offset From UTC in seconds.
-
- If the timeSpec() is Qt::OffsetFromUTC this will be the value originally set.
-
- If the timeSpec() is Qt::TimeZone this will be the offset effective in the
- Time Zone including any Daylight-Saving Offset.
-
- If the timeSpec() is Qt::LocalTime this will be the difference between the
- Local Time and UTC including any Daylight-Saving Offset.
-
- If the timeSpec() is Qt::UTC this will be 0.
-
- \sa setOffsetFromUtc()
-*/
-
-int QDateTime::offsetFromUtc() const
-{
- if (!d.isShort())
- return d->m_offsetFromUtc;
- if (!isValid())
- return 0;
-
- auto spec = getSpec(d);
- if (spec == Qt::LocalTime) {
- // we didn't cache the value, so we need to calculate it now...
- qint64 msecs = getMSecs(d);
- return (msecs - toMSecsSinceEpoch()) / 1000;
- }
-
- Q_ASSERT(spec == Qt::UTC);
- return 0;
-}
-
-/*!
- \since 5.2
-
- Returns the Time Zone Abbreviation for the datetime.
-
- If the timeSpec() is Qt::UTC this will be "UTC".
-
- If the timeSpec() is Qt::OffsetFromUTC this will be in the format
- "UTC[+-]00:00".
-
- If the timeSpec() is Qt::LocalTime then the host system is queried for the
- correct abbreviation.
-
- Note that abbreviations may or may not be localized.
-
- Note too that the abbreviation is not guaranteed to be a unique value,
- i.e. different time zones may have the same abbreviation.
-
- \sa timeSpec()
-*/
-
-QString QDateTime::timeZoneAbbreviation() const
-{
- switch (getSpec(d)) {
- case Qt::UTC:
- return QLatin1String("UTC");
- case Qt::OffsetFromUTC:
- return QLatin1String("UTC") + toOffsetString(Qt::ISODate, d->m_offsetFromUtc);
- case Qt::TimeZone:
-#if !QT_CONFIG(timezone)
- break;
-#else
- return d->m_timeZone.d->abbreviation(toMSecsSinceEpoch());
-#endif // timezone
- case Qt::LocalTime: {
- QString abbrev;
- auto status = extractDaylightStatus(getStatus(d));
- localMSecsToEpochMSecs(getMSecs(d), &status, 0, 0, &abbrev);
- return abbrev;
- }
- }
- return QString();
-}
-
-/*!
- \since 5.2
-
- Returns if this datetime falls in Daylight-Saving Time.
-
- If the Qt::TimeSpec is not Qt::LocalTime or Qt::TimeZone then will always
- return false.
-
- \sa timeSpec()
-*/
-
-bool QDateTime::isDaylightTime() const
-{
- switch (getSpec(d)) {
- case Qt::UTC:
- case Qt::OffsetFromUTC:
- return false;
- case Qt::TimeZone:
-#if !QT_CONFIG(timezone)
- break;
-#else
- return d->m_timeZone.d->isDaylightTime(toMSecsSinceEpoch());
-#endif // timezone
- case Qt::LocalTime: {
- auto status = extractDaylightStatus(getStatus(d));
- if (status == QDateTimePrivate::UnknownDaylightTime)
- localMSecsToEpochMSecs(getMSecs(d), &status);
- return (status == QDateTimePrivate::DaylightTime);
- }
- }
- return false;
-}
-
-/*!
- Sets the date part of this datetime to \a date. If no time is set yet, it
- is set to midnight. If \a date is invalid, this QDateTime becomes invalid.
-
- \sa date(), setTime(), setTimeSpec()
-*/
-
-void QDateTime::setDate(const QDate &date)
-{
- setDateTime(d, date, time());
-}
-
-/*!
- Sets the time part of this datetime to \a time. If \a time is not valid,
- this function sets it to midnight. Therefore, it's possible to clear any
- set time in a QDateTime by setting it to a default QTime:
-
- \code
- QDateTime dt = QDateTime::currentDateTime();
- dt.setTime(QTime());
- \endcode
-
- \sa time(), setDate(), setTimeSpec()
-*/
-
-void QDateTime::setTime(const QTime &time)
-{
- setDateTime(d, date(), time);
-}
-
-/*!
- Sets the time specification used in this datetime to \a spec.
- The datetime will refer to a different point in time.
-
- If \a spec is Qt::OffsetFromUTC then the timeSpec() will be set
- to Qt::UTC, i.e. an effective offset of 0.
-
- If \a spec is Qt::TimeZone then the spec will be set to Qt::LocalTime,
- i.e. the current system time zone.
-
- Example:
- \snippet code/src_corelib_tools_qdatetime.cpp 19
-
- \sa timeSpec(), setDate(), setTime(), setTimeZone(), Qt::TimeSpec
-*/
-
-void QDateTime::setTimeSpec(Qt::TimeSpec spec)
-{
- QT_PREPEND_NAMESPACE(setTimeSpec(d, spec, 0));
- checkValidDateTime(d);
-}
-
-/*!
- \since 5.2
-
- Sets the timeSpec() to Qt::OffsetFromUTC and the offset to \a offsetSeconds.
- The datetime will refer to a different point in time.
-
- The maximum and minimum offset is 14 positive or negative hours. If
- \a offsetSeconds is larger or smaller than that, then the result is
- undefined.
-
- If \a offsetSeconds is 0 then the timeSpec() will be set to Qt::UTC.
-
- \sa isValid(), offsetFromUtc()
-*/
-
-void QDateTime::setOffsetFromUtc(int offsetSeconds)
-{
- QT_PREPEND_NAMESPACE(setTimeSpec(d, Qt::OffsetFromUTC, offsetSeconds));
- checkValidDateTime(d);
-}
-
-#if QT_CONFIG(timezone)
-/*!
- \since 5.2
-
- Sets the time zone used in this datetime to \a toZone.
- The datetime will refer to a different point in time.
-
- If \a toZone is invalid then the datetime will be invalid.
-
- \sa timeZone(), Qt::TimeSpec
-*/
-
-void QDateTime::setTimeZone(const QTimeZone &toZone)
-{
- d.detach(); // always detach
- d->m_status = mergeSpec(d->m_status, Qt::TimeZone);
- d->m_offsetFromUtc = 0;
- d->m_timeZone = toZone;
- refreshDateTime(d);
-}
-#endif // timezone
-
-/*!
- \since 4.7
-
- Returns the datetime as the number of milliseconds that have passed
- since 1970-01-01T00:00:00.000, Coordinated Universal Time (Qt::UTC).
-
- On systems that do not support time zones, this function will
- behave as if local time were Qt::UTC.
-
- The behavior for this function is undefined if the datetime stored in
- this object is not valid. However, for all valid dates, this function
- returns a unique value.
-
- \sa toSecsSinceEpoch(), setMSecsSinceEpoch()
-*/
-qint64 QDateTime::toMSecsSinceEpoch() const
-{
- switch (getSpec(d)) {
- case Qt::UTC:
- return getMSecs(d);
-
- case Qt::OffsetFromUTC:
- return d->m_msecs - (d->m_offsetFromUtc * 1000);
-
- case Qt::LocalTime: {
- // recalculate the local timezone
- auto status = extractDaylightStatus(getStatus(d));
- return localMSecsToEpochMSecs(getMSecs(d), &status);
- }
-
- case Qt::TimeZone:
-#if !QT_CONFIG(timezone)
- return 0;
-#else
- return QDateTimePrivate::zoneMSecsToEpochMSecs(d->m_msecs, d->m_timeZone,
- extractDaylightStatus(getStatus(d)));
-#endif
- }
- Q_UNREACHABLE();
- return 0;
-}
-
-/*!
- \since 5.8
-
- Returns the datetime as the number of seconds that have passed since
- 1970-01-01T00:00:00.000, Coordinated Universal Time (Qt::UTC).
-
- On systems that do not support time zones, this function will
- behave as if local time were Qt::UTC.
-
- The behavior for this function is undefined if the datetime stored in
- this object is not valid. However, for all valid dates, this function
- returns a unique value.
-
- \sa toMSecsSinceEpoch(), setSecsSinceEpoch()
-*/
-qint64 QDateTime::toSecsSinceEpoch() const
-{
- return toMSecsSinceEpoch() / 1000;
-}
-
-#if QT_DEPRECATED_SINCE(5, 8)
-/*!
- \deprecated
-
- Returns the datetime as the number of seconds that have passed
- since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC).
-
- On systems that do not support time zones, this function will
- behave as if local time were Qt::UTC.
-
- \note This function returns a 32-bit unsigned integer and is deprecated.
-
- If the date is outside the range 1970-01-01T00:00:00 to
- 2106-02-07T06:28:14, this function returns -1 cast to an unsigned integer
- (i.e., 0xFFFFFFFF).
-
- To get an extended range, use toMSecsSinceEpoch() or toSecsSinceEpoch().
-
- \sa toSecsSinceEpoch(), toMSecsSinceEpoch(), setTime_t()
-*/
-
-uint QDateTime::toTime_t() const
-{
- if (!isValid())
- return uint(-1);
- qint64 retval = toMSecsSinceEpoch() / 1000;
- if (quint64(retval) >= Q_UINT64_C(0xFFFFFFFF))
- return uint(-1);
- return uint(retval);
-}
-#endif
-
-/*!
- \since 4.7
-
- Sets the date and time given the number of milliseconds \a msecs that have
- passed since 1970-01-01T00:00:00.000, Coordinated Universal Time
- (Qt::UTC). On systems that do not support time zones this function
- will behave as if local time were Qt::UTC.
-
- Note that passing the minimum of \c qint64
- (\c{std::numeric_limits<qint64>::min()}) to \a msecs will result in
- undefined behavior.
-
- \sa toMSecsSinceEpoch(), setSecsSinceEpoch()
-*/
-void QDateTime::setMSecsSinceEpoch(qint64 msecs)
-{
- const auto spec = getSpec(d);
- auto status = getStatus(d);
-
- status &= ~QDateTimePrivate::ValidityMask;
- switch (spec) {
- case Qt::UTC:
- status = status
- | QDateTimePrivate::ValidDate
- | QDateTimePrivate::ValidTime
- | QDateTimePrivate::ValidDateTime;
- break;
- case Qt::OffsetFromUTC:
- msecs = msecs + (d->m_offsetFromUtc * 1000);
- status = status
- | QDateTimePrivate::ValidDate
- | QDateTimePrivate::ValidTime
- | QDateTimePrivate::ValidDateTime;
- break;
- case Qt::TimeZone:
- Q_ASSERT(!d.isShort());
-#if QT_CONFIG(timezone)
- // Docs state any LocalTime before 1970-01-01 will *not* have any DST applied
- // but all affected times afterwards will have DST applied.
- d.detach();
- if (msecs >= 0) {
- status = mergeDaylightStatus(status,
- d->m_timeZone.d->isDaylightTime(msecs)
- ? QDateTimePrivate::DaylightTime
- : QDateTimePrivate::StandardTime);
- d->m_offsetFromUtc = d->m_timeZone.d->offsetFromUtc(msecs);
- } else {
- status = mergeDaylightStatus(status, QDateTimePrivate::StandardTime);
- d->m_offsetFromUtc = d->m_timeZone.d->standardTimeOffset(msecs);
- }
- msecs = msecs + (d->m_offsetFromUtc * 1000);
- status = status
- | QDateTimePrivate::ValidDate
- | QDateTimePrivate::ValidTime
- | QDateTimePrivate::ValidDateTime;
-#endif // timezone
- break;
- case Qt::LocalTime: {
- QDate dt;
- QTime tm;
- QDateTimePrivate::DaylightStatus dstStatus;
- epochMSecsToLocalTime(msecs, &dt, &tm, &dstStatus);
- setDateTime(d, dt, tm);
- msecs = getMSecs(d);
- status = mergeDaylightStatus(getStatus(d), dstStatus);
- break;
- }
- }
-
- if (msecsCanBeSmall(msecs) && d.isShort()) {
- // we can keep short
- d.data.msecs = qintptr(msecs);
- d.data.status = status;
- } else {
- d.detach();
- d->m_status = status & ~QDateTimePrivate::ShortData;
- d->m_msecs = msecs;
- }
-
- if (spec == Qt::LocalTime || spec == Qt::TimeZone)
- refreshDateTime(d);
-}
-
-/*!
- \since 5.8
-
- Sets the date and time given the number of seconds \a secs that have
- passed since 1970-01-01T00:00:00.000, Coordinated Universal Time
- (Qt::UTC). On systems that do not support time zones this function
- will behave as if local time were Qt::UTC.
-
- \sa toSecsSinceEpoch(), setMSecsSinceEpoch()
-*/
-void QDateTime::setSecsSinceEpoch(qint64 secs)
-{
- setMSecsSinceEpoch(secs * 1000);
-}
-
-#if QT_DEPRECATED_SINCE(5, 8)
-/*!
- \fn void QDateTime::setTime_t(uint seconds)
- \deprecated
-
- Sets the date and time given the number of \a seconds that have
- passed since 1970-01-01T00:00:00, Coordinated Universal Time
- (Qt::UTC). On systems that do not support time zones this function
- will behave as if local time were Qt::UTC.
-
- \note This function is deprecated. For new code, use setSecsSinceEpoch().
-
- \sa toTime_t()
-*/
-
-void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
-{
- setMSecsSinceEpoch((qint64)secsSince1Jan1970UTC * 1000);
-}
-#endif
-
-#if QT_CONFIG(datestring)
-/*!
- \fn QString QDateTime::toString(Qt::DateFormat format) const
-
- \overload
-
- Returns the datetime as a string in the \a format given.
-
- If the \a format is Qt::TextDate, the string is formatted in
- the default way. QDate::shortDayName(), QDate::shortMonthName(),
- and QTime::toString() are used to generate the string, so the
- day and month names will be localized names using the system locale,
- i.e. QLocale::system(). An example of this formatting is
- "Wed May 20 03:40:13 1998".
-
- If the \a format is Qt::ISODate, the string format corresponds
- to the ISO 8601 extended specification for representations of
- dates and times, taking the form yyyy-MM-ddTHH:mm:ss[Z|[+|-]HH:mm],
- depending on the timeSpec() of the QDateTime. If the timeSpec()
- is Qt::UTC, Z will be appended to the string; if the timeSpec() is
- Qt::OffsetFromUTC, the offset in hours and minutes from UTC will
- be appended to the string. To include milliseconds in the ISO 8601
- date, use the \a format Qt::ISODateWithMs, which corresponds to
- yyyy-MM-ddTHH:mm:ss.zzz[Z|[+|-]HH:mm].
-
- If the \a format is Qt::SystemLocaleShortDate or
- Qt::SystemLocaleLongDate, the string format depends on the locale
- settings of the system. Identical to calling
- QLocale::system().toString(datetime, QLocale::ShortFormat) or
- QLocale::system().toString(datetime, QLocale::LongFormat).
-
- If the \a format is Qt::DefaultLocaleShortDate or
- Qt::DefaultLocaleLongDate, the string format depends on the
- default application locale. This is the locale set with
- QLocale::setDefault(), or the system locale if no default locale
- has been set. Identical to calling QLocale().toString(datetime,
- QLocale::ShortFormat) or QLocale().toString(datetime,
- QLocale::LongFormat).
-
- If the \a format is Qt::RFC2822Date, the string is formatted
- following \l{RFC 2822}.
-
- If the datetime is invalid, an empty string will be returned.
-
- \warning The Qt::ISODate format is only valid for years in the
- range 0 to 9999. This restriction may apply to locale-aware
- formats as well, depending on the locale settings.
-
- \sa fromString(), QDate::toString(), QTime::toString(),
- QLocale::toString()
-*/
-
-QString QDateTime::toString(Qt::DateFormat format) const
-{
- QString buf;
- if (!isValid())
- return buf;
-
- switch (format) {
- case Qt::SystemLocaleDate:
- case Qt::SystemLocaleShortDate:
- return QLocale::system().toString(*this, QLocale::ShortFormat);
- case Qt::SystemLocaleLongDate:
- return QLocale::system().toString(*this, QLocale::LongFormat);
- case Qt::LocaleDate:
- case Qt::DefaultLocaleShortDate:
- return QLocale().toString(*this, QLocale::ShortFormat);
- case Qt::DefaultLocaleLongDate:
- return QLocale().toString(*this, QLocale::LongFormat);
- case Qt::RFC2822Date: {
- buf = QLocale::c().toString(*this, QStringViewLiteral("dd MMM yyyy hh:mm:ss "));
- buf += toOffsetString(Qt::TextDate, offsetFromUtc());
- return buf;
- }
- default:
-#if QT_CONFIG(textdate)
- case Qt::TextDate: {
- const QPair<QDate, QTime> p = getDateTime(d);
- buf = p.first.toString(Qt::TextDate);
- // Insert time between date's day and year:
- buf.insert(buf.lastIndexOf(QLatin1Char(' ')),
- QLatin1Char(' ') + p.second.toString(Qt::TextDate));
- // Append zone/offset indicator, as appropriate:
- switch (timeSpec()) {
- case Qt::LocalTime:
- break;
-# if QT_CONFIG(timezone)
- case Qt::TimeZone:
- buf += QLatin1Char(' ') + d->m_timeZone.abbreviation(*this);
- break;
-# endif
- default:
- buf += QLatin1String(" GMT");
- if (getSpec(d) == Qt::OffsetFromUTC)
- buf += toOffsetString(Qt::TextDate, offsetFromUtc());
- }
- return buf;
- }
-#endif
- case Qt::ISODate:
- case Qt::ISODateWithMs: {
- const QPair<QDate, QTime> p = getDateTime(d);
- const QDate &dt = p.first;
- const QTime &tm = p.second;
- buf = dt.toString(Qt::ISODate);
- if (buf.isEmpty())
- return QString(); // failed to convert
- buf += QLatin1Char('T');
- buf += tm.toString(format);
- switch (getSpec(d)) {
- case Qt::UTC:
- buf += QLatin1Char('Z');
- break;
- case Qt::OffsetFromUTC:
-#if QT_CONFIG(timezone)
- case Qt::TimeZone:
-#endif
- buf += toOffsetString(Qt::ISODate, offsetFromUtc());
- break;
- default:
- break;
- }
- return buf;
- }
- }
-}
-
-/*!
- \fn QString QDateTime::toString(const QString &format) const
- \fn QString QDateTime::toString(QStringView format) const
-
- Returns the datetime as a string. The \a format parameter
- determines the format of the result string.
-
- These expressions may be used for the date:
-
- \table
- \header \li Expression \li Output
- \row \li d \li the day as number without a leading zero (1 to 31)
- \row \li dd \li the day as number with a leading zero (01 to 31)
- \row \li ddd
- \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li dddd
- \li the long localized day name (e.g. 'Monday' to 'Sunday').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li M \li the month as number without a leading zero (1-12)
- \row \li MM \li the month as number with a leading zero (01-12)
- \row \li MMM
- \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li MMMM
- \li the long localized month name (e.g. 'January' to 'December').
- Uses the system locale to localize the name, i.e. QLocale::system().
- \row \li yy \li the year as two digit number (00-99)
- \row \li yyyy \li the year as four digit number
- \endtable
-
- These expressions may be used for the time:
-
- \table
- \header \li Expression \li Output
- \row \li h
- \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \li hh
- \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \li H
- \li the hour without a leading zero (0 to 23, even with AM/PM display)
- \row \li HH
- \li the hour with a leading zero (00 to 23, even with AM/PM display)
- \row \li m \li the minute without a leading zero (0 to 59)
- \row \li mm \li the minute with a leading zero (00 to 59)
- \row \li s \li the whole second without a leading zero (0 to 59)
- \row \li ss \li the whole second with a leading zero where applicable (00 to 59)
- \row \li z \li the fractional part of the second, to go after a decimal
- point, without trailing zeroes (0 to 999). Thus "\c{s.z}"
- reports the seconds to full available (millisecond) precision
- without trailing zeroes.
- \row \li zzz \li the fractional part of the second, to millisecond
- precision, including trailing zeroes where applicable (000 to 999).
- \row \li AP or A
- \li use AM/PM display. \e A/AP will be replaced by either "AM" or "PM".
- \row \li ap or a
- \li use am/pm display. \e a/ap will be replaced by either "am" or "pm".
- \row \li t \li the timezone (for example "CEST")
- \endtable
-
- Any sequence of characters enclosed in single quotes will be included
- verbatim in the output string (stripped of the quotes), even if it contains
- formatting characters. Two consecutive single quotes ("''") are replaced by
- a single quote in the output. All other characters in the format string are
- included verbatim in the output string.
-
- Formats without separators (e.g. "ddMM") are supported but must be used with
- care, as the resulting strings aren't always reliably readable (e.g. if "dM"
- produces "212" it could mean either the 2nd of December or the 21st of
- February).
-
- Example format strings (assumed that the QDateTime is 21 May 2001
- 14:13:09.120):
-
- \table
- \header \li Format \li Result
- \row \li dd.MM.yyyy \li 21.05.2001
- \row \li ddd MMMM d yy \li Tue May 21 01
- \row \li hh:mm:ss.zzz \li 14:13:09.120
- \row \li hh:mm:ss.z \li 14:13:09.12
- \row \li h:m:s ap \li 2:13:9 pm
- \endtable
-
- If the datetime is invalid, an empty string will be returned.
-
- \sa fromString(), QDate::toString(), QTime::toString(), QLocale::toString()
-*/
-QString QDateTime::toString(QStringView format) const
-{
- return QLocale::system().toString(*this, format); // QLocale::c() ### Qt6
-}
-
-#if QT_STRINGVIEW_LEVEL < 2
-QString QDateTime::toString(const QString &format) const
-{
- return toString(qToStringViewIgnoringNull(format));
-}
-#endif
-
-#endif // datestring
-
-static inline void massageAdjustedDateTime(const QDateTimeData &d, QDate *date, QTime *time)
-{
- /*
- If we have just adjusted to a day with a DST transition, our given time
- may lie in the transition hour (either missing or duplicated). For any
- other time, telling mktime (deep in the bowels of localMSecsToEpochMSecs)
- we don't know its DST-ness will produce no adjustment (just a decision as
- to its DST-ness); but for a time in spring's missing hour it'll adjust the
- time while picking a DST-ness. (Handling of autumn is trickier, as either
- DST-ness is valid, without adjusting the time. We might want to propagate
- the daylight status in that case, but it's hard to do so without breaking
- (far more common) other cases; and it makes little difference, as the two
- answers do then differ only in DST-ness.)
- */
- auto spec = getSpec(d);
- if (spec == Qt::LocalTime) {
- QDateTimePrivate::DaylightStatus status = QDateTimePrivate::UnknownDaylightTime;
- localMSecsToEpochMSecs(timeToMSecs(*date, *time), &status, date, time);
-#if QT_CONFIG(timezone)
- } else if (spec == Qt::TimeZone) {
- QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(*date, *time),
- d->m_timeZone,
- QDateTimePrivate::UnknownDaylightTime,
- date, time);
-#endif // timezone
- }
-}
-
-/*!
- Returns a QDateTime object containing a datetime \a ndays days
- later than the datetime of this object (or earlier if \a ndays is
- negative).
-
- If the timeSpec() is Qt::LocalTime and the resulting
- date and time fall in the Standard Time to Daylight-Saving Time transition
- hour then the result will be adjusted accordingly, i.e. if the transition
- is at 2am and the clock goes forward to 3am and the result falls between
- 2am and 3am then the result will be adjusted to fall after 3am.
-
- \sa daysTo(), addMonths(), addYears(), addSecs()
-*/
-
-QDateTime QDateTime::addDays(qint64 ndays) const
-{
- QDateTime dt(*this);
- QPair<QDate, QTime> p = getDateTime(d);
- QDate &date = p.first;
- QTime &time = p.second;
- date = date.addDays(ndays);
- massageAdjustedDateTime(dt.d, &date, &time);
- setDateTime(dt.d, date, time);
- return dt;
-}
-
-/*!
- Returns a QDateTime object containing a datetime \a nmonths months
- later than the datetime of this object (or earlier if \a nmonths
- is negative).
-
- If the timeSpec() is Qt::LocalTime and the resulting
- date and time fall in the Standard Time to Daylight-Saving Time transition
- hour then the result will be adjusted accordingly, i.e. if the transition
- is at 2am and the clock goes forward to 3am and the result falls between
- 2am and 3am then the result will be adjusted to fall after 3am.
-
- \sa daysTo(), addDays(), addYears(), addSecs()
-*/
-
-QDateTime QDateTime::addMonths(int nmonths) const
-{
- QDateTime dt(*this);
- QPair<QDate, QTime> p = getDateTime(d);
- QDate &date = p.first;
- QTime &time = p.second;
- date = date.addMonths(nmonths);
- massageAdjustedDateTime(dt.d, &date, &time);
- setDateTime(dt.d, date, time);
- return dt;
-}
-
-/*!
- Returns a QDateTime object containing a datetime \a nyears years
- later than the datetime of this object (or earlier if \a nyears is
- negative).
-
- If the timeSpec() is Qt::LocalTime and the resulting
- date and time fall in the Standard Time to Daylight-Saving Time transition
- hour then the result will be adjusted accordingly, i.e. if the transition
- is at 2am and the clock goes forward to 3am and the result falls between
- 2am and 3am then the result will be adjusted to fall after 3am.
-
- \sa daysTo(), addDays(), addMonths(), addSecs()
-*/
-
-QDateTime QDateTime::addYears(int nyears) const
-{
- QDateTime dt(*this);
- QPair<QDate, QTime> p = getDateTime(d);
- QDate &date = p.first;
- QTime &time = p.second;
- date = date.addYears(nyears);
- massageAdjustedDateTime(dt.d, &date, &time);
- setDateTime(dt.d, date, time);
- return dt;
-}
-
-/*!
- Returns a QDateTime object containing a datetime \a s seconds
- later than the datetime of this object (or earlier if \a s is
- negative).
-
- If this datetime is invalid, an invalid datetime will be returned.
-
- \sa addMSecs(), secsTo(), addDays(), addMonths(), addYears()
-*/
-
-QDateTime QDateTime::addSecs(qint64 s) const
-{
- return addMSecs(s * 1000);
-}
-
-/*!
- Returns a QDateTime object containing a datetime \a msecs miliseconds
- later than the datetime of this object (or earlier if \a msecs is
- negative).
-
- If this datetime is invalid, an invalid datetime will be returned.
-
- \sa addSecs(), msecsTo(), addDays(), addMonths(), addYears()
-*/
-QDateTime QDateTime::addMSecs(qint64 msecs) const
-{
- if (!isValid())
- return QDateTime();
-
- QDateTime dt(*this);
- auto spec = getSpec(d);
- if (spec == Qt::LocalTime || spec == Qt::TimeZone) {
- // Convert to real UTC first in case crosses DST transition
- dt.setMSecsSinceEpoch(toMSecsSinceEpoch() + msecs);
- } else {
- // No need to convert, just add on
- if (d.isShort()) {
- // need to check if we need to enlarge first
- msecs += dt.d.data.msecs;
- if (msecsCanBeSmall(msecs)) {
- dt.d.data.msecs = qintptr(msecs);
- } else {
- dt.d.detach();
- dt.d->m_msecs = msecs;
- }
- } else {
- dt.d.detach();
- dt.d->m_msecs += msecs;
- }
- }
- return dt;
-}
-
-/*!
- Returns the number of days from this datetime to the \a other
- datetime. The number of days is counted as the number of times
- midnight is reached between this datetime to the \a other
- datetime. This means that a 10 minute difference from 23:55 to
- 0:05 the next day counts as one day.
-
- If the \a other datetime is earlier than this datetime,
- the value returned is negative.
-
- Example:
- \snippet code/src_corelib_tools_qdatetime.cpp 15
-
- \sa addDays(), secsTo(), msecsTo()
-*/
-
-qint64 QDateTime::daysTo(const QDateTime &other) const
-{
- return date().daysTo(other.date());
-}
-
-/*!
- Returns the number of seconds from this datetime to the \a other
- datetime. If the \a other datetime is earlier than this datetime,
- the value returned is negative.
-
- Before performing the comparison, the two datetimes are converted
- to Qt::UTC to ensure that the result is correct if daylight-saving
- (DST) applies to one of the two datetimes but not the other.
-
- Returns 0 if either datetime is invalid.
-
- Example:
- \snippet code/src_corelib_tools_qdatetime.cpp 11
-
- \sa addSecs(), daysTo(), QTime::secsTo()
-*/
-
-qint64 QDateTime::secsTo(const QDateTime &other) const
-{
- return (msecsTo(other) / 1000);
-}
-
-/*!
- Returns the number of milliseconds from this datetime to the \a other
- datetime. If the \a other datetime is earlier than this datetime,
- the value returned is negative.
-
- Before performing the comparison, the two datetimes are converted
- to Qt::UTC to ensure that the result is correct if daylight-saving
- (DST) applies to one of the two datetimes and but not the other.
-
- Returns 0 if either datetime is invalid.
-
- \sa addMSecs(), daysTo(), QTime::msecsTo()
-*/
-
-qint64 QDateTime::msecsTo(const QDateTime &other) const
-{
- if (!isValid() || !other.isValid())
- return 0;
-
- return other.toMSecsSinceEpoch() - toMSecsSinceEpoch();
-}
-
-/*!
- \fn QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
-
- Returns a copy of this datetime converted to the given time
- \a spec.
-
- If \a spec is Qt::OffsetFromUTC then it is set to Qt::UTC. To set to a
- spec of Qt::OffsetFromUTC use toOffsetFromUtc().
-
- If \a spec is Qt::TimeZone then it is set to Qt::LocalTime,
- i.e. the local Time Zone.
-
- Example:
- \snippet code/src_corelib_tools_qdatetime.cpp 16
-
- \sa timeSpec(), toTimeZone(), toUTC(), toLocalTime()
-*/
-
-QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
-{
- if (getSpec(d) == spec && (spec == Qt::UTC || spec == Qt::LocalTime))
- return *this;
-
- if (!isValid()) {
- QDateTime ret = *this;
- ret.setTimeSpec(spec);
- return ret;
- }
-
- return fromMSecsSinceEpoch(toMSecsSinceEpoch(), spec, 0);
-}
-
-/*!
- \since 5.2
-
- \fn QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
-
- Returns a copy of this datetime converted to a spec of Qt::OffsetFromUTC
- with the given \a offsetSeconds.
-
- If the \a offsetSeconds equals 0 then a UTC datetime will be returned
-
- \sa setOffsetFromUtc(), offsetFromUtc(), toTimeSpec()
-*/
-
-QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
-{
- if (getSpec(d) == Qt::OffsetFromUTC
- && d->m_offsetFromUtc == offsetSeconds)
- return *this;
-
- if (!isValid()) {
- QDateTime ret = *this;
- ret.setOffsetFromUtc(offsetSeconds);
- return ret;
- }
-
- return fromMSecsSinceEpoch(toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds);
-}
-
-#if QT_CONFIG(timezone)
-/*!
- \since 5.2
-
- Returns a copy of this datetime converted to the given \a timeZone
-
- \sa timeZone(), toTimeSpec()
-*/
-
-QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const
-{
- if (getSpec(d) == Qt::TimeZone && d->m_timeZone == timeZone)
- return *this;
-
- if (!isValid()) {
- QDateTime ret = *this;
- ret.setTimeZone(timeZone);
- return ret;
- }
-
- return fromMSecsSinceEpoch(toMSecsSinceEpoch(), timeZone);
-}
-#endif // timezone
-
-/*!
- Returns \c true if this datetime is equal to the \a other datetime;
- otherwise returns \c false.
-
- \sa operator!=()
-*/
-
-bool QDateTime::operator==(const QDateTime &other) const
-{
- if (getSpec(d) == Qt::LocalTime
- && getStatus(d) == getStatus(other.d)) {
- return getMSecs(d) == getMSecs(other.d);
- }
- // Convert to UTC and compare
- return (toMSecsSinceEpoch() == other.toMSecsSinceEpoch());
-}
-
-/*!
- \fn bool QDateTime::operator!=(const QDateTime &other) const
-
- Returns \c true if this datetime is different from the \a other
- datetime; otherwise returns \c false.
-
- Two datetimes are different if either the date, the time, or the
- time zone components are different.
-
- \sa operator==()
-*/
-
-/*!
- Returns \c true if this datetime is earlier than the \a other
- datetime; otherwise returns \c false.
-*/
-
-bool QDateTime::operator<(const QDateTime &other) const
-{
- if (getSpec(d) == Qt::LocalTime
- && getStatus(d) == getStatus(other.d)) {
- return getMSecs(d) < getMSecs(other.d);
- }
- // Convert to UTC and compare
- return (toMSecsSinceEpoch() < other.toMSecsSinceEpoch());
-}
-
-/*!
- \fn bool QDateTime::operator<=(const QDateTime &other) const
-
- Returns \c true if this datetime is earlier than or equal to the
- \a other datetime; otherwise returns \c false.
-*/
-
-/*!
- \fn bool QDateTime::operator>(const QDateTime &other) const
-
- Returns \c true if this datetime is later than the \a other datetime;
- otherwise returns \c false.
-*/
-
-/*!
- \fn bool QDateTime::operator>=(const QDateTime &other) const
-
- Returns \c true if this datetime is later than or equal to the
- \a other datetime; otherwise returns \c false.
-*/
-
-/*!
- \fn QDateTime QDateTime::currentDateTime()
- Returns the current datetime, as reported by the system clock, in
- the local time zone.
-
- \sa currentDateTimeUtc(), QDate::currentDate(), QTime::currentTime(), toTimeSpec()
-*/
-
-/*!
- \fn QDateTime QDateTime::currentDateTimeUtc()
- \since 4.7
- Returns the current datetime, as reported by the system clock, in
- UTC.
-
- \sa currentDateTime(), QDate::currentDate(), QTime::currentTime(), toTimeSpec()
-*/
-
-/*!
- \fn qint64 QDateTime::currentMSecsSinceEpoch()
- \since 4.7
-
- Returns the number of milliseconds since 1970-01-01T00:00:00 Universal
- Coordinated Time. This number is like the POSIX time_t variable, but
- expressed in milliseconds instead.
-
- \sa currentDateTime(), currentDateTimeUtc(), toTime_t(), toTimeSpec()
-*/
-
-/*!
- \fn qint64 QDateTime::currentSecsSinceEpoch()
- \since 5.8
-
- Returns the number of seconds since 1970-01-01T00:00:00 Universal
- Coordinated Time.
-
- \sa currentMSecsSinceEpoch()
-*/
-
-#if defined(Q_OS_WIN)
-static inline uint msecsFromDecomposed(int hour, int minute, int sec, int msec = 0)
-{
- return MSECS_PER_HOUR * hour + MSECS_PER_MIN * minute + 1000 * sec + msec;
-}
-
-QDate QDate::currentDate()
-{
- QDate d;
- SYSTEMTIME st;
- memset(&st, 0, sizeof(SYSTEMTIME));
- GetLocalTime(&st);
- d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
- return d;
-}
-
-QTime QTime::currentTime()
-{
- QTime ct;
- SYSTEMTIME st;
- memset(&st, 0, sizeof(SYSTEMTIME));
- GetLocalTime(&st);
- ct.setHMS(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
- return ct;
-}
-
-QDateTime QDateTime::currentDateTime()
-{
- QDate d;
- QTime t;
- SYSTEMTIME st;
- memset(&st, 0, sizeof(SYSTEMTIME));
- GetLocalTime(&st);
- d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
- t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
- return QDateTime(d, t);
-}
-
-QDateTime QDateTime::currentDateTimeUtc()
-{
- QDate d;
- QTime t;
- SYSTEMTIME st;
- memset(&st, 0, sizeof(SYSTEMTIME));
- GetSystemTime(&st);
- d.jd = julianDayFromDate(st.wYear, st.wMonth, st.wDay);
- t.mds = msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
- return QDateTime(d, t, Qt::UTC);
-}
-
-qint64 QDateTime::currentMSecsSinceEpoch() noexcept
-{
- SYSTEMTIME st;
- memset(&st, 0, sizeof(SYSTEMTIME));
- GetSystemTime(&st);
-
- return msecsFromDecomposed(st.wHour, st.wMinute, st.wSecond, st.wMilliseconds) +
- qint64(julianDayFromDate(st.wYear, st.wMonth, st.wDay)
- - julianDayFromDate(1970, 1, 1)) * Q_INT64_C(86400000);
-}
-
-qint64 QDateTime::currentSecsSinceEpoch() noexcept
-{
- SYSTEMTIME st;
- memset(&st, 0, sizeof(SYSTEMTIME));
- GetSystemTime(&st);
-
- return st.wHour * SECS_PER_HOUR + st.wMinute * SECS_PER_MIN + st.wSecond +
- qint64(julianDayFromDate(st.wYear, st.wMonth, st.wDay)
- - julianDayFromDate(1970, 1, 1)) * Q_INT64_C(86400);
-}
-
-#elif defined(Q_OS_UNIX)
-QDate QDate::currentDate()
-{
- return QDateTime::currentDateTime().date();
-}
-
-QTime QTime::currentTime()
-{
- return QDateTime::currentDateTime().time();
-}
-
-QDateTime QDateTime::currentDateTime()
-{
- return fromMSecsSinceEpoch(currentMSecsSinceEpoch(), Qt::LocalTime);
-}
-
-QDateTime QDateTime::currentDateTimeUtc()
-{
- return fromMSecsSinceEpoch(currentMSecsSinceEpoch(), Qt::UTC);
-}
-
-qint64 QDateTime::currentMSecsSinceEpoch() noexcept
-{
- // posix compliant system
- // we have milliseconds
- struct timeval tv;
- gettimeofday(&tv, 0);
- return qint64(tv.tv_sec) * Q_INT64_C(1000) + tv.tv_usec / 1000;
-}
-
-qint64 QDateTime::currentSecsSinceEpoch() noexcept
-{
- struct timeval tv;
- gettimeofday(&tv, 0);
- return qint64(tv.tv_sec);
-}
-#else
-#error "What system is this?"
-#endif
-
-#if QT_DEPRECATED_SINCE(5, 8)
-/*!
- \since 4.2
- \deprecated
-
- Returns a datetime whose date and time are the number of \a seconds
- that have passed since 1970-01-01T00:00:00, Coordinated Universal
- Time (Qt::UTC) and converted to Qt::LocalTime. On systems that do not
- support time zones, the time will be set as if local time were Qt::UTC.
-
- \note This function is deprecated. Please use fromSecsSinceEpoch() in new
- code.
-
- \sa toTime_t(), setTime_t()
-*/
-QDateTime QDateTime::fromTime_t(uint seconds)
-{
- return fromMSecsSinceEpoch((qint64)seconds * 1000, Qt::LocalTime);
-}
-
-/*!
- \since 5.2
- \deprecated
-
- Returns a datetime whose date and time are the number of \a seconds
- that have passed since 1970-01-01T00:00:00, Coordinated Universal
- Time (Qt::UTC) and converted to the given \a spec.
-
- If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be
- ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0
- then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds.
-
- \note This function is deprecated. Please use fromSecsSinceEpoch() in new
- code.
-
- \sa toTime_t(), setTime_t()
-*/
-QDateTime QDateTime::fromTime_t(uint seconds, Qt::TimeSpec spec, int offsetSeconds)
-{
- return fromMSecsSinceEpoch((qint64)seconds * 1000, spec, offsetSeconds);
-}
-
-#if QT_CONFIG(timezone)
-/*!
- \since 5.2
- \deprecated
-
- Returns a datetime whose date and time are the number of \a seconds
- that have passed since 1970-01-01T00:00:00, Coordinated Universal
- Time (Qt::UTC) and with the given \a timeZone.
-
- \note This function is deprecated. Please use fromSecsSinceEpoch() in new
- code.
-
- \sa toTime_t(), setTime_t()
-*/
-QDateTime QDateTime::fromTime_t(uint seconds, const QTimeZone &timeZone)
-{
- return fromMSecsSinceEpoch((qint64)seconds * 1000, timeZone);
-}
-#endif
-#endif // QT_DEPRECATED_SINCE(5, 8)
-
-/*!
- \since 4.7
-
- Returns a datetime whose date and time are the number of milliseconds, \a msecs,
- that have passed since 1970-01-01T00:00:00.000, Coordinated Universal
- Time (Qt::UTC), and converted to Qt::LocalTime. On systems that do not
- support time zones, the time will be set as if local time were Qt::UTC.
-
- Note that there are possible values for \a msecs that lie outside the valid
- range of QDateTime, both negative and positive. The behavior of this
- function is undefined for those values.
-
- \sa toMSecsSinceEpoch(), setMSecsSinceEpoch()
-*/
-QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs)
-{
- return fromMSecsSinceEpoch(msecs, Qt::LocalTime);
-}
-
-/*!
- \since 5.2
-
- Returns a datetime whose date and time are the number of milliseconds \a msecs
- that have passed since 1970-01-01T00:00:00.000, Coordinated Universal
- Time (Qt::UTC) and converted to the given \a spec.
-
- Note that there are possible values for \a msecs that lie outside the valid
- range of QDateTime, both negative and positive. The behavior of this
- function is undefined for those values.
-
- If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be
- ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0
- then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds.
-
- If \a spec is Qt::TimeZone then the spec will be set to Qt::LocalTime,
- i.e. the current system time zone.
-
- \sa toMSecsSinceEpoch(), setMSecsSinceEpoch()
-*/
-QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetSeconds)
-{
- QDateTime dt;
- QT_PREPEND_NAMESPACE(setTimeSpec(dt.d, spec, offsetSeconds));
- dt.setMSecsSinceEpoch(msecs);
- return dt;
-}
-
-/*!
- \since 5.8
-
- Returns a datetime whose date and time are the number of seconds \a secs
- that have passed since 1970-01-01T00:00:00.000, Coordinated Universal
- Time (Qt::UTC) and converted to the given \a spec.
-
- Note that there are possible values for \a secs that lie outside the valid
- range of QDateTime, both negative and positive. The behavior of this
- function is undefined for those values.
-
- If the \a spec is not Qt::OffsetFromUTC then the \a offsetSeconds will be
- ignored. If the \a spec is Qt::OffsetFromUTC and the \a offsetSeconds is 0
- then the spec will be set to Qt::UTC, i.e. an offset of 0 seconds.
-
- If \a spec is Qt::TimeZone then the spec will be set to Qt::LocalTime,
- i.e. the current system time zone.
-
- \sa toSecsSinceEpoch(), setSecsSinceEpoch()
-*/
-QDateTime QDateTime::fromSecsSinceEpoch(qint64 secs, Qt::TimeSpec spec, int offsetSeconds)
-{
- return fromMSecsSinceEpoch(secs * 1000, spec, offsetSeconds);
-}
-
-#if QT_CONFIG(timezone)
-/*!
- \since 5.2
-
- Returns a datetime whose date and time are the number of milliseconds \a msecs
- that have passed since 1970-01-01T00:00:00.000, Coordinated Universal
- Time (Qt::UTC) and with the given \a timeZone.
-
- \sa fromSecsSinceEpoch()
-*/
-QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone)
-{
- QDateTime dt;
- dt.setTimeZone(timeZone);
- dt.setMSecsSinceEpoch(msecs);
- return dt;
-}
-
-/*!
- \since 5.8
-
- Returns a datetime whose date and time are the number of seconds \a secs
- that have passed since 1970-01-01T00:00:00.000, Coordinated Universal
- Time (Qt::UTC) and with the given \a timeZone.
-
- \sa fromMSecsSinceEpoch()
-*/
-QDateTime QDateTime::fromSecsSinceEpoch(qint64 secs, const QTimeZone &timeZone)
-{
- return fromMSecsSinceEpoch(secs * 1000, timeZone);
-}
-#endif
-
-#if QT_DEPRECATED_SINCE(5, 2)
-/*!
- \since 4.4
- \internal
- \obsolete
-
- This method was added in 4.4 but never documented as public. It was replaced
- in 5.2 with public method setOffsetFromUtc() for consistency with QTimeZone.
-
- This method should never be made public.
-
- \sa setOffsetFromUtc()
- */
-void QDateTime::setUtcOffset(int seconds)
-{
- setOffsetFromUtc(seconds);
-}
-
-/*!
- \since 4.4
- \internal
- \obsolete
-
- This method was added in 4.4 but never documented as public. It was replaced
- in 5.1 with public method offsetFromUTC() for consistency with QTimeZone.
-
- This method should never be made public.
-
- \sa offsetFromUTC()
-*/
-int QDateTime::utcOffset() const
-{
- return offsetFromUtc();
-}
-#endif // QT_DEPRECATED_SINCE
-
-#if QT_CONFIG(datestring)
-
-/*!
- Returns the QDateTime represented by the \a string, using the
- \a format given, or an invalid datetime if this is not possible.
-
- Note for Qt::TextDate: It is recommended that you use the
- English short month names (e.g. "Jan"). Although localized month
- names can also be used, they depend on the user's locale settings.
-
- \sa toString(), QLocale::toDateTime()
-*/
-QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
-{
- if (string.isEmpty())
- return QDateTime();
-
- switch (format) {
- case Qt::SystemLocaleDate:
- case Qt::SystemLocaleShortDate:
- return QLocale::system().toDateTime(string, QLocale::ShortFormat);
- case Qt::SystemLocaleLongDate:
- return QLocale::system().toDateTime(string, QLocale::LongFormat);
- case Qt::LocaleDate:
- case Qt::DefaultLocaleShortDate:
- return QLocale().toDateTime(string, QLocale::ShortFormat);
- case Qt::DefaultLocaleLongDate:
- return QLocale().toDateTime(string, QLocale::LongFormat);
- case Qt::RFC2822Date: {
- const ParsedRfcDateTime rfc = rfcDateImpl(string);
-
- if (!rfc.date.isValid() || !rfc.time.isValid())
- return QDateTime();
-
- QDateTime dateTime(rfc.date, rfc.time, Qt::UTC);
- dateTime.setOffsetFromUtc(rfc.utcOffset);
- return dateTime;
- }
- case Qt::ISODate:
- case Qt::ISODateWithMs: {
- const int size = string.size();
- if (size < 10)
- return QDateTime();
-
- QDate date = QDate::fromString(string.left(10), Qt::ISODate);
- if (!date.isValid())
- return QDateTime();
- if (size == 10)
- return QDateTime(date);
-
- Qt::TimeSpec spec = Qt::LocalTime;
- QStringRef isoString(&string);
- isoString = isoString.mid(10); // trim "yyyy-MM-dd"
-
- // Must be left with T and at least one digit for the hour:
- if (isoString.size() < 2
- || !(isoString.startsWith(QLatin1Char('T'))
- // FIXME: QSql relies on QVariant::toDateTime() accepting a space here:
- || isoString.startsWith(QLatin1Char(' ')))) {
- return QDateTime();
- }
- isoString = isoString.mid(1); // trim 'T' (or space)
-
- int offset = 0;
- // Check end of string for Time Zone definition, either Z for UTC or [+-]HH:mm for Offset
- if (isoString.endsWith(QLatin1Char('Z'))) {
- spec = Qt::UTC;
- isoString.chop(1); // trim 'Z'
- } else {
- // the loop below is faster but functionally equal to:
- // const int signIndex = isoString.indexOf(QRegExp(QStringLiteral("[+-]")));
- int signIndex = isoString.size() - 1;
- Q_ASSERT(signIndex >= 0);
- bool found = false;
- {
- const QChar plus = QLatin1Char('+');
- const QChar minus = QLatin1Char('-');
- do {
- QChar character(isoString.at(signIndex));
- found = character == plus || character == minus;
- } while (!found && --signIndex >= 0);
- }
-
- if (found) {
- bool ok;
- offset = fromOffsetString(isoString.mid(signIndex), &ok);
- if (!ok)
- return QDateTime();
- isoString = isoString.left(signIndex);
- spec = Qt::OffsetFromUTC;
- }
- }
-
- // Might be end of day (24:00, including variants), which QTime considers invalid.
- // ISO 8601 (section 4.2.3) says that 24:00 is equivalent to 00:00 the next day.
- bool isMidnight24 = false;
- QTime time = fromIsoTimeString(isoString, format, &isMidnight24);
- if (!time.isValid())
- return QDateTime();
- if (isMidnight24)
- date = date.addDays(1);
- return QDateTime(date, time, spec, offset);
- }
-#if QT_CONFIG(textdate)
- case Qt::TextDate: {
- QVector<QStringRef> parts = string.splitRef(QLatin1Char(' '), QString::SkipEmptyParts);
-
- if ((parts.count() < 5) || (parts.count() > 6))
- return QDateTime();
-
- // Accept "Sun Dec 1 13:02:00 1974" and "Sun 1. Dec 13:02:00 1974"
- int month = 0;
- int day = 0;
- bool ok = false;
-
- // First try month then day
- month = fromShortMonthName(parts.at(1));
- if (month)
- day = parts.at(2).toInt();
-
- // If failed try day then month
- if (!month || !day) {
- month = fromShortMonthName(parts.at(2));
- if (month) {
- QStringRef dayStr = parts.at(1);
- if (dayStr.endsWith(QLatin1Char('.'))) {
- dayStr = dayStr.left(dayStr.size() - 1);
- day = dayStr.toInt();
- }
- }
- }
-
- // If both failed, give up
- if (!month || !day)
- return QDateTime();
-
- // Year can be before or after time, "Sun Dec 1 1974 13:02:00" or "Sun Dec 1 13:02:00 1974"
- // Guess which by looking for ':' in the time
- int year = 0;
- int yearPart = 0;
- int timePart = 0;
- if (parts.at(3).contains(QLatin1Char(':'))) {
- yearPart = 4;
- timePart = 3;
- } else if (parts.at(4).contains(QLatin1Char(':'))) {
- yearPart = 3;
- timePart = 4;
- } else {
- return QDateTime();
- }
-
- year = parts.at(yearPart).toInt(&ok);
- if (!ok)
- return QDateTime();
-
- QDate date(year, month, day);
- if (!date.isValid())
- return QDateTime();
-
- QVector<QStringRef> timeParts = parts.at(timePart).split(QLatin1Char(':'));
- if (timeParts.count() < 2 || timeParts.count() > 3)
- return QDateTime();
-
- int hour = timeParts.at(0).toInt(&ok);
- if (!ok)
- return QDateTime();
-
- int minute = timeParts.at(1).toInt(&ok);
- if (!ok)
- return QDateTime();
-
- int second = 0;
- int millisecond = 0;
- if (timeParts.count() > 2) {
- const QVector<QStringRef> secondParts = timeParts.at(2).split(QLatin1Char('.'));
- if (secondParts.size() > 2) {
- return QDateTime();
- }
-
- second = secondParts.first().toInt(&ok);
- if (!ok) {
- return QDateTime();
- }
-
- if (secondParts.size() > 1) {
- millisecond = secondParts.last().toInt(&ok);
- if (!ok) {
- return QDateTime();
- }
- }
- }
-
- QTime time(hour, minute, second, millisecond);
- if (!time.isValid())
- return QDateTime();
-
- if (parts.count() == 5)
- return QDateTime(date, time, Qt::LocalTime);
-
- QStringRef tz = parts.at(5);
- if (!tz.startsWith(QLatin1String("GMT"), Qt::CaseInsensitive))
- return QDateTime();
- tz = tz.mid(3);
- if (!tz.isEmpty()) {
- int offset = fromOffsetString(tz, &ok);
- if (!ok)
- return QDateTime();
- return QDateTime(date, time, Qt::OffsetFromUTC, offset);
- } else {
- return QDateTime(date, time, Qt::UTC);
- }
- }
-#endif // textdate
- }
-
- return QDateTime();
-}
-
-/*!
- Returns the QDateTime represented by the \a string, using the \a
- format given, or an invalid datetime if the string cannot be parsed.
-
- These expressions may be used for the date part of the format string:
-
- \table
- \header \li Expression \li Output
- \row \li d \li the day as number without a leading zero (1 to 31)
- \row \li dd \li the day as number with a leading zero (01 to 31)
- \row \li ddd
- \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
- Uses QDate::shortDayName().
- \row \li dddd
- \li the long localized day name (e.g. 'Monday' to 'Sunday').
- Uses QDate::longDayName().
- \row \li M \li the month as number without a leading zero (1-12)
- \row \li MM \li the month as number with a leading zero (01-12)
- \row \li MMM
- \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
- Uses QDate::shortMonthName().
- \row \li MMMM
- \li the long localized month name (e.g. 'January' to 'December').
- Uses QDate::longMonthName().
- \row \li yy \li the year as two digit number (00-99)
- \row \li yyyy \li the year as four digit number
- \endtable
-
- \note Unlike the other version of this function, day and month names must
- be given in the user's local language. It is only possible to use the English
- names if the user's language is English.
-
- These expressions may be used for the time part of the format string:
-
- \table
- \header \li Expression \li Output
- \row \li h
- \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \li hh
- \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \li H
- \li the hour without a leading zero (0 to 23, even with AM/PM display)
- \row \li HH
- \li the hour with a leading zero (00 to 23, even with AM/PM display)
- \row \li m \li the minute without a leading zero (0 to 59)
- \row \li mm \li the minute with a leading zero (00 to 59)
- \row \li s \li the whole second without a leading zero (0 to 59)
- \row \li ss \li the whole second with a leading zero where applicable (00 to 59)
- \row \li z \li the fractional part of the second, to go after a decimal
- point, without trailing zeroes (0 to 999). Thus "\c{s.z}"
- reports the seconds to full available (millisecond) precision
- without trailing zeroes.
- \row \li zzz \li the fractional part of the second, to millisecond
- precision, including trailing zeroes where applicable (000 to 999).
- \row \li AP or A
- \li interpret as an AM/PM time. \e AP must be either "AM" or "PM".
- \row \li ap or a
- \li Interpret as an AM/PM time. \e ap must be either "am" or "pm".
- \endtable
-
- All other input characters will be treated as text. Any sequence
- of characters that are enclosed in single quotes will also be
- treated as text and not be used as an expression.
-
- \snippet code/src_corelib_tools_qdatetime.cpp 12
-
- If the format is not satisfied, an invalid QDateTime is returned.
- The expressions that don't have leading zeroes (d, M, h, m, s, z) will be
- greedy. This means that they will use two digits even if this will
- put them outside the range and/or leave too few digits for other
- sections.
-
- \snippet code/src_corelib_tools_qdatetime.cpp 13
-
- This could have meant 1 January 00:30.00 but the M will grab
- two digits.
-
- Incorrectly specified fields of the \a string will cause an invalid
- QDateTime to be returned. For example, consider the following code,
- where the two digit year 12 is read as 1912 (see the table below for all
- field defaults); the resulting datetime is invalid because 23 April 1912
- was a Tuesday, not a Monday:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 20
-
- The correct code is:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 21
-
- For any field that is not represented in the format, the following
- defaults are used:
-
- \table
- \header \li Field \li Default value
- \row \li Year \li 1900
- \row \li Month \li 1 (January)
- \row \li Day \li 1
- \row \li Hour \li 0
- \row \li Minute \li 0
- \row \li Second \li 0
- \endtable
-
- For example:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 14
-
- \sa toString(), QDate::fromString(), QTime::fromString(),
- QLocale::toDateTime()
-*/
-
-QDateTime QDateTime::fromString(const QString &string, const QString &format)
-{
-#if QT_CONFIG(datetimeparser)
- QTime time;
- QDate date;
-
- QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString);
- // dt.setDefaultLocale(QLocale::c()); ### Qt 6
- if (dt.parseFormat(format) && dt.fromString(string, &date, &time))
- return QDateTime(date, time);
-#else
- Q_UNUSED(string);
- Q_UNUSED(format);
-#endif
- return QDateTime();
-}
-
-#endif // datestring
-/*!
- \fn QDateTime QDateTime::toLocalTime() const
-
- Returns a datetime containing the date and time information in
- this datetime, but specified using the Qt::LocalTime definition.
-
- Example:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 17
-
- \sa toTimeSpec()
-*/
-
-/*!
- \fn QDateTime QDateTime::toUTC() const
-
- Returns a datetime containing the date and time information in
- this datetime, but specified using the Qt::UTC definition.
-
- Example:
-
- \snippet code/src_corelib_tools_qdatetime.cpp 18
-
- \sa toTimeSpec()
-*/
-
-/*****************************************************************************
- Date/time stream functions
- *****************************************************************************/
-
-#ifndef QT_NO_DATASTREAM
-/*!
- \relates QDate
-
- Writes the \a date to stream \a out.
-
- \sa {Serializing Qt Data Types}
-*/
-
-QDataStream &operator<<(QDataStream &out, const QDate &date)
-{
- if (out.version() < QDataStream::Qt_5_0)
- return out << quint32(date.jd);
- else
- return out << qint64(date.jd);
-}
-
-/*!
- \relates QDate
-
- Reads a date from stream \a in into the \a date.
-
- \sa {Serializing Qt Data Types}
-*/
-
-QDataStream &operator>>(QDataStream &in, QDate &date)
-{
- if (in.version() < QDataStream::Qt_5_0) {
- quint32 jd;
- in >> jd;
- // Older versions consider 0 an invalid jd.
- date.jd = (jd != 0 ? jd : QDate::nullJd());
- } else {
- qint64 jd;
- in >> jd;
- date.jd = jd;
- }
-
- return in;
-}
-
-/*!
- \relates QTime
-
- Writes \a time to stream \a out.
-
- \sa {Serializing Qt Data Types}
-*/
-
-QDataStream &operator<<(QDataStream &out, const QTime &time)
-{
- if (out.version() >= QDataStream::Qt_4_0) {
- return out << quint32(time.mds);
- } else {
- // Qt3 had no support for reading -1, QTime() was valid and serialized as 0
- return out << quint32(time.isNull() ? 0 : time.mds);
- }
-}
-
-/*!
- \relates QTime
-
- Reads a time from stream \a in into the given \a time.
-
- \sa {Serializing Qt Data Types}
-*/
-
-QDataStream &operator>>(QDataStream &in, QTime &time)
-{
- quint32 ds;
- in >> ds;
- if (in.version() >= QDataStream::Qt_4_0) {
- time.mds = int(ds);
- } else {
- // Qt3 would write 0 for a null time
- time.mds = (ds == 0) ? QTime::NullTime : int(ds);
- }
- return in;
-}
-
-/*!
- \relates QDateTime
-
- Writes \a dateTime to the \a out stream.
-
- \sa {Serializing Qt Data Types}
-*/
-QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime)
-{
- QPair<QDate, QTime> dateAndTime;
-
- if (out.version() >= QDataStream::Qt_5_2) {
-
- // In 5.2 we switched to using Qt::TimeSpec and added offset support
- dateAndTime = getDateTime(dateTime.d);
- out << dateAndTime << qint8(dateTime.timeSpec());
- if (dateTime.timeSpec() == Qt::OffsetFromUTC)
- out << qint32(dateTime.offsetFromUtc());
-#if QT_CONFIG(timezone)
- else if (dateTime.timeSpec() == Qt::TimeZone)
- out << dateTime.timeZone();
-#endif // timezone
-
- } else if (out.version() == QDataStream::Qt_5_0) {
-
- // In Qt 5.0 we incorrectly serialised all datetimes as UTC.
- // This approach is wrong and should not be used again; it breaks
- // the guarantee that a deserialised local datetime is the same time
- // of day, regardless of which timezone it was serialised in.
- dateAndTime = getDateTime((dateTime.isValid() ? dateTime.toUTC() : dateTime).d);
- out << dateAndTime << qint8(dateTime.timeSpec());
-
- } else if (out.version() >= QDataStream::Qt_4_0) {
-
- // From 4.0 to 5.1 (except 5.0) we used QDateTimePrivate::Spec
- dateAndTime = getDateTime(dateTime.d);
- out << dateAndTime;
- switch (dateTime.timeSpec()) {
- case Qt::UTC:
- out << (qint8)QDateTimePrivate::UTC;
- break;
- case Qt::OffsetFromUTC:
- out << (qint8)QDateTimePrivate::OffsetFromUTC;
- break;
- case Qt::TimeZone:
- out << (qint8)QDateTimePrivate::TimeZone;
- break;
- case Qt::LocalTime:
- out << (qint8)QDateTimePrivate::LocalUnknown;
- break;
- }
-
- } else { // version < QDataStream::Qt_4_0
-
- // Before 4.0 there was no TimeSpec, only Qt::LocalTime was supported
- dateAndTime = getDateTime(dateTime.d);
- out << dateAndTime;
-
- }
-
- return out;
-}
-
-/*!
- \relates QDateTime
-
- Reads a datetime from the stream \a in into \a dateTime.
-
- \sa {Serializing Qt Data Types}
-*/
-
-QDataStream &operator>>(QDataStream &in, QDateTime &dateTime)
-{
- QDate dt;
- QTime tm;
- qint8 ts = 0;
- Qt::TimeSpec spec = Qt::LocalTime;
- qint32 offset = 0;
-#if QT_CONFIG(timezone)
- QTimeZone tz;
-#endif // timezone
-
- if (in.version() >= QDataStream::Qt_5_2) {
-
- // In 5.2 we switched to using Qt::TimeSpec and added offset support
- in >> dt >> tm >> ts;
- spec = static_cast<Qt::TimeSpec>(ts);
- if (spec == Qt::OffsetFromUTC) {
- in >> offset;
- dateTime = QDateTime(dt, tm, spec, offset);
-#if QT_CONFIG(timezone)
- } else if (spec == Qt::TimeZone) {
- in >> tz;
- dateTime = QDateTime(dt, tm, tz);
-#endif // timezone
- } else {
- dateTime = QDateTime(dt, tm, spec);
- }
-
- } else if (in.version() == QDataStream::Qt_5_0) {
-
- // In Qt 5.0 we incorrectly serialised all datetimes as UTC
- in >> dt >> tm >> ts;
- spec = static_cast<Qt::TimeSpec>(ts);
- dateTime = QDateTime(dt, tm, Qt::UTC);
- dateTime = dateTime.toTimeSpec(spec);
-
- } else if (in.version() >= QDataStream::Qt_4_0) {
-
- // From 4.0 to 5.1 (except 5.0) we used QDateTimePrivate::Spec
- in >> dt >> tm >> ts;
- switch ((QDateTimePrivate::Spec)ts) {
- case QDateTimePrivate::UTC:
- spec = Qt::UTC;
- break;
- case QDateTimePrivate::OffsetFromUTC:
- spec = Qt::OffsetFromUTC;
- break;
- case QDateTimePrivate::TimeZone:
- spec = Qt::TimeZone;
-#if QT_CONFIG(timezone)
- // FIXME: need to use a different constructor !
-#endif
- break;
- case QDateTimePrivate::LocalUnknown:
- case QDateTimePrivate::LocalStandard:
- case QDateTimePrivate::LocalDST:
- spec = Qt::LocalTime;
- break;
- }
- dateTime = QDateTime(dt, tm, spec, offset);
-
- } else { // version < QDataStream::Qt_4_0
-
- // Before 4.0 there was no TimeSpec, only Qt::LocalTime was supported
- in >> dt >> tm;
- dateTime = QDateTime(dt, tm, spec, offset);
-
- }
-
- return in;
-}
-#endif // QT_NO_DATASTREAM
-
-/*****************************************************************************
- Date / Time Debug Streams
-*****************************************************************************/
-
-#if !defined(QT_NO_DEBUG_STREAM) && QT_CONFIG(datestring)
-QDebug operator<<(QDebug dbg, const QDate &date)
-{
- QDebugStateSaver saver(dbg);
- dbg.nospace() << "QDate(";
- if (date.isValid())
- dbg.nospace() << date.toString(Qt::ISODate);
- else
- dbg.nospace() << "Invalid";
- dbg.nospace() << ')';
- return dbg;
-}
-
-QDebug operator<<(QDebug dbg, const QTime &time)
-{
- QDebugStateSaver saver(dbg);
- dbg.nospace() << "QTime(";
- if (time.isValid())
- dbg.nospace() << time.toString(QStringViewLiteral("HH:mm:ss.zzz"));
- else
- dbg.nospace() << "Invalid";
- dbg.nospace() << ')';
- return dbg;
-}
-
-QDebug operator<<(QDebug dbg, const QDateTime &date)
-{
- QDebugStateSaver saver(dbg);
- dbg.nospace() << "QDateTime(";
- if (date.isValid()) {
- const Qt::TimeSpec ts = date.timeSpec();
- dbg.noquote() << date.toString(QStringViewLiteral("yyyy-MM-dd HH:mm:ss.zzz t"))
- << ' ' << ts;
- switch (ts) {
- case Qt::UTC:
- break;
- case Qt::OffsetFromUTC:
- dbg.space() << date.offsetFromUtc() << 's';
- break;
- case Qt::TimeZone:
-#if QT_CONFIG(timezone)
- dbg.space() << date.timeZone().id();
-#endif // timezone
- break;
- case Qt::LocalTime:
- break;
- }
- } else {
- dbg.nospace() << "Invalid";
- }
- return dbg.nospace() << ')';
-}
-#endif // debug_stream && datestring
-
-/*! \fn uint qHash(const QDateTime &key, uint seed = 0)
- \relates QHash
- \since 5.0
-
- Returns the hash value for the \a key, using \a seed to seed the calculation.
-*/
-uint qHash(const QDateTime &key, uint seed)
-{
- // Use to toMSecsSinceEpoch instead of individual qHash functions for
- // QDate/QTime/spec/offset because QDateTime::operator== converts both arguments
- // to the same timezone. If we don't, qHash would return different hashes for
- // two QDateTimes that are equivalent once converted to the same timezone.
- return qHash(key.toMSecsSinceEpoch(), seed);
-}
-
-/*! \fn uint qHash(const QDate &key, uint seed = 0)
- \relates QHash
- \since 5.0
-
- Returns the hash value for the \a key, using \a seed to seed the calculation.
-*/
-uint qHash(const QDate &key, uint seed) noexcept
-{
- return qHash(key.toJulianDay(), seed);
-}
-
-/*! \fn uint qHash(const QTime &key, uint seed = 0)
- \relates QHash
- \since 5.0
-
- Returns the hash value for the \a key, using \a seed to seed the calculation.
-*/
-uint qHash(const QTime &key, uint seed) noexcept
-{
- return qHash(key.msecsSinceStartOfDay(), seed);
-}
-
-QT_END_NAMESPACE
diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h
deleted file mode 100644
index 3e3b953b52..0000000000
--- a/src/corelib/tools/qdatetime.h
+++ /dev/null
@@ -1,426 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDATETIME_H
-#define QDATETIME_H
-
-#include <QtCore/qstring.h>
-#include <QtCore/qnamespace.h>
-#include <QtCore/qshareddata.h>
-
-#include <limits>
-
-#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
-Q_FORWARD_DECLARE_CF_TYPE(CFDate);
-Q_FORWARD_DECLARE_OBJC_CLASS(NSDate);
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QTimeZone;
-class QDateTime;
-
-class Q_CORE_EXPORT QDate
-{
-public:
- enum MonthNameType { // ### Qt 6: remove, along with methods using it
- DateFormat = 0,
- StandaloneFormat
- };
-private:
- explicit Q_DECL_CONSTEXPR QDate(qint64 julianDay) : jd(julianDay) {}
-public:
- Q_DECL_CONSTEXPR QDate() : jd(nullJd()) {}
- QDate(int y, int m, int d);
-
- Q_DECL_CONSTEXPR bool isNull() const { return !isValid(); }
- Q_DECL_CONSTEXPR bool isValid() const { return jd >= minJd() && jd <= maxJd(); }
-
- int year() const;
- int month() const;
- int day() const;
- int dayOfWeek() const;
- int dayOfYear() const;
- int daysInMonth() const;
- int daysInYear() const;
- int weekNumber(int *yearNum = nullptr) const;
-
- QDateTime startOfDay(Qt::TimeSpec spec = Qt::LocalTime, int offsetSeconds = 0) const;
- QDateTime endOfDay(Qt::TimeSpec spec = Qt::LocalTime, int offsetSeconds = 0) const;
-#if QT_CONFIG(timezone)
- QDateTime startOfDay(const QTimeZone &zone) const;
- QDateTime endOfDay(const QTimeZone &zone) const;
-#endif
-
-#if QT_DEPRECATED_SINCE(5, 10) && QT_CONFIG(textdate)
- QT_DEPRECATED_X("Use QLocale::monthName or QLocale::standaloneMonthName")
- static QString shortMonthName(int month, MonthNameType type = DateFormat);
- QT_DEPRECATED_X("Use QLocale::dayName or QLocale::standaloneDayName")
- static QString shortDayName(int weekday, MonthNameType type = DateFormat);
- QT_DEPRECATED_X("Use QLocale::monthName or QLocale::standaloneMonthName")
- static QString longMonthName(int month, MonthNameType type = DateFormat);
- QT_DEPRECATED_X("Use QLocale::dayName or QLocale::standaloneDayName")
- static QString longDayName(int weekday, MonthNameType type = DateFormat);
-#endif // textdate && deprecated
-#if QT_CONFIG(datestring)
- QString toString(Qt::DateFormat f = Qt::TextDate) const;
-#if QT_STRINGVIEW_LEVEL < 2
- QString toString(const QString &format) const;
-#endif
- QString toString(QStringView format) const;
-#endif
-#if QT_DEPRECATED_SINCE(5,0)
- QT_DEPRECATED_X("Use setDate() instead") inline bool setYMD(int y, int m, int d)
- { if (uint(y) <= 99) y += 1900; return setDate(y, m, d); }
-#endif
-
- bool setDate(int year, int month, int day);
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- void getDate(int *year, int *month, int *day); // ### Qt 6: remove
-#endif // < Qt 6
- void getDate(int *year, int *month, int *day) const;
-
- Q_REQUIRED_RESULT QDate addDays(qint64 days) const;
- Q_REQUIRED_RESULT QDate addMonths(int months) const;
- Q_REQUIRED_RESULT QDate addYears(int years) const;
- qint64 daysTo(const QDate &) const;
-
- Q_DECL_CONSTEXPR bool operator==(const QDate &other) const { return jd == other.jd; }
- Q_DECL_CONSTEXPR bool operator!=(const QDate &other) const { return jd != other.jd; }
- Q_DECL_CONSTEXPR bool operator< (const QDate &other) const { return jd < other.jd; }
- Q_DECL_CONSTEXPR bool operator<=(const QDate &other) const { return jd <= other.jd; }
- Q_DECL_CONSTEXPR bool operator> (const QDate &other) const { return jd > other.jd; }
- Q_DECL_CONSTEXPR bool operator>=(const QDate &other) const { return jd >= other.jd; }
-
- static QDate currentDate();
-#if QT_CONFIG(datestring)
- static QDate fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
- static QDate fromString(const QString &s, const QString &format);
-#endif
- static bool isValid(int y, int m, int d);
- static bool isLeapYear(int year);
-
- static Q_DECL_CONSTEXPR inline QDate fromJulianDay(qint64 jd_)
- { return jd_ >= minJd() && jd_ <= maxJd() ? QDate(jd_) : QDate() ; }
- Q_DECL_CONSTEXPR inline qint64 toJulianDay() const { return jd; }
-
-private:
- // using extra parentheses around min to avoid expanding it if it is a macro
- static Q_DECL_CONSTEXPR inline qint64 nullJd() { return (std::numeric_limits<qint64>::min)(); }
- static Q_DECL_CONSTEXPR inline qint64 minJd() { return Q_INT64_C(-784350574879); }
- static Q_DECL_CONSTEXPR inline qint64 maxJd() { return Q_INT64_C( 784354017364); }
-
- qint64 jd;
-
- friend class QDateTime;
- friend class QDateTimePrivate;
-#ifndef QT_NO_DATASTREAM
- friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDate &);
- friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDate &);
-#endif
-};
-Q_DECLARE_TYPEINFO(QDate, Q_MOVABLE_TYPE);
-
-class Q_CORE_EXPORT QTime
-{
- explicit Q_DECL_CONSTEXPR QTime(int ms) : mds(ms)
- {}
-public:
- Q_DECL_CONSTEXPR QTime(): mds(NullTime)
- {}
- QTime(int h, int m, int s = 0, int ms = 0);
-
- Q_DECL_CONSTEXPR bool isNull() const { return mds == NullTime; }
- bool isValid() const;
-
- int hour() const;
- int minute() const;
- int second() const;
- int msec() const;
-#if QT_CONFIG(datestring)
- QString toString(Qt::DateFormat f = Qt::TextDate) const;
-#if QT_STRINGVIEW_LEVEL < 2
- QString toString(const QString &format) const;
-#endif
- QString toString(QStringView format) const;
-#endif
- bool setHMS(int h, int m, int s, int ms = 0);
-
- Q_REQUIRED_RESULT QTime addSecs(int secs) const;
- int secsTo(const QTime &) const;
- Q_REQUIRED_RESULT QTime addMSecs(int ms) const;
- int msecsTo(const QTime &) const;
-
- Q_DECL_CONSTEXPR bool operator==(const QTime &other) const { return mds == other.mds; }
- Q_DECL_CONSTEXPR bool operator!=(const QTime &other) const { return mds != other.mds; }
- Q_DECL_CONSTEXPR bool operator< (const QTime &other) const { return mds < other.mds; }
- Q_DECL_CONSTEXPR bool operator<=(const QTime &other) const { return mds <= other.mds; }
- Q_DECL_CONSTEXPR bool operator> (const QTime &other) const { return mds > other.mds; }
- Q_DECL_CONSTEXPR bool operator>=(const QTime &other) const { return mds >= other.mds; }
-
- static Q_DECL_CONSTEXPR inline QTime fromMSecsSinceStartOfDay(int msecs) { return QTime(msecs); }
- Q_DECL_CONSTEXPR inline int msecsSinceStartOfDay() const { return mds == NullTime ? 0 : mds; }
-
- static QTime currentTime();
-#if QT_CONFIG(datestring)
- static QTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
- static QTime fromString(const QString &s, const QString &format);
-#endif
- static bool isValid(int h, int m, int s, int ms = 0);
-
-#if QT_DEPRECATED_SINCE(5, 14) // ### Qt 6: remove
- QT_DEPRECATED_X("Use QElapsedTimer instead") void start();
- QT_DEPRECATED_X("Use QElapsedTimer instead") int restart();
- QT_DEPRECATED_X("Use QElapsedTimer instead") int elapsed() const;
-#endif
-private:
- enum TimeFlag { NullTime = -1 };
- Q_DECL_CONSTEXPR inline int ds() const { return mds == -1 ? 0 : mds; }
- int mds;
-
- friend class QDateTime;
- friend class QDateTimePrivate;
-#ifndef QT_NO_DATASTREAM
- friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QTime &);
- friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QTime &);
-#endif
-};
-Q_DECLARE_TYPEINFO(QTime, Q_MOVABLE_TYPE);
-
-class QDateTimePrivate;
-
-class Q_CORE_EXPORT QDateTime
-{
- // ### Qt 6: revisit the optimization
- struct ShortData {
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- quintptr status : 8;
-#endif
- // note: this is only 24 bits on 32-bit systems...
- qintptr msecs : sizeof(void *) * 8 - 8;
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- quintptr status : 8;
-#endif
- };
-
- union Data {
- enum {
- // To be of any use, we need at least 60 years around 1970, which
- // is 1,893,456,000,000 ms. That requires 41 bits to store, plus
- // the sign bit. With the status byte, the minimum size is 50 bits.
- CanBeSmall = sizeof(ShortData) * 8 > 50
- };
-
- Data();
- Data(Qt::TimeSpec);
- Data(const Data &other);
- Data(Data &&other);
- Data &operator=(const Data &other);
- ~Data();
-
- bool isShort() const;
- void detach();
-
- const QDateTimePrivate *operator->() const;
- QDateTimePrivate *operator->();
-
- QDateTimePrivate *d;
- ShortData data;
- };
-
-public:
- QDateTime() noexcept(Data::CanBeSmall);
- explicit QDateTime(const QDate &);
- QDateTime(const QDate &, const QTime &, Qt::TimeSpec spec = Qt::LocalTime);
- // ### Qt 6: Merge with above with default offsetSeconds = 0
- QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds);
-#if QT_CONFIG(timezone)
- QDateTime(const QDate &date, const QTime &time, const QTimeZone &timeZone);
-#endif // timezone
- QDateTime(const QDateTime &other) noexcept;
- QDateTime(QDateTime &&other) noexcept;
- ~QDateTime();
-
- QDateTime &operator=(QDateTime &&other) noexcept { swap(other); return *this; }
- QDateTime &operator=(const QDateTime &other) noexcept;
-
- void swap(QDateTime &other) noexcept { qSwap(d.d, other.d.d); }
-
- bool isNull() const;
- bool isValid() const;
-
- QDate date() const;
- QTime time() const;
- Qt::TimeSpec timeSpec() const;
- int offsetFromUtc() const;
-#if QT_CONFIG(timezone)
- QTimeZone timeZone() const;
-#endif // timezone
- QString timeZoneAbbreviation() const;
- bool isDaylightTime() const;
-
- qint64 toMSecsSinceEpoch() const;
- qint64 toSecsSinceEpoch() const;
-
- void setDate(const QDate &date);
- void setTime(const QTime &time);
- void setTimeSpec(Qt::TimeSpec spec);
- void setOffsetFromUtc(int offsetSeconds);
-#if QT_CONFIG(timezone)
- void setTimeZone(const QTimeZone &toZone);
-#endif // timezone
- void setMSecsSinceEpoch(qint64 msecs);
- void setSecsSinceEpoch(qint64 secs);
-
-#if QT_CONFIG(datestring)
- QString toString(Qt::DateFormat f = Qt::TextDate) const;
-#if QT_STRINGVIEW_LEVEL < 2
- QString toString(const QString &format) const;
-#endif
- QString toString(QStringView format) const;
-#endif
- Q_REQUIRED_RESULT QDateTime addDays(qint64 days) const;
- Q_REQUIRED_RESULT QDateTime addMonths(int months) const;
- Q_REQUIRED_RESULT QDateTime addYears(int years) const;
- Q_REQUIRED_RESULT QDateTime addSecs(qint64 secs) const;
- Q_REQUIRED_RESULT QDateTime addMSecs(qint64 msecs) const;
-
- QDateTime toTimeSpec(Qt::TimeSpec spec) const;
- inline QDateTime toLocalTime() const { return toTimeSpec(Qt::LocalTime); }
- inline QDateTime toUTC() const { return toTimeSpec(Qt::UTC); }
- QDateTime toOffsetFromUtc(int offsetSeconds) const;
-#if QT_CONFIG(timezone)
- QDateTime toTimeZone(const QTimeZone &toZone) const;
-#endif // timezone
-
- qint64 daysTo(const QDateTime &) const;
- qint64 secsTo(const QDateTime &) const;
- qint64 msecsTo(const QDateTime &) const;
-
- bool operator==(const QDateTime &other) const;
- inline bool operator!=(const QDateTime &other) const { return !(*this == other); }
- bool operator<(const QDateTime &other) const;
- inline bool operator<=(const QDateTime &other) const { return !(other < *this); }
- inline bool operator>(const QDateTime &other) const { return other < *this; }
- inline bool operator>=(const QDateTime &other) const { return !(*this < other); }
-
-#if QT_DEPRECATED_SINCE(5, 2) // ### Qt 6: remove
- QT_DEPRECATED_X("Use setOffsetFromUtc() instead") void setUtcOffset(int seconds);
- QT_DEPRECATED_X("Use offsetFromUtc() instead") int utcOffset() const;
-#endif // QT_DEPRECATED_SINCE
-
- static QDateTime currentDateTime();
- static QDateTime currentDateTimeUtc();
-#if QT_CONFIG(datestring)
- static QDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
- static QDateTime fromString(const QString &s, const QString &format);
-#endif
-
-#if QT_DEPRECATED_SINCE(5, 8)
- uint toTime_t() const;
- void setTime_t(uint secsSince1Jan1970UTC);
- static QDateTime fromTime_t(uint secsSince1Jan1970UTC);
- static QDateTime fromTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec,
- int offsetFromUtc = 0);
- static QDateTime fromTime_t(uint secsSince1Jan1970UTC, const QTimeZone &timeZone);
-#endif
-
- static QDateTime fromMSecsSinceEpoch(qint64 msecs);
- // ### Qt 6: Merge with above with default spec = Qt::LocalTime
- static QDateTime fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetFromUtc = 0);
- static QDateTime fromSecsSinceEpoch(qint64 secs, Qt::TimeSpec spe = Qt::LocalTime, int offsetFromUtc = 0);
-
-#if QT_CONFIG(timezone)
- static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone);
- static QDateTime fromSecsSinceEpoch(qint64 secs, const QTimeZone &timeZone);
-#endif
-
- static qint64 currentMSecsSinceEpoch() noexcept;
- static qint64 currentSecsSinceEpoch() noexcept;
-
-#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
- static QDateTime fromCFDate(CFDateRef date);
- CFDateRef toCFDate() const Q_DECL_CF_RETURNS_RETAINED;
- static QDateTime fromNSDate(const NSDate *date);
- NSDate *toNSDate() const Q_DECL_NS_RETURNS_AUTORELEASED;
-#endif
-
-private:
- friend class QDateTimePrivate;
-
- Data d;
-
-#ifndef QT_NO_DATASTREAM
- friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &);
- friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &);
-#endif
-
-#if !defined(QT_NO_DEBUG_STREAM) && QT_CONFIG(datestring)
- friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &);
-#endif
-};
-Q_DECLARE_SHARED(QDateTime)
-
-#ifndef QT_NO_DATASTREAM
-Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDate &);
-Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDate &);
-Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QTime &);
-Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QTime &);
-Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &);
-Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &);
-#endif // QT_NO_DATASTREAM
-
-#if !defined(QT_NO_DEBUG_STREAM) && QT_CONFIG(datestring)
-Q_CORE_EXPORT QDebug operator<<(QDebug, const QDate &);
-Q_CORE_EXPORT QDebug operator<<(QDebug, const QTime &);
-Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &);
-#endif
-
-// QDateTime is not noexcept for now -- to be revised once
-// timezone and calendaring support is added
-Q_CORE_EXPORT uint qHash(const QDateTime &key, uint seed = 0);
-Q_CORE_EXPORT uint qHash(const QDate &key, uint seed = 0) noexcept;
-Q_CORE_EXPORT uint qHash(const QTime &key, uint seed = 0) noexcept;
-
-QT_END_NAMESPACE
-
-#endif // QDATETIME_H
diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h
deleted file mode 100644
index 6018f8f7b0..0000000000
--- a/src/corelib/tools/qdatetime_p.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDATETIME_P_H
-#define QDATETIME_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/private/qglobal_p.h>
-#include "qplatformdefs.h"
-#include "QtCore/qatomic.h"
-#include "QtCore/qdatetime.h"
-#include "QtCore/qpair.h"
-
-#if QT_CONFIG(timezone)
-#include "qtimezone.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QDateTimePrivate
-{
-public:
- // forward the declarations from QDateTime (this makes them public)
- typedef QDateTime::ShortData QDateTimeShortData;
- typedef QDateTime::Data QDateTimeData;
-
- // Never change or delete this enum, it is required for backwards compatible
- // serialization of QDateTime before 5.2, so is essentially public API
- enum Spec {
- LocalUnknown = -1,
- LocalStandard = 0,
- LocalDST = 1,
- UTC = 2,
- OffsetFromUTC = 3,
- TimeZone = 4
- };
-
- // Daylight Time Status
- enum DaylightStatus {
- UnknownDaylightTime = -1,
- StandardTime = 0,
- DaylightTime = 1
- };
-
- // Status of date/time
- enum StatusFlag {
- ShortData = 0x01,
-
- ValidDate = 0x02,
- ValidTime = 0x04,
- ValidDateTime = 0x08,
-
- TimeSpecMask = 0x30,
-
- SetToStandardTime = 0x40,
- SetToDaylightTime = 0x80
- };
- Q_DECLARE_FLAGS(StatusFlags, StatusFlag)
-
- enum {
- TimeSpecShift = 4,
- ValidityMask = ValidDate | ValidTime | ValidDateTime,
- DaylightMask = SetToStandardTime | SetToDaylightTime
- };
-
- QDateTimePrivate() : m_msecs(0),
- m_status(StatusFlag(Qt::LocalTime << TimeSpecShift)),
- m_offsetFromUtc(0),
- ref(0)
- {
- }
-
- static QDateTime::Data create(const QDate &toDate, const QTime &toTime, Qt::TimeSpec toSpec,
- int offsetSeconds);
-
-#if QT_CONFIG(timezone)
- static QDateTime::Data create(const QDate &toDate, const QTime &toTime, const QTimeZone & timeZone);
-#endif // timezone
-
- qint64 m_msecs;
- StatusFlags m_status;
- int m_offsetFromUtc;
- mutable QAtomicInt ref;
-#if QT_CONFIG(timezone)
- QTimeZone m_timeZone;
-#endif // timezone
-
-#if QT_CONFIG(timezone)
- static qint64 zoneMSecsToEpochMSecs(qint64 msecs, const QTimeZone &zone,
- DaylightStatus hint = UnknownDaylightTime,
- QDate *localDate = nullptr, QTime *localTime = nullptr);
-
- // Inlined for its one caller in qdatetime.cpp
- inline void setUtcOffsetByTZ(qint64 atMSecsSinceEpoch);
-#endif // timezone
-
- // ### Qt 5.14: expose publicly in QDateTime
- // The first and last years of which QDateTime can represent some part:
- enum class YearRange : qint32 { First = -292275056, Last = +292278994 };
-};
-
-QT_END_NAMESPACE
-
-#endif // QDATETIME_P_H
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
deleted file mode 100644
index 728b066db1..0000000000
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ /dev/null
@@ -1,2047 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qplatformdefs.h"
-#include "private/qdatetimeparser_p.h"
-
-#include "qdatastream.h"
-#include "qset.h"
-#include "qlocale.h"
-#include "qdatetime.h"
-#if QT_CONFIG(timezone)
-#include "qtimezone.h"
-#endif
-#include "qdebug.h"
-
-//#define QDATETIMEPARSER_DEBUG
-#if defined (QDATETIMEPARSER_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
-# define QDTPDEBUG qDebug()
-# define QDTPDEBUGN qDebug
-#else
-# define QDTPDEBUG if (false) qDebug()
-# define QDTPDEBUGN if (false) qDebug
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QDateTimeParser::~QDateTimeParser()
-{
-}
-
-/*!
- \internal
- Gets the digit from a datetime. E.g.
-
- QDateTime var(QDate(2004, 02, 02));
- int digit = getDigit(var, Year);
- // digit = 2004
-*/
-
-int QDateTimeParser::getDigit(const QDateTime &t, int index) const
-{
- if (index < 0 || index >= sectionNodes.size()) {
-#if QT_CONFIG(datestring)
- qWarning("QDateTimeParser::getDigit() Internal error (%ls %d)",
- qUtf16Printable(t.toString()), index);
-#else
- qWarning("QDateTimeParser::getDigit() Internal error (%d)", index);
-#endif
- return -1;
- }
- const SectionNode &node = sectionNodes.at(index);
- switch (node.type) {
- case TimeZoneSection: return t.offsetFromUtc();
- case Hour24Section: case Hour12Section: return t.time().hour();
- case MinuteSection: return t.time().minute();
- case SecondSection: return t.time().second();
- case MSecSection: return t.time().msec();
- case YearSection2Digits:
- case YearSection: return t.date().year();
- case MonthSection: return t.date().month();
- case DaySection: return t.date().day();
- case DayOfWeekSectionShort:
- case DayOfWeekSectionLong: return t.date().day();
- case AmPmSection: return t.time().hour() > 11 ? 1 : 0;
-
- default: break;
- }
-
-#if QT_CONFIG(datestring)
- qWarning("QDateTimeParser::getDigit() Internal error 2 (%ls %d)",
- qUtf16Printable(t.toString()), index);
-#else
- qWarning("QDateTimeParser::getDigit() Internal error 2 (%d)", index);
-#endif
- return -1;
-}
-
-/*!
- \internal
- Sets a digit in a datetime. E.g.
-
- QDateTime var(QDate(2004, 02, 02));
- int digit = getDigit(var, Year);
- // digit = 2004
- setDigit(&var, Year, 2005);
- digit = getDigit(var, Year);
- // digit = 2005
-*/
-
-bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
-{
- if (index < 0 || index >= sectionNodes.size()) {
-#if QT_CONFIG(datestring)
- qWarning("QDateTimeParser::setDigit() Internal error (%ls %d %d)",
- qUtf16Printable(v.toString()), index, newVal);
-#else
- qWarning("QDateTimeParser::setDigit() Internal error (%d %d)", index, newVal);
-#endif
- return false;
- }
- const SectionNode &node = sectionNodes.at(index);
-
- const QDate date = v.date();
- const QTime time = v.time();
- int year = date.year();
- int month = date.month();
- int day = date.day();
- int hour = time.hour();
- int minute = time.minute();
- int second = time.second();
- int msec = time.msec();
- Qt::TimeSpec tspec = v.timeSpec();
- // Only offset from UTC is amenable to setting an int value:
- int offset = tspec == Qt::OffsetFromUTC ? v.offsetFromUtc() : 0;
-
- switch (node.type) {
- case Hour24Section: case Hour12Section: hour = newVal; break;
- case MinuteSection: minute = newVal; break;
- case SecondSection: second = newVal; break;
- case MSecSection: msec = newVal; break;
- case YearSection2Digits:
- case YearSection: year = newVal; break;
- case MonthSection: month = newVal; break;
- case DaySection:
- case DayOfWeekSectionShort:
- case DayOfWeekSectionLong:
- if (newVal > 31) {
- // have to keep legacy behavior. setting the
- // date to 32 should return false. Setting it
- // to 31 for february should return true
- return false;
- }
- day = newVal;
- break;
- case TimeZoneSection:
- if (newVal < absoluteMin(index) || newVal > absoluteMax(index))
- return false;
- tspec = Qt::OffsetFromUTC;
- offset = newVal;
- break;
- case AmPmSection: hour = (newVal == 0 ? hour % 12 : (hour % 12) + 12); break;
- default:
- qWarning("QDateTimeParser::setDigit() Internal error (%ls)",
- qUtf16Printable(node.name()));
- break;
- }
-
- if (!(node.type & DaySectionMask)) {
- if (day < cachedDay)
- day = cachedDay;
- const int max = QDate(year, month, 1).daysInMonth();
- if (day > max) {
- day = max;
- }
- }
-
- const QDate newDate(year, month, day);
- const QTime newTime(hour, minute, second, msec);
- if (!newDate.isValid() || !newTime.isValid())
- return false;
-
- // Preserve zone:
- v =
-#if QT_CONFIG(timezone)
- tspec == Qt::TimeZone ? QDateTime(newDate, newTime, v.timeZone()) :
-#endif
- QDateTime(newDate, newTime, tspec, offset);
- return true;
-}
-
-
-
-/*!
- \internal
-
- Returns the absolute maximum for a section
-*/
-
-int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
-{
- const SectionNode &sn = sectionNode(s);
- switch (sn.type) {
-#if QT_CONFIG(timezone)
- case TimeZoneSection: return QTimeZone::MaxUtcOffsetSecs;
-#endif
- case Hour24Section:
- case Hour12Section: return 23; // this is special-cased in
- // parseSection. We want it to be
- // 23 for the stepBy case.
- case MinuteSection:
- case SecondSection: return 59;
- case MSecSection: return 999;
- case YearSection2Digits:
- case YearSection: return 9999; // sectionMaxSize will prevent
- // people from typing in a larger
- // number in count == 2 sections.
- // stepBy() will work on real years anyway
- case MonthSection: return 12;
- case DaySection:
- case DayOfWeekSectionShort:
- case DayOfWeekSectionLong: return cur.isValid() ? cur.date().daysInMonth() : 31;
- case AmPmSection: return 1;
- default: break;
- }
- qWarning("QDateTimeParser::absoluteMax() Internal error (%ls)",
- qUtf16Printable(sn.name()));
- return -1;
-}
-
-/*!
- \internal
-
- Returns the absolute minimum for a section
-*/
-
-int QDateTimeParser::absoluteMin(int s) const
-{
- const SectionNode &sn = sectionNode(s);
- switch (sn.type) {
-#if QT_CONFIG(timezone)
- case TimeZoneSection: return QTimeZone::MinUtcOffsetSecs;
-#endif
- case Hour24Section:
- case Hour12Section:
- case MinuteSection:
- case SecondSection:
- case MSecSection:
- case YearSection2Digits:
- case YearSection: return 0;
- case MonthSection:
- case DaySection:
- case DayOfWeekSectionShort:
- case DayOfWeekSectionLong: return 1;
- case AmPmSection: return 0;
- default: break;
- }
- qWarning("QDateTimeParser::absoluteMin() Internal error (%ls, %0x)",
- qUtf16Printable(sn.name()), sn.type);
- return -1;
-}
-
-/*!
- \internal
-
- Returns the sectionNode for the Section \a s.
-*/
-
-const QDateTimeParser::SectionNode &QDateTimeParser::sectionNode(int sectionIndex) const
-{
- if (sectionIndex < 0) {
- switch (sectionIndex) {
- case FirstSectionIndex:
- return first;
- case LastSectionIndex:
- return last;
- case NoSectionIndex:
- return none;
- }
- } else if (sectionIndex < sectionNodes.size()) {
- return sectionNodes.at(sectionIndex);
- }
-
- qWarning("QDateTimeParser::sectionNode() Internal error (%d)",
- sectionIndex);
- return none;
-}
-
-QDateTimeParser::Section QDateTimeParser::sectionType(int sectionIndex) const
-{
- return sectionNode(sectionIndex).type;
-}
-
-
-/*!
- \internal
-
- Returns the starting position for section \a s.
-*/
-
-int QDateTimeParser::sectionPos(int sectionIndex) const
-{
- return sectionPos(sectionNode(sectionIndex));
-}
-
-int QDateTimeParser::sectionPos(const SectionNode &sn) const
-{
- switch (sn.type) {
- case FirstSection: return 0;
- case LastSection: return displayText().size() - 1;
- default: break;
- }
- if (sn.pos == -1) {
- qWarning("QDateTimeParser::sectionPos Internal error (%ls)", qUtf16Printable(sn.name()));
- return -1;
- }
- return sn.pos;
-}
-
-
-/*!
- \internal
-
- helper function for parseFormat. removes quotes that are
- not escaped and removes the escaping on those that are escaped
-
-*/
-
-static QString unquote(const QStringRef &str)
-{
- const QChar quote(QLatin1Char('\''));
- const QChar slash(QLatin1Char('\\'));
- const QChar zero(QLatin1Char('0'));
- QString ret;
- QChar status(zero);
- const int max = str.size();
- for (int i=0; i<max; ++i) {
- if (str.at(i) == quote) {
- if (status != quote) {
- status = quote;
- } else if (!ret.isEmpty() && str.at(i - 1) == slash) {
- ret[ret.size() - 1] = quote;
- } else {
- status = zero;
- }
- } else {
- ret += str.at(i);
- }
- }
- return ret;
-}
-/*!
- \internal
-
- Parses the format \a newFormat. If successful, returns \c true and
- sets up the format. Else keeps the old format and returns \c false.
-
-*/
-
-static inline int countRepeat(const QString &str, int index, int maxCount)
-{
- int count = 1;
- const QChar ch(str.at(index));
- const int max = qMin(index + maxCount, str.size());
- while (index + count < max && str.at(index + count) == ch) {
- ++count;
- }
- return count;
-}
-
-static inline void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote)
-{
- const QStringRef separator = string.midRef(from, size);
- list->append(lastQuote >= from ? unquote(separator) : separator.toString());
-}
-
-
-bool QDateTimeParser::parseFormat(const QString &newFormat)
-{
- const QLatin1Char quote('\'');
- const QLatin1Char slash('\\');
- const QLatin1Char zero('0');
- if (newFormat == displayFormat && !newFormat.isEmpty()) {
- return true;
- }
-
- QDTPDEBUGN("parseFormat: %s", newFormat.toLatin1().constData());
-
- QVector<SectionNode> newSectionNodes;
- Sections newDisplay = 0;
- QStringList newSeparators;
- int i, index = 0;
- int add = 0;
- QChar status(zero);
- const int max = newFormat.size();
- int lastQuote = -1;
- for (i = 0; i<max; ++i) {
- if (newFormat.at(i) == quote) {
- lastQuote = i;
- ++add;
- if (status != quote) {
- status = quote;
- } else if (i > 0 && newFormat.at(i - 1) != slash) {
- status = zero;
- }
- } else if (status != quote) {
- const char sect = newFormat.at(i).toLatin1();
- switch (sect) {
- case 'H':
- case 'h':
- if (parserType != QVariant::Date) {
- const Section hour = (sect == 'h') ? Hour12Section : Hour24Section;
- const SectionNode sn = { hour, i - add, countRepeat(newFormat, i, 2), 0 };
- newSectionNodes.append(sn);
- appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
- i += sn.count - 1;
- index = i + 1;
- newDisplay |= hour;
- }
- break;
- case 'm':
- if (parserType != QVariant::Date) {
- const SectionNode sn = { MinuteSection, i - add, countRepeat(newFormat, i, 2), 0 };
- newSectionNodes.append(sn);
- appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
- i += sn.count - 1;
- index = i + 1;
- newDisplay |= MinuteSection;
- }
- break;
- case 's':
- if (parserType != QVariant::Date) {
- const SectionNode sn = { SecondSection, i - add, countRepeat(newFormat, i, 2), 0 };
- newSectionNodes.append(sn);
- appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
- i += sn.count - 1;
- index = i + 1;
- newDisplay |= SecondSection;
- }
- break;
-
- case 'z':
- if (parserType != QVariant::Date) {
- const SectionNode sn = { MSecSection, i - add, countRepeat(newFormat, i, 3) < 3 ? 1 : 3, 0 };
- newSectionNodes.append(sn);
- appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
- i += sn.count - 1;
- index = i + 1;
- newDisplay |= MSecSection;
- }
- break;
- case 'A':
- case 'a':
- if (parserType != QVariant::Date) {
- const bool cap = (sect == 'A');
- const SectionNode sn = { AmPmSection, i - add, (cap ? 1 : 0), 0 };
- newSectionNodes.append(sn);
- appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
- newDisplay |= AmPmSection;
- if (i + 1 < newFormat.size()
- && newFormat.at(i+1) == (cap ? QLatin1Char('P') : QLatin1Char('p'))) {
- ++i;
- }
- index = i + 1;
- }
- break;
- case 'y':
- if (parserType != QVariant::Time) {
- const int repeat = countRepeat(newFormat, i, 4);
- if (repeat >= 2) {
- const SectionNode sn = { repeat == 4 ? YearSection : YearSection2Digits,
- i - add, repeat == 4 ? 4 : 2, 0 };
- newSectionNodes.append(sn);
- appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
- i += sn.count - 1;
- index = i + 1;
- newDisplay |= sn.type;
- }
- }
- break;
- case 'M':
- if (parserType != QVariant::Time) {
- const SectionNode sn = { MonthSection, i - add, countRepeat(newFormat, i, 4), 0 };
- newSectionNodes.append(sn);
- newSeparators.append(unquote(newFormat.midRef(index, i - index)));
- i += sn.count - 1;
- index = i + 1;
- newDisplay |= MonthSection;
- }
- break;
- case 'd':
- if (parserType != QVariant::Time) {
- const int repeat = countRepeat(newFormat, i, 4);
- const Section sectionType = (repeat == 4 ? DayOfWeekSectionLong
- : (repeat == 3 ? DayOfWeekSectionShort : DaySection));
- const SectionNode sn = { sectionType, i - add, repeat, 0 };
- newSectionNodes.append(sn);
- appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
- i += sn.count - 1;
- index = i + 1;
- newDisplay |= sn.type;
- }
- break;
- case 't':
- if (parserType != QVariant::Time) {
- const SectionNode sn = { TimeZoneSection, i - add, countRepeat(newFormat, i, 4), 0 };
- newSectionNodes.append(sn);
- appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
- i += sn.count - 1;
- index = i + 1;
- newDisplay |= TimeZoneSection;
- }
- break;
- default:
- break;
- }
- }
- }
- if (newSectionNodes.isEmpty() && context == DateTimeEdit) {
- return false;
- }
-
- if ((newDisplay & (AmPmSection|Hour12Section)) == Hour12Section) {
- const int count = newSectionNodes.size();
- for (int i = 0; i < count; ++i) {
- SectionNode &node = newSectionNodes[i];
- if (node.type == Hour12Section)
- node.type = Hour24Section;
- }
- }
-
- if (index < max) {
- appendSeparator(&newSeparators, newFormat, index, index - max, lastQuote);
- } else {
- newSeparators.append(QString());
- }
-
- displayFormat = newFormat;
- separators = newSeparators;
- sectionNodes = newSectionNodes;
- display = newDisplay;
- last.pos = -1;
-
-// for (int i=0; i<sectionNodes.size(); ++i) {
-// QDTPDEBUG << sectionNodes.at(i).name() << sectionNodes.at(i).count;
-// }
-
- QDTPDEBUG << newFormat << displayFormat;
- QDTPDEBUGN("separators:\n'%s'", separators.join(QLatin1String("\n")).toLatin1().constData());
-
- return true;
-}
-
-/*!
- \internal
-
- Returns the size of section \a s.
-*/
-
-int QDateTimeParser::sectionSize(int sectionIndex) const
-{
- if (sectionIndex < 0)
- return 0;
-
- if (sectionIndex >= sectionNodes.size()) {
- qWarning("QDateTimeParser::sectionSize Internal error (%d)", sectionIndex);
- return -1;
- }
-
- if (sectionIndex == sectionNodes.size() - 1) {
- // In some cases there is a difference between displayText() and text.
- // e.g. when text is 2000/01/31 and displayText() is "2000/2/31" - text
- // is the previous value and displayText() is the new value.
- // The size difference is always due to leading zeroes.
- int sizeAdjustment = 0;
- const int displayTextSize = displayText().size();
- if (displayTextSize != text.size()) {
- // Any zeroes added before this section will affect our size.
- int preceedingZeroesAdded = 0;
- if (sectionNodes.size() > 1 && context == DateTimeEdit) {
- const auto begin = sectionNodes.cbegin();
- const auto end = begin + sectionIndex;
- for (auto sectionIt = begin; sectionIt != end; ++sectionIt)
- preceedingZeroesAdded += sectionIt->zeroesAdded;
- }
- sizeAdjustment = preceedingZeroesAdded;
- }
-
- return displayTextSize + sizeAdjustment - sectionPos(sectionIndex) - separators.last().size();
- } else {
- return sectionPos(sectionIndex + 1) - sectionPos(sectionIndex)
- - separators.at(sectionIndex + 1).size();
- }
-}
-
-
-int QDateTimeParser::sectionMaxSize(Section s, int count) const
-{
-#if QT_CONFIG(textdate)
- int mcount = 12;
-#endif
-
- switch (s) {
- case FirstSection:
- case NoSection:
- case LastSection: return 0;
-
- case AmPmSection: {
- const int lowerMax = qMin(getAmPmText(AmText, LowerCase).size(),
- getAmPmText(PmText, LowerCase).size());
- const int upperMax = qMin(getAmPmText(AmText, UpperCase).size(),
- getAmPmText(PmText, UpperCase).size());
- return qMin(4, qMin(lowerMax, upperMax));
- }
-
- case Hour24Section:
- case Hour12Section:
- case MinuteSection:
- case SecondSection:
- case DaySection: return 2;
- case DayOfWeekSectionShort:
- case DayOfWeekSectionLong:
-#if !QT_CONFIG(textdate)
- return 2;
-#else
- mcount = 7;
- Q_FALLTHROUGH();
-#endif
- case MonthSection:
-#if !QT_CONFIG(textdate)
- return 2;
-#else
- if (count <= 2)
- return 2;
-
- {
- int ret = 0;
- const QLocale l = locale();
- const QLocale::FormatType format = count == 4 ? QLocale::LongFormat : QLocale::ShortFormat;
- for (int i=1; i<=mcount; ++i) {
- const QString str = (s == MonthSection
- ? l.monthName(i, format)
- : l.dayName(i, format));
- ret = qMax(str.size(), ret);
- }
- return ret;
- }
-#endif
- case MSecSection: return 3;
- case YearSection: return 4;
- case YearSection2Digits: return 2;
- // Arbitrarily many tokens (each up to 14 bytes) joined with / separators:
- case TimeZoneSection: return std::numeric_limits<int>::max();
-
- case CalendarPopupSection:
- case Internal:
- case TimeSectionMask:
- case DateSectionMask:
- case HourSectionMask:
- case YearSectionMask:
- case DayOfWeekSectionMask:
- case DaySectionMask:
- qWarning("QDateTimeParser::sectionMaxSize: Invalid section %s",
- SectionNode::name(s).toLatin1().constData());
-
- case NoSectionIndex:
- case FirstSectionIndex:
- case LastSectionIndex:
- case CalendarPopupIndex:
- // these cases can't happen
- break;
- }
- return -1;
-}
-
-
-int QDateTimeParser::sectionMaxSize(int index) const
-{
- const SectionNode &sn = sectionNode(index);
- return sectionMaxSize(sn.type, sn.count);
-}
-
-/*!
- \internal
-
- Returns the text of section \a s. This function operates on the
- arg text rather than edit->text().
-*/
-
-
-QString QDateTimeParser::sectionText(const QString &text, int sectionIndex, int index) const
-{
- const SectionNode &sn = sectionNode(sectionIndex);
- switch (sn.type) {
- case NoSectionIndex:
- case FirstSectionIndex:
- case LastSectionIndex:
- return QString();
- default: break;
- }
-
- return text.mid(index, sectionSize(sectionIndex));
-}
-
-QString QDateTimeParser::sectionText(int sectionIndex) const
-{
- const SectionNode &sn = sectionNode(sectionIndex);
- return sectionText(displayText(), sectionIndex, sn.pos);
-}
-
-
-#if QT_CONFIG(datestring)
-
-QDateTimeParser::ParsedSection
-QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex,
- int offset, QString *text) const
-{
- ParsedSection result; // initially Invalid
- const SectionNode &sn = sectionNode(sectionIndex);
- if (sn.type & Internal) {
- qWarning("QDateTimeParser::parseSection Internal error (%ls %d)",
- qUtf16Printable(sn.name()), sectionIndex);
- return result;
- }
-
- const int sectionmaxsize = sectionMaxSize(sectionIndex);
- QStringRef sectionTextRef = text->midRef(offset, sectionmaxsize);
-
- QDTPDEBUG << "sectionValue for" << sn.name()
- << "with text" << *text << "and (at" << offset
- << ") st:" << sectionTextRef;
-
- switch (sn.type) {
- case AmPmSection: {
- QString sectiontext = sectionTextRef.toString();
- int used;
- const int ampm = findAmPm(sectiontext, sectionIndex, &used);
- switch (ampm) {
- case AM: // sectiontext == AM
- case PM: // sectiontext == PM
- result = ParsedSection(Acceptable, ampm, used);
- break;
- case PossibleAM: // sectiontext => AM
- case PossiblePM: // sectiontext => PM
- result = ParsedSection(Intermediate, ampm - 2, used);
- break;
- case PossibleBoth: // sectiontext => AM|PM
- result = ParsedSection(Intermediate, 0, used);
- break;
- case Neither:
- QDTPDEBUG << "invalid because findAmPm(" << sectiontext << ") returned -1";
- break;
- default:
- QDTPDEBUGN("This should never happen (findAmPm returned %d)", ampm);
- break;
- }
- if (result.state != Invalid)
- text->replace(offset, used, sectiontext.constData(), used);
- break; }
- case TimeZoneSection:
-#if QT_CONFIG(timezone)
- result = findTimeZone(sectionTextRef, currentValue,
- absoluteMax(sectionIndex),
- absoluteMin(sectionIndex));
-#endif
- break;
- case MonthSection:
- case DayOfWeekSectionShort:
- case DayOfWeekSectionLong:
- if (sn.count >= 3) {
- QString sectiontext = sectionTextRef.toString();
- int num = 0, used = 0;
- if (sn.type == MonthSection) {
- const QDate minDate = getMinimum().date();
- const int min = (currentValue.date().year() == minDate.year())
- ? minDate.month() : 1;
- num = findMonth(sectiontext.toLower(), min, sectionIndex, &sectiontext, &used);
- } else {
- num = findDay(sectiontext.toLower(), 1, sectionIndex, &sectiontext, &used);
- }
-
- result = ParsedSection(Intermediate, num, used);
- if (num != -1) {
- text->replace(offset, used, sectiontext.constData(), used);
- if (used == sectiontext.size())
- result = ParsedSection(Acceptable, num, used);
- }
- break;
- }
- Q_FALLTHROUGH();
- // All numeric:
- case DaySection:
- case YearSection:
- case YearSection2Digits:
- case Hour12Section:
- case Hour24Section:
- case MinuteSection:
- case SecondSection:
- case MSecSection: {
- int sectiontextSize = sectionTextRef.size();
- if (sectiontextSize == 0) {
- result = ParsedSection(Intermediate);
- } else {
- for (int i = 0; i < sectiontextSize; ++i) {
- if (sectionTextRef.at(i).isSpace())
- sectiontextSize = i; // which exits the loop
- }
-
- const int absMax = absoluteMax(sectionIndex);
- QLocale loc;
- bool ok = true;
- int last = -1, used = -1;
-
- Q_ASSERT(sectiontextSize <= sectionmaxsize);
- QStringRef digitsStr = sectionTextRef.left(sectiontextSize);
- for (int digits = sectiontextSize; digits >= 1; --digits) {
- digitsStr.truncate(digits);
- int tmp = (int)loc.toUInt(digitsStr, &ok);
- if (ok && sn.type == Hour12Section) {
- if (tmp > 12) {
- tmp = -1;
- ok = false;
- } else if (tmp == 12) {
- tmp = 0;
- }
- }
- if (ok && tmp <= absMax) {
- QDTPDEBUG << sectionTextRef.left(digits) << tmp << digits;
- last = tmp;
- used = digits;
- break;
- }
- }
-
- if (last == -1) {
- QChar first(sectionTextRef.at(0));
- if (separators.at(sectionIndex + 1).startsWith(first))
- result = ParsedSection(Intermediate, 0, used);
- else
- QDTPDEBUG << "invalid because" << sectionTextRef << "can't become a uint" << last << ok;
- } else {
- const FieldInfo fi = fieldInfo(sectionIndex);
- const bool unfilled = used < sectionmaxsize;
- if (unfilled && fi & Fraction) { // typing 2 in a zzz field should be .200, not .002
- for (int i = used; i < sectionmaxsize; ++i)
- last *= 10;
- }
- // Even those *= 10s can't take last above absMax:
- Q_ASSERT(last <= absMax);
- const int absMin = absoluteMin(sectionIndex);
- if (last < absMin) {
- if (unfilled)
- result = ParsedSection(Intermediate, last, used);
- else
- QDTPDEBUG << "invalid because" << last << "is less than absoluteMin" << absMin;
- } else if (unfilled && (fi & (FixedWidth|Numeric)) == (FixedWidth|Numeric)) {
- if (skipToNextSection(sectionIndex, currentValue, digitsStr)) {
- const int missingZeroes = sectionmaxsize - digitsStr.size();
- result = ParsedSection(Acceptable, last, sectionmaxsize, missingZeroes);
- text->insert(offset, QString(missingZeroes, QLatin1Char('0')));
- ++(const_cast<QDateTimeParser*>(this)->sectionNodes[sectionIndex].zeroesAdded);
- } else {
- result = ParsedSection(Intermediate, last, used);;
- }
- } else {
- result = ParsedSection(Acceptable, last, used);
- }
- }
- }
- break; }
- default:
- qWarning("QDateTimeParser::parseSection Internal error (%ls %d)",
- qUtf16Printable(sn.name()), sectionIndex);
- return result;
- }
- Q_ASSERT(result.state != Invalid || result.value == -1);
-
- return result;
-}
-
-/*!
- \internal
-
- Returns a date consistent with the given data on parts specified by known,
- while staying as close to the given data as it can. Returns an invalid date
- when on valid date is consistent with the data.
-*/
-
-static QDate actualDate(QDateTimeParser::Sections known, int year, int year2digits,
- int month, int day, int dayofweek)
-{
- QDate actual(year, month, day);
- if (actual.isValid() && year % 100 == year2digits && actual.dayOfWeek() == dayofweek)
- return actual; // The obvious candidate is fine :-)
-
- if (dayofweek < 1 || dayofweek > 7) // Invalid: ignore
- known &= ~QDateTimeParser::DayOfWeekSectionMask;
-
- // Assuming year > 0 ...
- if (year % 100 != year2digits) {
- if (known & QDateTimeParser::YearSection2Digits) {
- // Over-ride year, even if specified:
- year += year2digits - year % 100;
- known &= ~QDateTimeParser::YearSection;
- } else {
- year2digits = year % 100;
- }
- }
- Q_ASSERT(year % 100 == year2digits);
-
- if (month < 1) { // If invalid, clip to nearest valid and ignore in known.
- month = 1;
- known &= ~QDateTimeParser::MonthSection;
- } else if (month > 12) {
- month = 12;
- known &= ~QDateTimeParser::MonthSection;
- }
-
- QDate first(year, month, 1);
- int last = known & QDateTimeParser::YearSection && known & QDateTimeParser::MonthSection
- ? first.daysInMonth() : 0;
- // If we also know day-of-week, tweak last to the last in the month that matches it:
- if (last && known & QDateTimeParser::DayOfWeekSectionMask) {
- int diff = (dayofweek - first.dayOfWeek() - last) % 7;
- Q_ASSERT(diff <= 0); // C++11 specifies (-ve) % (+ve) to be <= 0.
- last += diff;
- }
- if (day < 1) {
- if (known & QDateTimeParser::DayOfWeekSectionMask && last) {
- day = 1 + dayofweek - first.dayOfWeek();
- if (day < 1)
- day += 7;
- } else {
- day = 1;
- }
- known &= ~QDateTimeParser::DaySection;
- } else if (day > 31) {
- day = last;
- known &= ~QDateTimeParser::DaySection;
- } else if (last && day > last && (known & QDateTimeParser::DaySection) == 0) {
- day = last;
- }
-
- actual = QDate(year, month, day);
- if (!actual.isValid() // We can't do better than we have, in this case
- || (known & QDateTimeParser::DaySection
- && known & QDateTimeParser::MonthSection
- && known & QDateTimeParser::YearSection) // ditto
- || actual.dayOfWeek() == dayofweek // Good enough, use it.
- || (known & QDateTimeParser::DayOfWeekSectionMask) == 0) { // No contradiction, use it.
- return actual;
- }
-
- /*
- Now it gets trickier.
-
- We have some inconsistency in our data; we've been told day of week, but
- it doesn't fit with our year, month and day. At least one of these is
- unknown, though: so we can fix day of week by tweaking it.
- */
-
- if ((known & QDateTimeParser::DaySection) == 0) {
- // Relatively easy to fix.
- day += dayofweek - actual.dayOfWeek();
- if (day < 1)
- day += 7;
- else if (day > actual.daysInMonth())
- day -= 7;
- actual = QDate(year, month, day);
- return actual;
- }
-
- if ((known & QDateTimeParser::MonthSection) == 0) {
- /*
- Try possible month-offsets, m, preferring small; at least one (present
- month doesn't work) and at most 11 (max month, 12, minus min, 1); try
- in both directions, ignoring any offset that takes us out of range.
- */
- for (int m = 1; m < 12; m++) {
- if (m < month) {
- actual = QDate(year, month - m, day);
- if (actual.dayOfWeek() == dayofweek)
- return actual;
- }
- if (m + month <= 12) {
- actual = QDate(year, month + m, day);
- if (actual.dayOfWeek() == dayofweek)
- return actual;
- }
- }
- // Should only get here in corner cases; e.g. day == 31
- actual = QDate(year, month, day); // Restore from trial values.
- }
-
- if ((known & QDateTimeParser::YearSection) == 0) {
- if (known & QDateTimeParser::YearSection2Digits) {
- /*
- Two-digit year and month are specified; choice of century can only
- fix this if diff is in one of {1, 2, 5} or {2, 4, 6}; but not if
- diff is in the other. It's also only reasonable to consider
- adjacent century, e.g. if year thinks it's 2012 and two-digit year
- is '97, it makes sense to consider 1997. If either adjacent
- century does work, the other won't.
- */
- actual = QDate(year + 100, month, day);
- if (actual.dayOfWeek() == dayofweek)
- return actual;
- actual = QDate(year - 100, month, day);
- if (actual.dayOfWeek() == dayofweek)
- return actual;
- } else {
- // Offset by 7 is usually enough, but rare cases may need more:
- for (int y = 1; y < 12; y++) {
- actual = QDate(year - y, month, day);
- if (actual.dayOfWeek() == dayofweek)
- return actual;
- actual = QDate(year + y, month, day);
- if (actual.dayOfWeek() == dayofweek)
- return actual;
- }
- }
- actual = QDate(year, month, day); // Restore from trial values.
- }
-
- return actual; // It'll just have to do :-(
-}
-
-/*!
- \internal
-*/
-
-static QTime actualTime(QDateTimeParser::Sections known,
- int hour, int hour12, int ampm,
- int minute, int second, int msec)
-{
- // If we have no conflict, or don't know enough to diagonose one, use this:
- QTime actual(hour, minute, second, msec);
- if (hour12 < 0 || hour12 > 12) { // ignore bogus value
- known &= ~QDateTimeParser::Hour12Section;
- hour12 = hour % 12;
- }
-
- if (ampm == -1 || (known & QDateTimeParser::AmPmSection) == 0) {
- if ((known & QDateTimeParser::Hour12Section) == 0 || hour % 12 == hour12)
- return actual;
-
- if ((known & QDateTimeParser::Hour24Section) == 0)
- hour = hour12 + (hour > 12 ? 12 : 0);
- } else {
- Q_ASSERT(ampm == 0 || ampm == 1);
- if (hour - hour12 == ampm * 12)
- return actual;
-
- if ((known & QDateTimeParser::Hour24Section) == 0
- && known & QDateTimeParser::Hour12Section) {
- hour = hour12 + ampm * 12;
- }
- }
- actual = QTime(hour, minute, second, msec);
- return actual;
-}
-
-/*!
- \internal
-*/
-QDateTimeParser::StateNode
-QDateTimeParser::scanString(const QDateTime &defaultValue,
- bool fixup, QString *input) const
-{
- State state = Acceptable;
- bool conflicts = false;
- const int sectionNodesCount = sectionNodes.size();
- int padding = 0;
- int pos = 0;
- int year, month, day;
- const QDate defaultDate = defaultValue.date();
- const QTime defaultTime = defaultValue.time();
- defaultDate.getDate(&year, &month, &day);
- int year2digits = year % 100;
- int hour = defaultTime.hour();
- int hour12 = -1;
- int minute = defaultTime.minute();
- int second = defaultTime.second();
- int msec = defaultTime.msec();
- int dayofweek = defaultDate.dayOfWeek();
- Qt::TimeSpec tspec = defaultValue.timeSpec();
- int zoneOffset = 0; // In seconds; local - UTC
-#if QT_CONFIG(timezone)
- QTimeZone timeZone;
-#endif
- switch (tspec) {
- case Qt::OffsetFromUTC: // timeZone is ignored
- zoneOffset = defaultValue.offsetFromUtc();
- break;
-#if QT_CONFIG(timezone)
- case Qt::TimeZone:
- timeZone = defaultValue.timeZone();
- if (timeZone.isValid())
- zoneOffset = timeZone.offsetFromUtc(defaultValue);
- // else: is there anything we can do about this ?
- break;
-#endif
- default: // zoneOffset and timeZone are ignored
- break;
- }
-
- int ampm = -1;
- Sections isSet = NoSection;
-
- for (int index = 0; index < sectionNodesCount; ++index) {
- Q_ASSERT(state != Invalid);
- const QString &separator = separators.at(index);
- if (input->midRef(pos, separator.size()) != separator) {
- QDTPDEBUG << "invalid because" << input->midRef(pos, separator.size())
- << "!=" << separator
- << index << pos << currentSectionIndex;
- return StateNode();
- }
- pos += separator.size();
- sectionNodes[index].pos = pos;
- int *current = 0;
- const SectionNode sn = sectionNodes.at(index);
- ParsedSection sect;
-
- {
- const QDate date = actualDate(isSet, year, year2digits, month, day, dayofweek);
- const QTime time = actualTime(isSet, hour, hour12, ampm, minute, second, msec);
- sect = parseSection(
-#if QT_CONFIG(timezone)
- tspec == Qt::TimeZone ? QDateTime(date, time, timeZone) :
-#endif
- QDateTime(date, time, tspec, zoneOffset),
- index, pos, input);
- }
-
- QDTPDEBUG << "sectionValue" << sn.name() << *input
- << "pos" << pos << "used" << sect.used << stateName(sect.state);
-
- padding += sect.zeroes;
- if (fixup && sect.state == Intermediate && sect.used < sn.count) {
- const FieldInfo fi = fieldInfo(index);
- if ((fi & (Numeric|FixedWidth)) == (Numeric|FixedWidth)) {
- const QString newText = QString::fromLatin1("%1").arg(sect.value, sn.count, 10, QLatin1Char('0'));
- input->replace(pos, sect.used, newText);
- sect.used = sn.count;
- }
- }
-
- state = qMin<State>(state, sect.state);
- // QDateTimeEdit can fix Intermediate and zeroes, but input needing that didn't match format:
- if (state == Invalid || (context == FromString && (state == Intermediate || sect.zeroes)))
- return StateNode();
-
- switch (sn.type) {
- case TimeZoneSection:
- current = &zoneOffset;
- if (sect.used > 0) {
-#if QT_CONFIG(timezone) // Synchronize with what findTimeZone() found:
- QStringRef zoneName = input->midRef(pos, sect.used);
- Q_ASSERT(!zoneName.isEmpty()); // sect.used > 0
- const QByteArray latinZone(zoneName == QLatin1String("Z")
- ? QByteArray("UTC") : zoneName.toLatin1());
- timeZone = QTimeZone(latinZone);
- tspec = timeZone.isValid()
- ? (QTimeZone::isTimeZoneIdAvailable(latinZone)
- ? Qt::TimeZone
- : Qt::OffsetFromUTC)
- : (Q_ASSERT(startsWithLocalTimeZone(zoneName)), Qt::LocalTime);
-#else
- tspec = Qt::LocalTime;
-#endif
- }
- break;
- case Hour24Section: current = &hour; break;
- case Hour12Section: current = &hour12; break;
- case MinuteSection: current = &minute; break;
- case SecondSection: current = &second; break;
- case MSecSection: current = &msec; break;
- case YearSection: current = &year; break;
- case YearSection2Digits: current = &year2digits; break;
- case MonthSection: current = &month; break;
- case DayOfWeekSectionShort:
- case DayOfWeekSectionLong: current = &dayofweek; break;
- case DaySection: current = &day; sect.value = qMax<int>(1, sect.value); break;
- case AmPmSection: current = &ampm; break;
- default:
- qWarning("QDateTimeParser::parse Internal error (%ls)",
- qUtf16Printable(sn.name()));
- break;
- }
-
- if (sect.used > 0)
- pos += sect.used;
- QDTPDEBUG << index << sn.name() << "is set to"
- << pos << "state is" << stateName(state);
-
- if (!current) {
- qWarning("QDateTimeParser::parse Internal error 2");
- return StateNode();
- }
- if (isSet & sn.type && *current != sect.value) {
- QDTPDEBUG << "CONFLICT " << sn.name() << *current << sect.value;
- conflicts = true;
- if (index != currentSectionIndex || sect.state == Invalid) {
- continue;
- }
- }
- if (sect.state != Invalid)
- *current = sect.value;
-
- // Record the present section:
- isSet |= sn.type;
- }
-
- if (input->midRef(pos) != separators.last()) {
- QDTPDEBUG << "invalid because" << input->midRef(pos)
- << "!=" << separators.last() << pos;
- return StateNode();
- }
-
- if (parserType != QVariant::Time) {
- if (year % 100 != year2digits && (isSet & YearSection2Digits)) {
- if (!(isSet & YearSection)) {
- year = (year / 100) * 100;
- year += year2digits;
- } else {
- conflicts = true;
- const SectionNode &sn = sectionNode(currentSectionIndex);
- if (sn.type == YearSection2Digits) {
- year = (year / 100) * 100;
- year += year2digits;
- }
- }
- }
-
- const QDate date(year, month, day);
- const int diff = dayofweek - date.dayOfWeek();
- if (diff != 0 && state == Acceptable && isSet & DayOfWeekSectionMask) {
- if (isSet & DaySection)
- conflicts = true;
- const SectionNode &sn = sectionNode(currentSectionIndex);
- if (sn.type & DayOfWeekSectionMask || currentSectionIndex == -1) {
- // dayofweek should be preferred
- day += diff;
- if (day <= 0) {
- day += 7;
- } else if (day > date.daysInMonth()) {
- day -= 7;
- }
- QDTPDEBUG << year << month << day << dayofweek
- << diff << QDate(year, month, day).dayOfWeek();
- }
- }
-
- bool needfixday = false;
- if (sectionType(currentSectionIndex) & DaySectionMask) {
- cachedDay = day;
- } else if (cachedDay > day) {
- day = cachedDay;
- needfixday = true;
- }
-
- if (!QDate::isValid(year, month, day)) {
- if (day < 32) {
- cachedDay = day;
- }
- if (day > 28 && QDate::isValid(year, month, 1)) {
- needfixday = true;
- }
- }
- if (needfixday) {
- if (context == FromString) {
- return StateNode();
- }
- if (state == Acceptable && fixday) {
- day = qMin<int>(day, QDate(year, month, 1).daysInMonth());
-
- const QLocale loc = locale();
- for (int i=0; i<sectionNodesCount; ++i) {
- const SectionNode sn = sectionNode(i);
- if (sn.type & DaySection) {
- input->replace(sectionPos(sn), sectionSize(i), loc.toString(day));
- } else if (sn.type & DayOfWeekSectionMask) {
- const int dayOfWeek = QDate(year, month, day).dayOfWeek();
- const QLocale::FormatType dayFormat =
- (sn.type == DayOfWeekSectionShort
- ? QLocale::ShortFormat : QLocale::LongFormat);
- const QString dayName(loc.dayName(dayOfWeek, dayFormat));
- input->replace(sectionPos(sn), sectionSize(i), dayName);
- }
- }
- } else if (state > Intermediate) {
- state = Intermediate;
- }
- }
- }
-
- if (parserType != QVariant::Date) {
- if (isSet & Hour12Section) {
- const bool hasHour = isSet & Hour24Section;
- if (ampm == -1) {
- if (hasHour) {
- ampm = (hour < 12 ? 0 : 1);
- } else {
- ampm = 0; // no way to tell if this is am or pm so I assume am
- }
- }
- hour12 = (ampm == 0 ? hour12 % 12 : (hour12 % 12) + 12);
- if (!hasHour) {
- hour = hour12;
- } else if (hour != hour12) {
- conflicts = true;
- }
- } else if (ampm != -1) {
- if (!(isSet & (Hour24Section))) {
- hour = (12 * ampm); // special case. Only ap section
- } else if ((ampm == 0) != (hour < 12)) {
- conflicts = true;
- }
- }
-
- }
-
- QDTPDEBUG << year << month << day << hour << minute << second << msec;
- Q_ASSERT(state != Invalid);
-
- const QDate date(year, month, day);
- const QTime time(hour, minute, second, msec);
- const QDateTime when =
-#if QT_CONFIG(timezone)
- tspec == Qt::TimeZone ? QDateTime(date, time, timeZone) :
-#endif
- QDateTime(date, time, tspec, zoneOffset);
-
- // If hour wasn't specified, check the default we're using exists on the
- // given date (which might be a spring-forward, skipping an hour).
- if (parserType == QVariant::DateTime && !(isSet & HourSectionMask) && !when.isValid()) {
- qint64 msecs = when.toMSecsSinceEpoch();
- // Fortunately, that gets a useful answer ...
- const QDateTime replace =
-#if QT_CONFIG(timezone)
- tspec == Qt::TimeZone
- ? QDateTime::fromMSecsSinceEpoch(msecs, timeZone) :
-#endif
- QDateTime::fromMSecsSinceEpoch(msecs, tspec, zoneOffset);
- const QTime tick = replace.time();
- if (replace.date() == date
- && (!(isSet & MinuteSection) || tick.minute() == minute)
- && (!(isSet & SecondSection) || tick.second() == second)
- && (!(isSet & MSecSection) || tick.msec() == msec)) {
- return StateNode(replace, state, padding, conflicts);
- }
- }
-
- return StateNode(when, state, padding, conflicts);
-}
-
-/*!
- \internal
-*/
-
-QDateTimeParser::StateNode
-QDateTimeParser::parse(QString input, int position, const QDateTime &defaultValue, bool fixup) const
-{
- const QDateTime minimum = getMinimum();
- const QDateTime maximum = getMaximum();
-
- QDTPDEBUG << "parse" << input;
- StateNode scan = scanString(defaultValue, fixup, &input);
- QDTPDEBUGN("'%s' => '%s'(%s)", input.toLatin1().constData(),
- scan.value.toString(QLatin1String("yyyy/MM/dd hh:mm:ss.zzz")).toLatin1().constData(),
- stateName(scan.state).toLatin1().constData());
-
- if (scan.value.isValid() && scan.state != Invalid) {
- if (context != FromString && scan.value < minimum) {
- const QLatin1Char space(' ');
- if (scan.value >= minimum)
- qWarning("QDateTimeParser::parse Internal error 3 (%ls %ls)",
- qUtf16Printable(scan.value.toString()), qUtf16Printable(minimum.toString()));
-
- bool done = false;
- scan.state = Invalid;
- const int sectionNodesCount = sectionNodes.size();
- for (int i=0; i<sectionNodesCount && !done; ++i) {
- const SectionNode &sn = sectionNodes.at(i);
- QString t = sectionText(input, i, sn.pos).toLower();
- if ((t.size() < sectionMaxSize(i)
- && (((int)fieldInfo(i) & (FixedWidth|Numeric)) != Numeric))
- || t.contains(space)) {
- switch (sn.type) {
- case AmPmSection:
- switch (findAmPm(t, i)) {
- case AM:
- case PM:
- scan.state = Acceptable;
- done = true;
- break;
- case Neither:
- scan.state = Invalid;
- done = true;
- break;
- case PossibleAM:
- case PossiblePM:
- case PossibleBoth: {
- const QDateTime copy(scan.value.addSecs(12 * 60 * 60));
- if (copy >= minimum && copy <= maximum) {
- scan.state = Intermediate;
- done = true;
- }
- break; }
- }
- Q_FALLTHROUGH();
- case MonthSection:
- if (sn.count >= 3) {
- const int finalMonth = scan.value.date().month();
- int tmp = finalMonth;
- // I know the first possible month makes the date too early
- while ((tmp = findMonth(t, tmp + 1, i)) != -1) {
- const QDateTime copy(scan.value.addMonths(tmp - finalMonth));
- if (copy >= minimum && copy <= maximum)
- break; // break out of while
- }
- if (tmp != -1) {
- scan.state = Intermediate;
- done = true;
- }
- break;
- }
- Q_FALLTHROUGH();
- default: {
- int toMin;
- int toMax;
-
- if (sn.type & TimeSectionMask) {
- if (scan.value.daysTo(minimum) != 0) {
- break;
- }
- const QTime time = scan.value.time();
- toMin = time.msecsTo(minimum.time());
- if (scan.value.daysTo(maximum) > 0)
- toMax = -1; // can't get to max
- else
- toMax = time.msecsTo(maximum.time());
- } else {
- toMin = scan.value.daysTo(minimum);
- toMax = scan.value.daysTo(maximum);
- }
- const int maxChange = sn.maxChange();
- if (toMin > maxChange) {
- QDTPDEBUG << "invalid because toMin > maxChange" << toMin
- << maxChange << t << scan.value << minimum;
- scan.state = Invalid;
- done = true;
- break;
- } else if (toMax > maxChange) {
- toMax = -1; // can't get to max
- }
-
- const int min = getDigit(minimum, i);
- if (min == -1) {
- qWarning("QDateTimeParser::parse Internal error 4 (%ls)",
- qUtf16Printable(sn.name()));
- scan.state = Invalid;
- done = true;
- break;
- }
-
- int max = toMax != -1 ? getDigit(maximum, i) : absoluteMax(i, scan.value);
- int pos = position + scan.padded - sn.pos;
- if (pos < 0 || pos >= t.size())
- pos = -1;
- if (!potentialValue(t.simplified(), min, max, i, scan.value, pos)) {
- QDTPDEBUG << "invalid because potentialValue(" << t.simplified() << min << max
- << sn.name() << "returned" << toMax << toMin << pos;
- scan.state = Invalid;
- done = true;
- break;
- }
- scan.state = Intermediate;
- done = true;
- break; }
- }
- }
- }
- } else {
- if (context == FromString) {
- // optimization
- Q_ASSERT(maximum.date().toJulianDay() == 5373484);
- if (scan.value.date().toJulianDay() > 5373484)
- scan.state = Invalid;
- } else {
- if (scan.value > maximum)
- scan.state = Invalid;
- }
-
- QDTPDEBUG << "not checking intermediate because scanned value is" << scan.value << minimum << maximum;
- }
- }
- text = scan.input = input;
- // Set spec *after* all checking, so validity is a property of the string:
- scan.value = scan.value.toTimeSpec(spec);
- return scan;
-}
-
-/*
- \internal
- \brief Returns the index in \a entries with the best prefix match to \a text
-
- Scans \a entries looking for an entry overlapping \a text as much as possible
- (an exact match beats any prefix match; a match of the full entry as prefix of
- text beats any entry but one matching a longer prefix; otherwise, the match of
- longest prefix wins, earlier entries beating later on a draw). Records the
- length of overlap in *used (if \a used is non-NULL) and the first entry that
- overlapped this much in *usedText (if \a usedText is non-NULL).
- */
-static int findTextEntry(const QString &text, const QVector<QString> &entries, QString *usedText, int *used)
-{
- if (text.isEmpty())
- return -1;
-
- int bestMatch = -1;
- int bestCount = 0;
- for (int n = 0; n < entries.size(); ++n)
- {
- const QString &name = entries.at(n);
-
- const int limit = qMin(text.size(), name.size());
- int i = 0;
- while (i < limit && text.at(i) == name.at(i).toLower())
- ++i;
- // Full match beats an equal prefix match:
- if (i > bestCount || (i == bestCount && i == name.size())) {
- bestCount = i;
- bestMatch = n;
- if (i == name.size() && i == text.size())
- break; // Exact match, name == text, wins.
- }
- }
- if (usedText && bestMatch != -1)
- *usedText = entries.at(bestMatch);
- if (used)
- *used = bestCount;
-
- return bestMatch;
-}
-
-/*!
- \internal
- finds the first possible monthname that \a str1 can
- match. Starting from \a index; str should already by lowered
-*/
-
-int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionIndex,
- QString *usedMonth, int *used) const
-{
- const SectionNode &sn = sectionNode(sectionIndex);
- if (sn.type != MonthSection) {
- qWarning("QDateTimeParser::findMonth Internal error");
- return -1;
- }
-
- QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
- QLocale l = locale();
- QVector<QString> monthNames;
- monthNames.reserve(13 - startMonth);
- for (int month = startMonth; month <= 12; ++month)
- monthNames.append(l.monthName(month, type));
-
- const int index = findTextEntry(str1, monthNames, usedMonth, used);
- return index < 0 ? index : index + startMonth;
-}
-
-int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex, QString *usedDay, int *used) const
-{
- const SectionNode &sn = sectionNode(sectionIndex);
- if (!(sn.type & DaySectionMask)) {
- qWarning("QDateTimeParser::findDay Internal error");
- return -1;
- }
-
- QLocale::FormatType type = sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat;
- QLocale l = locale();
- QVector<QString> daysOfWeek;
- daysOfWeek.reserve(8 - startDay);
- for (int day = startDay; day <= 7; ++day)
- daysOfWeek.append(l.dayName(day, type));
-
- const int index = findTextEntry(str1, daysOfWeek, usedDay, used);
- return index < 0 ? index : index + startDay;
-}
-
-/*!
- \internal
-
- Return's .value is zone's offset, zone time - UTC time, in seconds.
- See QTimeZonePrivate::isValidId() for the format of zone names.
- */
-QDateTimeParser::ParsedSection
-QDateTimeParser::findTimeZone(QStringRef str, const QDateTime &when,
- int maxVal, int minVal) const
-{
-#if QT_CONFIG(timezone)
- int index = startsWithLocalTimeZone(str);
- int offset;
-
- if (index > 0) {
- // We won't actually use this, but we need a valid return:
- offset = QDateTime(when.date(), when.time(), Qt::LocalTime).offsetFromUtc();
- } else {
- int size = str.length();
- offset = std::numeric_limits<int>::max(); // deliberately out of range
- Q_ASSERT(offset > QTimeZone::MaxUtcOffsetSecs); // cf. absoluteMax()
-
- // Collect up plausibly-valid characters; let QTimeZone work out what's truly valid.
- while (index < size) {
- QChar here = str[index];
- if (here < 127
- && (here.isLetterOrNumber()
- || here == '/' || here == '-'
- || here == '_' || here == '.'
- || here == '+' || here == ':'))
- index++;
- else
- break;
- }
-
- while (index > 0) {
- str.truncate(index);
- if (str == QLatin1String("Z")) {
- offset = 0; // "Zulu" time - a.k.a. UTC
- break;
- }
- QTimeZone zone(str.toLatin1());
- if (zone.isValid()) {
- offset = zone.offsetFromUtc(when);
- break;
- }
- index--; // maybe we collected too much ...
- }
- }
-
- if (index > 0 && maxVal >= offset && offset >= minVal)
- return ParsedSection(Acceptable, offset, index);
-
-#endif // timezone
- return ParsedSection();
-}
-
-/*!
- \internal
-
- Returns
- AM if str == tr("AM")
- PM if str == tr("PM")
- PossibleAM if str can become tr("AM")
- PossiblePM if str can become tr("PM")
- PossibleBoth if str can become tr("PM") and can become tr("AM")
- Neither if str can't become anything sensible
-*/
-QDateTimeParser::AmPmFinder QDateTimeParser::findAmPm(QString &str, int sectionIndex, int *used) const
-{
- const SectionNode &s = sectionNode(sectionIndex);
- if (s.type != AmPmSection) {
- qWarning("QDateTimeParser::findAmPm Internal error");
- return Neither;
- }
- if (used)
- *used = str.size();
- if (QStringRef(&str).trimmed().isEmpty()) {
- return PossibleBoth;
- }
- const QLatin1Char space(' ');
- int size = sectionMaxSize(sectionIndex);
-
- enum {
- amindex = 0,
- pmindex = 1
- };
- QString ampm[2];
- ampm[amindex] = getAmPmText(AmText, s.count == 1 ? UpperCase : LowerCase);
- ampm[pmindex] = getAmPmText(PmText, s.count == 1 ? UpperCase : LowerCase);
- for (int i=0; i<2; ++i)
- ampm[i].truncate(size);
-
- QDTPDEBUG << "findAmPm" << str << ampm[0] << ampm[1];
-
- if (str.indexOf(ampm[amindex], 0, Qt::CaseInsensitive) == 0) {
- str = ampm[amindex];
- return AM;
- } else if (str.indexOf(ampm[pmindex], 0, Qt::CaseInsensitive) == 0) {
- str = ampm[pmindex];
- return PM;
- } else if (context == FromString || (str.count(space) == 0 && str.size() >= size)) {
- return Neither;
- }
- size = qMin(size, str.size());
-
- bool broken[2] = {false, false};
- for (int i=0; i<size; ++i) {
- if (str.at(i) != space) {
- for (int j=0; j<2; ++j) {
- if (!broken[j]) {
- int index = ampm[j].indexOf(str.at(i));
- QDTPDEBUG << "looking for" << str.at(i)
- << "in" << ampm[j] << "and got" << index;
- if (index == -1) {
- if (str.at(i).category() == QChar::Letter_Uppercase) {
- index = ampm[j].indexOf(str.at(i).toLower());
- QDTPDEBUG << "trying with" << str.at(i).toLower()
- << "in" << ampm[j] << "and got" << index;
- } else if (str.at(i).category() == QChar::Letter_Lowercase) {
- index = ampm[j].indexOf(str.at(i).toUpper());
- QDTPDEBUG << "trying with" << str.at(i).toUpper()
- << "in" << ampm[j] << "and got" << index;
- }
- if (index == -1) {
- broken[j] = true;
- if (broken[amindex] && broken[pmindex]) {
- QDTPDEBUG << str << "didn't make it";
- return Neither;
- }
- continue;
- } else {
- str[i] = ampm[j].at(index); // fix case
- }
- }
- ampm[j].remove(index, 1);
- }
- }
- }
- }
- if (!broken[pmindex] && !broken[amindex])
- return PossibleBoth;
- return (!broken[amindex] ? PossibleAM : PossiblePM);
-}
-#endif // datestring
-
-/*!
- \internal
- Max number of units that can be changed by this section.
-*/
-
-int QDateTimeParser::SectionNode::maxChange() const
-{
- switch (type) {
- // Time. unit is msec
- case MSecSection: return 999;
- case SecondSection: return 59 * 1000;
- case MinuteSection: return 59 * 60 * 1000;
- case Hour24Section: case Hour12Section: return 59 * 60 * 60 * 1000;
-
- // Date. unit is day
- case DayOfWeekSectionShort:
- case DayOfWeekSectionLong: return 7;
- case DaySection: return 30;
- case MonthSection: return 365 - 31;
- case YearSection: return 9999 * 365;
- case YearSection2Digits: return 100 * 365;
- default:
- qWarning("QDateTimeParser::maxChange() Internal error (%ls)",
- qUtf16Printable(name()));
- }
-
- return -1;
-}
-
-QDateTimeParser::FieldInfo QDateTimeParser::fieldInfo(int index) const
-{
- FieldInfo ret = 0;
- const SectionNode &sn = sectionNode(index);
- switch (sn.type) {
- case MSecSection:
- ret |= Fraction;
- Q_FALLTHROUGH();
- case SecondSection:
- case MinuteSection:
- case Hour24Section:
- case Hour12Section:
- case YearSection2Digits:
- ret |= AllowPartial;
- Q_FALLTHROUGH();
- case YearSection:
- ret |= Numeric;
- if (sn.count != 1)
- ret |= FixedWidth;
- break;
- case MonthSection:
- case DaySection:
- switch (sn.count) {
- case 2:
- ret |= FixedWidth;
- Q_FALLTHROUGH();
- case 1:
- ret |= (Numeric|AllowPartial);
- break;
- }
- break;
- case DayOfWeekSectionShort:
- case DayOfWeekSectionLong:
- if (sn.count == 3)
- ret |= FixedWidth;
- break;
- case AmPmSection:
- ret |= FixedWidth;
- break;
- case TimeZoneSection:
- break;
- default:
- qWarning("QDateTimeParser::fieldInfo Internal error 2 (%d %ls %d)",
- index, qUtf16Printable(sn.name()), sn.count);
- break;
- }
- return ret;
-}
-
-QString QDateTimeParser::SectionNode::format() const
-{
- QChar fillChar;
- switch (type) {
- case AmPmSection: return count == 1 ? QLatin1String("AP") : QLatin1String("ap");
- case MSecSection: fillChar = QLatin1Char('z'); break;
- case SecondSection: fillChar = QLatin1Char('s'); break;
- case MinuteSection: fillChar = QLatin1Char('m'); break;
- case Hour24Section: fillChar = QLatin1Char('H'); break;
- case Hour12Section: fillChar = QLatin1Char('h'); break;
- case DayOfWeekSectionShort:
- case DayOfWeekSectionLong:
- case DaySection: fillChar = QLatin1Char('d'); break;
- case MonthSection: fillChar = QLatin1Char('M'); break;
- case YearSection2Digits:
- case YearSection: fillChar = QLatin1Char('y'); break;
- default:
- qWarning("QDateTimeParser::sectionFormat Internal error (%ls)",
- qUtf16Printable(name(type)));
- return QString();
- }
- if (fillChar.isNull()) {
- qWarning("QDateTimeParser::sectionFormat Internal error 2");
- return QString();
- }
- return QString(count, fillChar);
-}
-
-
-/*!
- \internal
-
- Returns \c true if str can be modified to represent a
- number that is within min and max.
-*/
-
-bool QDateTimeParser::potentialValue(const QStringRef &str, int min, int max, int index,
- const QDateTime &currentValue, int insert) const
-{
- if (str.isEmpty()) {
- return true;
- }
- const int size = sectionMaxSize(index);
- int val = (int)locale().toUInt(str);
- const SectionNode &sn = sectionNode(index);
- if (sn.type == YearSection2Digits) {
- const int year = currentValue.date().year();
- val += year - (year % 100);
- }
- if (val >= min && val <= max && str.size() == size) {
- return true;
- } else if (val > max) {
- return false;
- } else if (str.size() == size && val < min) {
- return false;
- }
-
- const int len = size - str.size();
- for (int i=0; i<len; ++i) {
- for (int j=0; j<10; ++j) {
- if (potentialValue(str + QLatin1Char('0' + j), min, max, index, currentValue, insert)) {
- return true;
- } else if (insert >= 0) {
- const QString tmp = str.left(insert) + QLatin1Char('0' + j) + str.mid(insert);
- if (potentialValue(tmp, min, max, index, currentValue, insert))
- return true;
- }
- }
- }
-
- return false;
-}
-
-/*!
- \internal
-*/
-bool QDateTimeParser::skipToNextSection(int index, const QDateTime &current, const QStringRef &text) const
-{
- Q_ASSERT(text.size() < sectionMaxSize(index));
- const SectionNode &node = sectionNode(index);
- int min = absoluteMin(index);
- int max = absoluteMax(index, current);
- // Time-zone field is only numeric if given as offset from UTC:
- if (node.type != TimeZoneSection || current.timeSpec() == Qt::OffsetFromUTC) {
- const QDateTime maximum = getMaximum();
- const QDateTime minimum = getMinimum();
- Q_ASSERT(current >= minimum && current <= maximum);
-
- QDateTime tmp = current;
- if (!setDigit(tmp, index, min) || tmp < minimum)
- min = getDigit(minimum, index);
-
- if (!setDigit(tmp, index, max) || tmp > maximum)
- max = getDigit(maximum, index);
- }
- int pos = cursorPosition() - node.pos;
- if (pos < 0 || pos >= text.size())
- pos = -1;
-
- /*
- If the value potentially can become another valid entry we don't want to
- skip to the next. E.g. In a M field (month without leading 0) if you type
- 1 we don't want to autoskip (there might be [012] following) but if you
- type 3 we do.
- */
- return !potentialValue(text, min, max, index, current, pos);
-}
-
-/*!
- \internal
- For debugging. Returns the name of the section \a s.
-*/
-
-QString QDateTimeParser::SectionNode::name(QDateTimeParser::Section s)
-{
- switch (s) {
- case QDateTimeParser::AmPmSection: return QLatin1String("AmPmSection");
- case QDateTimeParser::DaySection: return QLatin1String("DaySection");
- case QDateTimeParser::DayOfWeekSectionShort: return QLatin1String("DayOfWeekSectionShort");
- case QDateTimeParser::DayOfWeekSectionLong: return QLatin1String("DayOfWeekSectionLong");
- case QDateTimeParser::Hour24Section: return QLatin1String("Hour24Section");
- case QDateTimeParser::Hour12Section: return QLatin1String("Hour12Section");
- case QDateTimeParser::MSecSection: return QLatin1String("MSecSection");
- case QDateTimeParser::MinuteSection: return QLatin1String("MinuteSection");
- case QDateTimeParser::MonthSection: return QLatin1String("MonthSection");
- case QDateTimeParser::SecondSection: return QLatin1String("SecondSection");
- case QDateTimeParser::TimeZoneSection: return QLatin1String("TimeZoneSection");
- case QDateTimeParser::YearSection: return QLatin1String("YearSection");
- case QDateTimeParser::YearSection2Digits: return QLatin1String("YearSection2Digits");
- case QDateTimeParser::NoSection: return QLatin1String("NoSection");
- case QDateTimeParser::FirstSection: return QLatin1String("FirstSection");
- case QDateTimeParser::LastSection: return QLatin1String("LastSection");
- default: return QLatin1String("Unknown section ") + QString::number(int(s));
- }
-}
-
-/*!
- \internal
- For debugging. Returns the name of the state \a s.
-*/
-
-QString QDateTimeParser::stateName(State s) const
-{
- switch (s) {
- case Invalid: return QLatin1String("Invalid");
- case Intermediate: return QLatin1String("Intermediate");
- case Acceptable: return QLatin1String("Acceptable");
- default: return QLatin1String("Unknown state ") + QString::number(s);
- }
-}
-
-#if QT_CONFIG(datestring)
-bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) const
-{
- QDateTime val(QDate(1900, 1, 1).startOfDay());
- const StateNode tmp = parse(t, -1, val, false);
- if (tmp.state != Acceptable || tmp.conflicts) {
- return false;
- }
- if (time) {
- const QTime t = tmp.value.time();
- if (!t.isValid()) {
- return false;
- }
- *time = t;
- }
-
- if (date) {
- const QDate d = tmp.value.date();
- if (!d.isValid()) {
- return false;
- }
- *date = d;
- }
- return true;
-}
-#endif // datestring
-
-QDateTime QDateTimeParser::getMinimum() const
-{
- // Cache the most common case
- if (spec == Qt::LocalTime) {
- static const QDateTime localTimeMin(QDATETIMEEDIT_DATE_MIN.startOfDay(Qt::LocalTime));
- return localTimeMin;
- }
- return QDateTime(QDATETIMEEDIT_DATE_MIN.startOfDay(spec));
-}
-
-QDateTime QDateTimeParser::getMaximum() const
-{
- // Cache the most common case
- if (spec == Qt::LocalTime) {
- static const QDateTime localTimeMax(QDATETIMEEDIT_DATE_MAX.endOfDay(Qt::LocalTime));
- return localTimeMax;
- }
- return QDateTime(QDATETIMEEDIT_DATE_MAX.endOfDay(spec));
-}
-
-QString QDateTimeParser::getAmPmText(AmPm ap, Case cs) const
-{
- const QLocale loc = locale();
- QString raw = ap == AmText ? loc.amText() : loc.pmText();
- return cs == UpperCase ? raw.toUpper() : raw.toLower();
-}
-
-/*
- \internal
-
- I give arg2 preference because arg1 is always a QDateTime.
-*/
-
-bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::SectionNode &s2)
-{
- return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count);
-}
-
-QT_END_NAMESPACE
diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h
deleted file mode 100644
index d9e39f0795..0000000000
--- a/src/corelib/tools/qdatetimeparser_p.h
+++ /dev/null
@@ -1,310 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDATETIMEPARSER_P_H
-#define QDATETIMEPARSER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/private/qglobal_p.h>
-#include "qplatformdefs.h"
-#include "QtCore/qatomic.h"
-#include "QtCore/qdatetime.h"
-#include "QtCore/qstringlist.h"
-#include "QtCore/qlocale.h"
-#ifndef QT_BOOTSTRAPPED
-# include "QtCore/qvariant.h"
-#endif
-#include "QtCore/qvector.h"
-#include "QtCore/qcoreapplication.h"
-
-QT_REQUIRE_CONFIG(datetimeparser);
-
-#define QDATETIMEEDIT_TIME_MIN QTime(0, 0) // Prefer QDate::startOfDay()
-#define QDATETIMEEDIT_TIME_MAX QTime(23, 59, 59, 999) // Prefer QDate::endOfDay()
-#define QDATETIMEEDIT_DATE_MIN QDate(100, 1, 1)
-#define QDATETIMEEDIT_COMPAT_DATE_MIN QDate(1752, 9, 14)
-#define QDATETIMEEDIT_DATE_MAX QDate(9999, 12, 31)
-#define QDATETIMEEDIT_DATE_INITIAL QDate(2000, 1, 1)
-
-QT_BEGIN_NAMESPACE
-
-class Q_CORE_EXPORT QDateTimeParser
-{
- Q_DECLARE_TR_FUNCTIONS(QDateTimeParser)
-public:
- enum Context {
- FromString,
- DateTimeEdit
- };
- QDateTimeParser(QVariant::Type t, Context ctx)
- : currentSectionIndex(-1), display(nullptr), cachedDay(-1), parserType(t),
- fixday(false), spec(Qt::LocalTime), context(ctx)
- {
- defaultLocale = QLocale::system();
- first.type = FirstSection;
- first.pos = -1;
- first.count = -1;
- first.zeroesAdded = 0;
- last.type = LastSection;
- last.pos = -1;
- last.count = -1;
- last.zeroesAdded = 0;
- none.type = NoSection;
- none.pos = -1;
- none.count = -1;
- none.zeroesAdded = 0;
- }
- virtual ~QDateTimeParser();
-
- enum Section {
- NoSection = 0x00000,
- AmPmSection = 0x00001,
- MSecSection = 0x00002,
- SecondSection = 0x00004,
- MinuteSection = 0x00008,
- Hour12Section = 0x00010,
- Hour24Section = 0x00020,
- TimeZoneSection = 0x00040,
- HourSectionMask = (Hour12Section | Hour24Section),
- TimeSectionMask = (MSecSection | SecondSection | MinuteSection |
- HourSectionMask | AmPmSection | TimeZoneSection),
-
- DaySection = 0x00100,
- MonthSection = 0x00200,
- YearSection = 0x00400,
- YearSection2Digits = 0x00800,
- YearSectionMask = YearSection | YearSection2Digits,
- DayOfWeekSectionShort = 0x01000,
- DayOfWeekSectionLong = 0x02000,
- DayOfWeekSectionMask = DayOfWeekSectionShort | DayOfWeekSectionLong,
- DaySectionMask = DaySection | DayOfWeekSectionMask,
- DateSectionMask = DaySectionMask | MonthSection | YearSectionMask,
-
- Internal = 0x10000,
- FirstSection = 0x20000 | Internal,
- LastSection = 0x40000 | Internal,
- CalendarPopupSection = 0x80000 | Internal,
-
- NoSectionIndex = -1,
- FirstSectionIndex = -2,
- LastSectionIndex = -3,
- CalendarPopupIndex = -4
- }; // extending qdatetimeedit.h's equivalent
- Q_DECLARE_FLAGS(Sections, Section)
-
- struct Q_CORE_EXPORT SectionNode {
- Section type;
- mutable int pos;
- int count;
- int zeroesAdded;
-
- static QString name(Section s);
- QString name() const { return name(type); }
- QString format() const;
- int maxChange() const;
- };
-
- enum State { // duplicated from QValidator
- Invalid,
- Intermediate,
- Acceptable
- };
-
- struct StateNode {
- StateNode() : state(Invalid), padded(0), conflicts(false) {}
- StateNode(const QDateTime &val, State ok=Acceptable, int pad=0, bool bad=false)
- : value(val), state(ok), padded(pad), conflicts(bad) {}
- QString input;
- QDateTime value;
- State state;
- int padded;
- bool conflicts;
- };
-
- enum AmPm {
- AmText,
- PmText
- };
-
- enum Case {
- UpperCase,
- LowerCase
- };
-
-#if QT_CONFIG(datestring)
- StateNode parse(QString input, int position, const QDateTime &defaultValue, bool fixup) const;
- bool fromString(const QString &text, QDate *date, QTime *time) const;
-#endif
- bool parseFormat(const QString &format);
-
- enum FieldInfoFlag {
- Numeric = 0x01,
- FixedWidth = 0x02,
- AllowPartial = 0x04,
- Fraction = 0x08
- };
- Q_DECLARE_FLAGS(FieldInfo, FieldInfoFlag)
-
- FieldInfo fieldInfo(int index) const;
-
- void setDefaultLocale(const QLocale &loc) { defaultLocale = loc; }
- virtual QString displayText() const { return text; }
-
-private:
- int sectionMaxSize(Section s, int count) const;
- QString sectionText(const QString &text, int sectionIndex, int index) const;
-#if QT_CONFIG(datestring)
- StateNode scanString(const QDateTime &defaultValue,
- bool fixup, QString *input) const;
- struct ParsedSection {
- int value;
- int used;
- int zeroes;
- State state;
- Q_DECL_CONSTEXPR ParsedSection(State ok = Invalid,
- int val = 0, int read = 0, int zs = 0)
- : value(ok == Invalid ? -1 : val), used(read), zeroes(zs), state(ok)
- {}
- };
- ParsedSection parseSection(const QDateTime &currentValue, int sectionIndex,
- int offset, QString *text) const;
- int findMonth(const QString &str1, int monthstart, int sectionIndex,
- QString *monthName = nullptr, int *used = nullptr) const;
- int findDay(const QString &str1, int intDaystart, int sectionIndex,
- QString *dayName = nullptr, int *used = nullptr) const;
- ParsedSection findTimeZone(QStringRef str, const QDateTime &when,
- int maxVal, int minVal) const;
-#if QT_CONFIG(timezone)
- // Implemented in qdatetime.cpp:
- static int startsWithLocalTimeZone(const QStringRef name);
-#endif
-
- enum AmPmFinder {
- Neither = -1,
- AM = 0,
- PM = 1,
- PossibleAM = 2,
- PossiblePM = 3,
- PossibleBoth = 4
- };
- AmPmFinder findAmPm(QString &str, int index, int *used = nullptr) const;
-#endif // datestring
-
- bool potentialValue(const QStringRef &str, int min, int max, int index,
- const QDateTime &currentValue, int insert) const;
- bool potentialValue(const QString &str, int min, int max, int index,
- const QDateTime &currentValue, int insert) const
- {
- return potentialValue(QStringRef(&str), min, max, index, currentValue, insert);
- }
-
-protected: // for the benefit of QDateTimeEditPrivate
- int sectionSize(int index) const;
- int sectionMaxSize(int index) const;
- int sectionPos(int index) const;
- int sectionPos(const SectionNode &sn) const;
-
- const SectionNode &sectionNode(int index) const;
- Section sectionType(int index) const;
- QString sectionText(int sectionIndex) const;
- int getDigit(const QDateTime &dt, int index) const;
- bool setDigit(QDateTime &t, int index, int newval) const;
-
- int absoluteMax(int index, const QDateTime &value = QDateTime()) const;
- int absoluteMin(int index) const;
-
- bool skipToNextSection(int section, const QDateTime &current, const QStringRef &sectionText) const;
- bool skipToNextSection(int section, const QDateTime &current, const QString &sectionText) const
- {
- return skipToNextSection(section, current, QStringRef(&sectionText));
- }
- QString stateName(State s) const;
- virtual QDateTime getMinimum() const;
- virtual QDateTime getMaximum() const;
- virtual int cursorPosition() const { return -1; }
- virtual QString getAmPmText(AmPm ap, Case cs) const;
- virtual QLocale locale() const { return defaultLocale; }
-
- mutable int currentSectionIndex;
- Sections display;
- /*
- This stores the most recently selected day.
- It is useful when considering the following scenario:
-
- 1. Date is: 31/01/2000
- 2. User increments month: 29/02/2000
- 3. User increments month: 31/03/2000
-
- At step 1, cachedDay stores 31. At step 2, the 31 is invalid for February, so the cachedDay is not updated.
- At step 3, the month is changed to March, for which 31 is a valid day. Since 29 < 31, the day is set to cachedDay.
- This is good for when users have selected their desired day and are scrolling up or down in the month or year section
- and do not want smaller months (or non-leap years) to alter the day that they chose.
- */
- mutable int cachedDay;
- mutable QString text;
- QVector<SectionNode> sectionNodes;
- SectionNode first, last, none, popup;
- QStringList separators;
- QString displayFormat;
- QLocale defaultLocale;
- QVariant::Type parserType;
- bool fixday;
- Qt::TimeSpec spec; // spec if used by QDateTimeEdit
- Context context;
-};
-Q_DECLARE_TYPEINFO(QDateTimeParser::SectionNode, Q_PRIMITIVE_TYPE);
-
-Q_CORE_EXPORT bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::SectionNode &s2);
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::Sections)
-Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::FieldInfo)
-
-QT_END_NAMESPACE
-
-#endif // QDATETIME_P_H
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index f6eaa53c3a..c8740e55f3 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -55,7 +55,7 @@
#include "qlocale_p.h"
#include "qlocale_tools_p.h"
#if QT_CONFIG(datetimeparser)
-#include "qdatetimeparser_p.h"
+#include "private/qdatetimeparser_p.h"
#endif
#include "qnamespace.h"
#include "qdatetime.h"
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
deleted file mode 100644
index ef323de14a..0000000000
--- a/src/corelib/tools/qtimezone.cpp
+++ /dev/null
@@ -1,997 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 John Layt <jlayt@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qtimezone.h"
-#include "qtimezoneprivate_p.h"
-
-#include <QtCore/qdatastream.h>
-#include <QtCore/qdatetime.h>
-
-#include <qdebug.h>
-
-#include <algorithm>
-
-QT_BEGIN_NAMESPACE
-
-// Create default time zone using appropriate backend
-static QTimeZonePrivate *newBackendTimeZone()
-{
-#ifdef QT_NO_SYSTEMLOCALE
-#if QT_CONFIG(icu)
- return new QIcuTimeZonePrivate();
-#else
- return new QUtcTimeZonePrivate();
-#endif
-#else
-#if defined Q_OS_MAC
- return new QMacTimeZonePrivate();
-#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- return new QAndroidTimeZonePrivate();
-#elif defined(Q_OS_UNIX) || defined(Q_OS_ANDROID_EMBEDDED)
- return new QTzTimeZonePrivate();
-#elif QT_CONFIG(icu)
- return new QIcuTimeZonePrivate();
-#elif defined Q_OS_WIN
- return new QWinTimeZonePrivate();
-#else
- return new QUtcTimeZonePrivate();
-#endif // System Locales
-#endif // QT_NO_SYSTEMLOCALE
-}
-
-// Create named time zone using appropriate backend
-static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
-{
-#ifdef QT_NO_SYSTEMLOCALE
-#if QT_CONFIG(icu)
- return new QIcuTimeZonePrivate(ianaId);
-#else
- return new QUtcTimeZonePrivate(ianaId);
-#endif
-#else
-#if defined Q_OS_MAC
- return new QMacTimeZonePrivate(ianaId);
-#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
- return new QAndroidTimeZonePrivate(ianaId);
-#elif defined(Q_OS_UNIX) || defined(Q_OS_ANDROID_EMBEDDED)
- return new QTzTimeZonePrivate(ianaId);
-#elif QT_CONFIG(icu)
- return new QIcuTimeZonePrivate(ianaId);
-#elif defined Q_OS_WIN
- return new QWinTimeZonePrivate(ianaId);
-#else
- return new QUtcTimeZonePrivate(ianaId);
-#endif // System Locales
-#endif // QT_NO_SYSTEMLOCALE
-}
-
-class QTimeZoneSingleton
-{
-public:
- QTimeZoneSingleton() : backend(newBackendTimeZone()) {}
-
- // The backend_tz is the tz to use in static methods such as availableTimeZoneIds() and
- // isTimeZoneIdAvailable() and to create named IANA time zones. This is usually the host
- // system, but may be different if the host resources are insufficient or if
- // QT_NO_SYSTEMLOCALE is set. A simple UTC backend is used if no alternative is available.
- QSharedDataPointer<QTimeZonePrivate> backend;
-};
-
-Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
-
-/*!
- \class QTimeZone
- \inmodule QtCore
- \since 5.2
-
- \brief The QTimeZone class converts between UTC and local time in a specific
- time zone.
-
- \threadsafe
-
- This class provides a stateless calculator for time zone conversions
- between UTC and the local time in a specific time zone. By default it uses
- the host system time zone data to perform these conversions.
-
- This class is primarily designed for use in QDateTime; most applications
- will not need to access this class directly and should instead use
- QDateTime with a Qt::TimeSpec of Qt::TimeZone.
-
- \note For consistency with QDateTime, QTimeZone does not account for leap
- seconds.
-
- \section1 Remarks
-
- \section2 IANA Time Zone IDs
-
- QTimeZone uses the IANA time zone IDs as defined in the IANA Time Zone
- Database (http://www.iana.org/time-zones). This is to ensure a standard ID
- across all supported platforms. Most platforms support the IANA IDs
- and the IANA Database natively, but for Windows a mapping is required to
- the native IDs. See below for more details.
-
- The IANA IDs can and do change on a regular basis, and can vary depending
- on how recently the host system data was updated. As such you cannot rely
- on any given ID existing on any host system. You must use
- availableTimeZoneIds() to determine what IANA IDs are available.
-
- The IANA IDs and database are also know as the Olson IDs and database,
- named after their creator.
-
- \section2 UTC Offset Time Zones
-
- A default UTC time zone backend is provided which is always guaranteed to
- be available. This provides a set of generic Offset From UTC time zones
- in the range UTC-14:00 to UTC+14:00. These time zones can be created
- using either the standard ISO format names "UTC+00:00" as listed by
- availableTimeZoneIds(), or using the number of offset seconds.
-
- \section2 Windows Time Zones
-
- Windows native time zone support is severely limited compared to the
- standard IANA TZ Database. Windows time zones cover larger geographic
- areas and are thus less accurate in their conversions. They also do not
- support as much historic conversion data and so may only be accurate for
- the current year.
-
- QTimeZone uses a conversion table derived form the Unicode CLDR data to map
- between IANA IDs and Windows IDs. Depending on your version of Windows
- and Qt, this table may not be able to provide a valid conversion, in which
- "UTC" will be returned.
-
- QTimeZone provides a public API to use this conversion table. The Windows ID
- used is the Windows Registry Key for the time zone which is also the MS
- Exchange EWS ID as well, but is different to the Time Zone Name (TZID) and
- COD code used by MS Exchange in versions before 2007.
-
- \section2 System Time Zone
-
- QTimeZone does not support any concept of a system or default time zone.
- If you require a QDateTime that uses the current system time zone at any
- given moment then you should use a Qt::TimeSpec of Qt::LocalTime.
-
- The method systemTimeZoneId() returns the current system IANA time zone
- ID which on Unix-like systems will always be correct. On Windows this ID is
- translated from the Windows system ID using an internal translation
- table and the user's selected country. As a consequence there is a small
- chance any Windows install may have IDs not known by Qt, in which case
- "UTC" will be returned.
-
- Creating a new QTimeZone instance using the system time zone ID will only
- produce a fixed named copy of the time zone, it will not change if the
- system time zone changes.
-
- \section2 Time Zone Offsets
-
- The difference between UTC and the local time in a time zone is expressed
- as an offset in seconds from UTC, i.e. the number of seconds to add to UTC
- to obtain the local time. The total offset is comprised of two component
- parts, the standard time offset and the daylight-saving time offset. The
- standard time offset is the number of seconds to add to UTC to obtain
- standard time in the time zone. The daylight-saving time offset is the
- number of seconds to add to the standard time offset to obtain
- daylight-saving time (abbreviated DST and sometimes called "daylight time"
- or "summer time") in the time zone.
-
- Note that the standard and DST offsets for a time zone may change over time
- as countries have changed DST laws or even their standard time offset.
-
- \section2 License
-
- This class includes data obtained from the CLDR data files under the terms
- of the Unicode Data Files and Software License. See
- \l{Unicode Common Locale Data Repository (CLDR)} for details.
-
- \sa QDateTime
-*/
-
-/*!
- \enum QTimeZone::anonymous
-
- Sane UTC offsets range from -14 to +14 hours.
- No known zone > 12 hrs West of Greenwich (Baker Island, USA).
- No known zone > 14 hrs East of Greenwich (Kiritimati, Christmas Island, Kiribati).
-
- \value MinUtcOffsetSecs
- -14 * 3600,
-
- \value MaxUtcOffsetSecs
- +14 * 3600
-*/
-
-/*!
- \enum QTimeZone::TimeType
-
- The type of time zone time, for example when requesting the name. In time
- zones that do not apply DST, all three values may return the same result.
-
- \value StandardTime
- The standard time in a time zone, i.e. when Daylight-Saving is not
- in effect.
- For example when formatting a display name this will show something
- like "Pacific Standard Time".
- \value DaylightTime
- A time when Daylight-Saving is in effect.
- For example when formatting a display name this will show something
- like "Pacific daylight-saving time".
- \value GenericTime
- A time which is not specifically Standard or Daylight-Saving time,
- either an unknown time or a neutral form.
- For example when formatting a display name this will show something
- like "Pacific Time".
-*/
-
-/*!
- \enum QTimeZone::NameType
-
- The type of time zone name.
-
- \value DefaultName
- The default form of the time zone name, e.g. LongName, ShortName or OffsetName
- \value LongName
- The long form of the time zone name, e.g. "Central European Time"
- \value ShortName
- The short form of the time zone name, usually an abbreviation, e.g. "CET"
- \value OffsetName
- The standard ISO offset form of the time zone name, e.g. "UTC+01:00"
-*/
-
-/*!
- \class QTimeZone::OffsetData
- \inmodule QtCore
-
- The time zone offset data for a given moment in time, i.e. the time zone
- offsets and abbreviation to use at that moment in time.
-
- \list
- \li OffsetData::atUtc The datetime of the offset data in UTC time.
- \li OffsetData::offsetFromUtc The total offset from UTC in effect at the datetime.
- \li OffsetData::standardTimeOffset The standard time offset component of the total offset.
- \li OffsetData::daylightTimeOffset The DST offset component of the total offset.
- \li OffsetData::abbreviation The abbreviation in effect at the datetime.
- \endlist
-
- For example, for time zone "Europe/Berlin" the OffsetDate in standard and DST might be:
-
- \list
- \li atUtc = QDateTime(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC)
- \li offsetFromUtc = 3600
- \li standardTimeOffset = 3600
- \li daylightTimeOffset = 0
- \li abbreviation = "CET"
- \endlist
-
- \list
- \li atUtc = QDateTime(QDate(2013, 6, 1), QTime(0, 0, 0), Qt::UTC)
- \li offsetFromUtc = 7200
- \li standardTimeOffset = 3600
- \li daylightTimeOffset = 3600
- \li abbreviation = "CEST"
- \endlist
-*/
-
-/*!
- \typedef QTimeZone::OffsetDataList
-
- Synonym for QVector<OffsetData>.
-*/
-
-/*!
- Create a null/invalid time zone instance.
-*/
-
-QTimeZone::QTimeZone() noexcept
- : d(0)
-{
-}
-
-/*!
- Creates an instance of the requested time zone \a ianaId.
-
- The ID must be one of the available system IDs otherwise an invalid
- time zone will be returned.
-
- \sa availableTimeZoneIds()
-*/
-
-QTimeZone::QTimeZone(const QByteArray &ianaId)
-{
- // Try and see if it's a valid UTC offset ID, just as quick to try create as look-up
- d = new QUtcTimeZonePrivate(ianaId);
- // If not a valid UTC offset ID then try create it with the system backend
- // Relies on backend not creating valid tz with invalid name
- if (!d->isValid())
- d = newBackendTimeZone(ianaId);
-}
-
-/*!
- Creates an instance of a time zone with the requested Offset from UTC of
- \a offsetSeconds.
-
- The \a offsetSeconds from UTC must be in the range -14 hours to +14 hours
- otherwise an invalid time zone will be returned.
-*/
-
-QTimeZone::QTimeZone(int offsetSeconds)
- : d((offsetSeconds >= MinUtcOffsetSecs && offsetSeconds <= MaxUtcOffsetSecs)
- ? new QUtcTimeZonePrivate(offsetSeconds) : nullptr)
-{
-}
-
-/*!
- Creates a custom time zone with an ID of \a ianaId and an offset from UTC
- of \a offsetSeconds. The \a name will be the name used by displayName()
- for the LongName, the \a abbreviation will be used by displayName() for the
- ShortName and by abbreviation(), and the optional \a country will be used
- by country(). The \a comment is an optional note that may be displayed in
- a GUI to assist users in selecting a time zone.
-
- The \a ianaId must not be one of the available system IDs returned by
- availableTimeZoneIds(). The \a offsetSeconds from UTC must be in the range
- -14 hours to +14 hours.
-
- If the custom time zone does not have a specific country then set it to the
- default value of QLocale::AnyCountry.
-*/
-
-QTimeZone::QTimeZone(const QByteArray &ianaId, int offsetSeconds, const QString &name,
- const QString &abbreviation, QLocale::Country country, const QString &comment)
- : d()
-{
- if (!isTimeZoneIdAvailable(ianaId))
- d = new QUtcTimeZonePrivate(ianaId, offsetSeconds, name, abbreviation, country, comment);
-}
-
-/*!
- \internal
-
- Private. Create time zone with given private backend
-*/
-
-QTimeZone::QTimeZone(QTimeZonePrivate &dd)
- : d(&dd)
-{
-}
-
-/*!
- Copy constructor, copy \a other to this.
-*/
-
-QTimeZone::QTimeZone(const QTimeZone &other)
- : d(other.d)
-{
-}
-
-/*!
- Destroys the time zone.
-*/
-
-QTimeZone::~QTimeZone()
-{
-}
-
-/*!
- \fn QTimeZone::swap(QTimeZone &other)
-
- Swaps this time zone instance with \a other. This function is very
- fast and never fails.
-*/
-
-/*!
- Assignment operator, assign \a other to this.
-*/
-
-QTimeZone &QTimeZone::operator=(const QTimeZone &other)
-{
- d = other.d;
- return *this;
-}
-
-/*
- \fn void QTimeZone::swap(QTimeZone &other)
-
- Swaps this timezone with \a other. This function is very fast and
- never fails.
-*/
-
-/*!
- \fn QTimeZone &QTimeZone::operator=(QTimeZone &&other)
-
- Move-assigns \a other to this QTimeZone instance, transferring the
- ownership of the managed pointer to this instance.
-*/
-
-/*!
- Returns \c true if this time zone is equal to the \a other time zone.
-*/
-
-bool QTimeZone::operator==(const QTimeZone &other) const
-{
- if (d && other.d)
- return (*d == *other.d);
- else
- return (d == other.d);
-}
-
-/*!
- Returns \c true if this time zone is not equal to the \a other time zone.
-*/
-
-bool QTimeZone::operator!=(const QTimeZone &other) const
-{
- if (d && other.d)
- return (*d != *other.d);
- else
- return (d != other.d);
-}
-
-/*!
- Returns \c true if this time zone is valid.
-*/
-
-bool QTimeZone::isValid() const
-{
- if (d)
- return d->isValid();
- else
- return false;
-}
-
-/*!
- Returns the IANA ID for the time zone.
-
- IANA IDs are used on all platforms. On Windows these are translated
- from the Windows ID into the closest IANA ID for the time zone and country.
-*/
-
-QByteArray QTimeZone::id() const
-{
- if (d)
- return d->id();
- else
- return QByteArray();
-}
-
-/*!
- Returns the country for the time zone.
-*/
-
-QLocale::Country QTimeZone::country() const
-{
- if (isValid())
- return d->country();
- else
- return QLocale::AnyCountry;
-}
-
-/*!
- Returns any comment for the time zone.
-
- A comment may be provided by the host platform to assist users in
- choosing the correct time zone. Depending on the platform this may not
- be localized.
-*/
-
-QString QTimeZone::comment() const
-{
- if (isValid())
- return d->comment();
- else
- return QString();
-}
-
-/*!
- Returns the localized time zone display name at the given \a atDateTime
- for the given \a nameType in the given \a locale. The \a nameType and
- \a locale requested may not be supported on all platforms, in which case
- the best available option will be returned.
-
- If the \a locale is not provided then the application default locale will
- be used.
-
- The display name may change depending on DST or historical events.
-
- \sa abbreviation()
-*/
-
-QString QTimeZone::displayName(const QDateTime &atDateTime, NameType nameType,
- const QLocale &locale) const
-{
- if (isValid())
- return d->displayName(atDateTime.toMSecsSinceEpoch(), nameType, locale);
- else
- return QString();
-}
-
-/*!
- Returns the localized time zone display name for the given \a timeType
- and \a nameType in the given \a locale. The \a nameType and \a locale
- requested may not be supported on all platforms, in which case the best
- available option will be returned.
-
- If the \a locale is not provided then the application default locale will
- be used.
-
- Where the time zone display names have changed over time then the most
- recent names will be used.
-
- \sa abbreviation()
-*/
-
-QString QTimeZone::displayName(TimeType timeType, NameType nameType,
- const QLocale &locale) const
-{
- if (isValid())
- return d->displayName(timeType, nameType, locale);
- else
- return QString();
-}
-
-/*!
- Returns the time zone abbreviation at the given \a atDateTime. The
- abbreviation may change depending on DST or even historical events.
-
- Note that the abbreviation is not guaranteed to be unique to this time zone
- and should not be used in place of the ID or display name.
-
- \sa displayName()
-*/
-
-QString QTimeZone::abbreviation(const QDateTime &atDateTime) const
-{
- if (isValid())
- return d->abbreviation(atDateTime.toMSecsSinceEpoch());
- else
- return QString();
-}
-
-/*!
- Returns the total effective offset at the given \a atDateTime, i.e. the
- number of seconds to add to UTC to obtain the local time. This includes
- any DST offset that may be in effect, i.e. it is the sum of
- standardTimeOffset() and daylightTimeOffset() for the given datetime.
-
- For example, for the time zone "Europe/Berlin" the standard time offset is
- +3600 seconds and the DST offset is +3600 seconds. During standard time
- offsetFromUtc() will return +3600 (UTC+01:00), and during DST it will
- return +7200 (UTC+02:00).
-
- \sa standardTimeOffset(), daylightTimeOffset()
-*/
-
-int QTimeZone::offsetFromUtc(const QDateTime &atDateTime) const
-{
- if (isValid())
- return d->offsetFromUtc(atDateTime.toMSecsSinceEpoch());
- else
- return 0;
-}
-
-/*!
- Returns the standard time offset at the given \a atDateTime, i.e. the
- number of seconds to add to UTC to obtain the local Standard Time. This
- excludes any DST offset that may be in effect.
-
- For example, for the time zone "Europe/Berlin" the standard time offset is
- +3600 seconds. During both standard and DST offsetFromUtc() will return
- +3600 (UTC+01:00).
-
- \sa offsetFromUtc(), daylightTimeOffset()
-*/
-
-int QTimeZone::standardTimeOffset(const QDateTime &atDateTime) const
-{
- if (isValid())
- return d->standardTimeOffset(atDateTime.toMSecsSinceEpoch());
- else
- return 0;
-}
-
-/*!
- Returns the daylight-saving time offset at the given \a atDateTime,
- i.e. the number of seconds to add to the standard time offset to obtain the
- local daylight-saving time.
-
- For example, for the time zone "Europe/Berlin" the DST offset is +3600
- seconds. During standard time daylightTimeOffset() will return 0, and when
- daylight-saving is in effect it will return +3600.
-
- \sa offsetFromUtc(), standardTimeOffset()
-*/
-
-int QTimeZone::daylightTimeOffset(const QDateTime &atDateTime) const
-{
- if (hasDaylightTime())
- return d->daylightTimeOffset(atDateTime.toMSecsSinceEpoch());
- else
- return 0;
-}
-
-/*!
- Returns \c true if the time zone has practiced daylight-saving at any time.
-
- \sa isDaylightTime(), daylightTimeOffset()
-*/
-
-bool QTimeZone::hasDaylightTime() const
-{
- if (isValid())
- return d->hasDaylightTime();
- else
- return false;
-}
-
-/*!
- Returns \c true if daylight-saving was in effect at the given \a atDateTime.
-
- \sa hasDaylightTime(), daylightTimeOffset()
-*/
-
-bool QTimeZone::isDaylightTime(const QDateTime &atDateTime) const
-{
- if (hasDaylightTime())
- return d->isDaylightTime(atDateTime.toMSecsSinceEpoch());
- else
- return false;
-}
-
-/*!
- Returns the effective offset details at the given \a forDateTime. This is
- the equivalent of calling offsetFromUtc(), abbreviation(), etc individually but is
- more efficient.
-
- \sa offsetFromUtc(), standardTimeOffset(), daylightTimeOffset(), abbreviation()
-*/
-
-QTimeZone::OffsetData QTimeZone::offsetData(const QDateTime &forDateTime) const
-{
- if (hasTransitions())
- return QTimeZonePrivate::toOffsetData(d->data(forDateTime.toMSecsSinceEpoch()));
- else
- return QTimeZonePrivate::invalidOffsetData();
-}
-
-/*!
- Returns \c true if the system backend supports obtaining transitions.
-
- Transitions are changes in the time-zone: these happen when DST turns on or
- off and when authorities alter the offsets for the time-zone.
-
- \sa nextTransition(), previousTransition(), transitions()
-*/
-
-bool QTimeZone::hasTransitions() const
-{
- if (isValid())
- return d->hasTransitions();
- else
- return false;
-}
-
-/*!
- Returns the first time zone Transition after the given \a afterDateTime.
- This is most useful when you have a Transition time and wish to find the
- Transition after it.
-
- If there is no transition after the given \a afterDateTime then an invalid
- OffsetData will be returned with an invalid QDateTime.
-
- The given \a afterDateTime is exclusive.
-
- \sa hasTransitions(), previousTransition(), transitions()
-*/
-
-QTimeZone::OffsetData QTimeZone::nextTransition(const QDateTime &afterDateTime) const
-{
- if (hasTransitions())
- return QTimeZonePrivate::toOffsetData(d->nextTransition(afterDateTime.toMSecsSinceEpoch()));
- else
- return QTimeZonePrivate::invalidOffsetData();
-}
-
-/*!
- Returns the first time zone Transition before the given \a beforeDateTime.
- This is most useful when you have a Transition time and wish to find the
- Transition before it.
-
- If there is no transition before the given \a beforeDateTime then an invalid
- OffsetData will be returned with an invalid QDateTime.
-
- The given \a beforeDateTime is exclusive.
-
- \sa hasTransitions(), nextTransition(), transitions()
-*/
-
-QTimeZone::OffsetData QTimeZone::previousTransition(const QDateTime &beforeDateTime) const
-{
- if (hasTransitions())
- return QTimeZonePrivate::toOffsetData(d->previousTransition(beforeDateTime.toMSecsSinceEpoch()));
- else
- return QTimeZonePrivate::invalidOffsetData();
-}
-
-/*!
- Returns a list of all time zone transitions between the given datetimes.
-
- The given \a fromDateTime and \a toDateTime are inclusive.
-
- \sa hasTransitions(), nextTransition(), previousTransition()
-*/
-
-QTimeZone::OffsetDataList QTimeZone::transitions(const QDateTime &fromDateTime,
- const QDateTime &toDateTime) const
-{
- OffsetDataList list;
- if (hasTransitions()) {
- const QTimeZonePrivate::DataList plist = d->transitions(fromDateTime.toMSecsSinceEpoch(),
- toDateTime.toMSecsSinceEpoch());
- list.reserve(plist.count());
- for (const QTimeZonePrivate::Data &pdata : plist)
- list.append(QTimeZonePrivate::toOffsetData(pdata));
- }
- return list;
-}
-
-// Static methods
-
-/*!
- Returns the current system time zone IANA ID.
-
- On Windows this ID is translated from the Windows ID using an internal
- translation table and the user's selected country. As a consequence there
- is a small chance any Windows install may have IDs not known by Qt, in
- which case "UTC" will be returned.
-*/
-
-QByteArray QTimeZone::systemTimeZoneId()
-{
- return global_tz->backend->systemTimeZoneId();
-}
-
-/*!
- \since 5.5
- Returns a QTimeZone object that refers to the local system time, as
- specified by systemTimeZoneId().
-
- \sa utc()
-*/
-QTimeZone QTimeZone::systemTimeZone()
-{
- return QTimeZone(QTimeZone::systemTimeZoneId());
-}
-
-/*!
- \since 5.5
- Returns a QTimeZone object that refers to UTC (Universal Time Coordinated).
-
- \sa systemTimeZone()
-*/
-QTimeZone QTimeZone::utc()
-{
- return QTimeZone(QTimeZonePrivate::utcQByteArray());
-}
-
-/*!
- Returns \c true if a given time zone \a ianaId is available on this system.
-
- \sa availableTimeZoneIds()
-*/
-
-bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &ianaId)
-{
- // isValidId is not strictly required, but faster to weed out invalid
- // IDs as availableTimeZoneIds() may be slow
- if (!QTimeZonePrivate::isValidId(ianaId))
- return false;
- return QUtcTimeZonePrivate().isTimeZoneIdAvailable(ianaId) ||
- global_tz->backend->isTimeZoneIdAvailable(ianaId);
-}
-
-static QList<QByteArray> set_union(const QList<QByteArray> &l1, const QList<QByteArray> &l2)
-{
- QList<QByteArray> result;
- result.reserve(l1.size() + l2.size());
- std::set_union(l1.begin(), l1.end(),
- l2.begin(), l2.end(),
- std::back_inserter(result));
- return result;
-}
-
-/*!
- Returns a list of all available IANA time zone IDs on this system.
-
- \sa isTimeZoneIdAvailable()
-*/
-
-QList<QByteArray> QTimeZone::availableTimeZoneIds()
-{
- return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(),
- global_tz->backend->availableTimeZoneIds());
-}
-
-/*!
- Returns a list of all available IANA time zone IDs for a given \a country.
-
- As a special case, a \a country of Qt::AnyCountry returns those time zones
- that do not have any country related to them, such as UTC. If you require
- a list of all time zone IDs for all countries then use the standard
- availableTimeZoneIds() method.
-
- \sa isTimeZoneIdAvailable()
-*/
-
-QList<QByteArray> QTimeZone::availableTimeZoneIds(QLocale::Country country)
-{
- return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(country),
- global_tz->backend->availableTimeZoneIds(country));
-}
-
-/*!
- Returns a list of all available IANA time zone IDs with a given standard
- time offset of \a offsetSeconds.
-
- \sa isTimeZoneIdAvailable()
-*/
-
-QList<QByteArray> QTimeZone::availableTimeZoneIds(int offsetSeconds)
-{
- return set_union(QUtcTimeZonePrivate().availableTimeZoneIds(offsetSeconds),
- global_tz->backend->availableTimeZoneIds(offsetSeconds));
-}
-
-/*!
- Returns the Windows ID equivalent to the given \a ianaId.
-
- \sa windowsIdToDefaultIanaId(), windowsIdToIanaIds()
-*/
-
-QByteArray QTimeZone::ianaIdToWindowsId(const QByteArray &ianaId)
-{
- return QTimeZonePrivate::ianaIdToWindowsId(ianaId);
-}
-
-/*!
- Returns the default IANA ID for a given \a windowsId.
-
- Because a Windows ID can cover several IANA IDs in several different
- countries, this function returns the most frequently used IANA ID with no
- regard for the country and should thus be used with care. It is usually
- best to request the default for a specific country.
-
- \sa ianaIdToWindowsId(), windowsIdToIanaIds()
-*/
-
-QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId)
-{
- return QTimeZonePrivate::windowsIdToDefaultIanaId(windowsId);
-}
-
-/*!
- Returns the default IANA ID for a given \a windowsId and \a country.
-
- Because a Windows ID can cover several IANA IDs within a given country,
- the most frequently used IANA ID in that country is returned.
-
- As a special case, QLocale::AnyCountry returns the default of those IANA IDs
- that do not have any specific country.
-
- \sa ianaIdToWindowsId(), windowsIdToIanaIds()
-*/
-
-QByteArray QTimeZone::windowsIdToDefaultIanaId(const QByteArray &windowsId,
- QLocale::Country country)
-{
- return QTimeZonePrivate::windowsIdToDefaultIanaId(windowsId, country);
-}
-
-/*!
- Returns all the IANA IDs for a given \a windowsId.
-
- The returned list is sorted alphabetically.
-
- \sa ianaIdToWindowsId(), windowsIdToDefaultIanaId()
-*/
-
-QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId)
-{
- return QTimeZonePrivate::windowsIdToIanaIds(windowsId);
-}
-
-/*!
- Returns all the IANA IDs for a given \a windowsId and \a country.
-
- As a special case QLocale::AnyCountry returns those IANA IDs that do
- not have any specific country.
-
- The returned list is in order of frequency of usage, i.e. larger zones
- within a country are listed first.
-
- \sa ianaIdToWindowsId(), windowsIdToDefaultIanaId()
-*/
-
-QList<QByteArray> QTimeZone::windowsIdToIanaIds(const QByteArray &windowsId,
- QLocale::Country country)
-{
- return QTimeZonePrivate::windowsIdToIanaIds(windowsId, country);
-}
-
-#ifndef QT_NO_DATASTREAM
-QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz)
-{
- tz.d->serialize(ds);
- return ds;
-}
-
-QDataStream &operator>>(QDataStream &ds, QTimeZone &tz)
-{
- QString ianaId;
- ds >> ianaId;
- if (ianaId == QLatin1String("OffsetFromUtc")) {
- int utcOffset;
- QString name;
- QString abbreviation;
- int country;
- QString comment;
- ds >> ianaId >> utcOffset >> name >> abbreviation >> country >> comment;
- // Try creating as a system timezone, which succeeds (producing a valid
- // zone) iff ianaId is valid; we can then ignore the other data.
- tz = QTimeZone(ianaId.toUtf8());
- // If not, then construct a custom timezone using all the saved values:
- if (!tz.isValid())
- tz = QTimeZone(ianaId.toUtf8(), utcOffset, name, abbreviation,
- QLocale::Country(country), comment);
- } else {
- tz = QTimeZone(ianaId.toUtf8());
- }
- return ds;
-}
-#endif // QT_NO_DATASTREAM
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug dbg, const QTimeZone &tz)
-{
- QDebugStateSaver saver(dbg);
- //TODO Include backend and data version details?
- dbg.nospace() << "QTimeZone(" << QString::fromUtf8(tz.id()) << ')';
- return dbg;
-}
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/corelib/tools/qtimezone.h b/src/corelib/tools/qtimezone.h
deleted file mode 100644
index 62ecee49bb..0000000000
--- a/src/corelib/tools/qtimezone.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 John Layt <jlayt@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QTIMEZONE_H
-#define QTIMEZONE_H
-
-#include <QtCore/qshareddata.h>
-#include <QtCore/qlocale.h>
-#include <QtCore/qdatetime.h>
-
-QT_REQUIRE_CONFIG(timezone);
-
-#if (defined(Q_OS_DARWIN) || defined(Q_QDOC)) && !defined(QT_NO_SYSTEMLOCALE)
-Q_FORWARD_DECLARE_CF_TYPE(CFTimeZone);
-Q_FORWARD_DECLARE_OBJC_CLASS(NSTimeZone);
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QTimeZonePrivate;
-
-class Q_CORE_EXPORT QTimeZone
-{
-public:
- // Sane UTC offsets range from -14 to +14 hours:
- enum {
- // No known zone > 12 hrs West of Greenwich (Baker Island, USA)
- MinUtcOffsetSecs = -14 * 3600,
- // No known zone > 14 hrs East of Greenwich (Kiritimati, Christmas Island, Kiribati)
- MaxUtcOffsetSecs = +14 * 3600
- };
-
- enum TimeType {
- StandardTime = 0,
- DaylightTime = 1,
- GenericTime = 2
- };
-
- enum NameType {
- DefaultName = 0,
- LongName = 1,
- ShortName = 2,
- OffsetName = 3
- };
-
- struct OffsetData {
- QString abbreviation;
- QDateTime atUtc;
- int offsetFromUtc;
- int standardTimeOffset;
- int daylightTimeOffset;
- };
- typedef QVector<OffsetData> OffsetDataList;
-
- QTimeZone() noexcept;
- explicit QTimeZone(const QByteArray &ianaId);
- explicit QTimeZone(int offsetSeconds);
- /*implicit*/ QTimeZone(const QByteArray &zoneId, int offsetSeconds, const QString &name,
- const QString &abbreviation, QLocale::Country country = QLocale::AnyCountry,
- const QString &comment = QString());
- QTimeZone(const QTimeZone &other);
- ~QTimeZone();
-
- QTimeZone &operator=(const QTimeZone &other);
- QTimeZone &operator=(QTimeZone &&other) noexcept { swap(other); return *this; }
-
- void swap(QTimeZone &other) noexcept
- { d.swap(other.d); }
-
- bool operator==(const QTimeZone &other) const;
- bool operator!=(const QTimeZone &other) const;
-
- bool isValid() const;
-
- QByteArray id() const;
- QLocale::Country country() const;
- QString comment() const;
-
- QString displayName(const QDateTime &atDateTime,
- QTimeZone::NameType nameType = QTimeZone::DefaultName,
- const QLocale &locale = QLocale()) const;
- QString displayName(QTimeZone::TimeType timeType,
- QTimeZone::NameType nameType = QTimeZone::DefaultName,
- const QLocale &locale = QLocale()) const;
- QString abbreviation(const QDateTime &atDateTime) const;
-
- int offsetFromUtc(const QDateTime &atDateTime) const;
- int standardTimeOffset(const QDateTime &atDateTime) const;
- int daylightTimeOffset(const QDateTime &atDateTime) const;
-
- bool hasDaylightTime() const;
- bool isDaylightTime(const QDateTime &atDateTime) const;
-
- OffsetData offsetData(const QDateTime &forDateTime) const;
-
- bool hasTransitions() const;
- OffsetData nextTransition(const QDateTime &afterDateTime) const;
- OffsetData previousTransition(const QDateTime &beforeDateTime) const;
- OffsetDataList transitions(const QDateTime &fromDateTime, const QDateTime &toDateTime) const;
-
- static QByteArray systemTimeZoneId();
- static QTimeZone systemTimeZone();
- static QTimeZone utc();
-
- static bool isTimeZoneIdAvailable(const QByteArray &ianaId);
-
- static QList<QByteArray> availableTimeZoneIds();
- static QList<QByteArray> availableTimeZoneIds(QLocale::Country country);
- static QList<QByteArray> availableTimeZoneIds(int offsetSeconds);
-
- static QByteArray ianaIdToWindowsId(const QByteArray &ianaId);
- static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId);
- static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId,
- QLocale::Country country);
- static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId);
- static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId,
- QLocale::Country country);
-
-#if (defined(Q_OS_DARWIN) || defined(Q_QDOC)) && !defined(QT_NO_SYSTEMLOCALE)
- static QTimeZone fromCFTimeZone(CFTimeZoneRef timeZone);
- CFTimeZoneRef toCFTimeZone() const Q_DECL_CF_RETURNS_RETAINED;
- static QTimeZone fromNSTimeZone(const NSTimeZone *timeZone);
- NSTimeZone *toNSTimeZone() const Q_DECL_NS_RETURNS_AUTORELEASED;
-#endif
-
-private:
- QTimeZone(QTimeZonePrivate &dd);
-#ifndef QT_NO_DATASTREAM
- friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz);
-#endif
- friend class QTimeZonePrivate;
- friend class QDateTime;
- friend class QDateTimePrivate;
- QSharedDataPointer<QTimeZonePrivate> d;
-};
-
-Q_DECLARE_TYPEINFO(QTimeZone::OffsetData, Q_MOVABLE_TYPE);
-Q_DECLARE_SHARED(QTimeZone)
-
-#ifndef QT_NO_DATASTREAM
-Q_CORE_EXPORT QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz);
-Q_CORE_EXPORT QDataStream &operator>>(QDataStream &ds, QTimeZone &tz);
-#endif
-
-#ifndef QT_NO_DEBUG_STREAM
-Q_CORE_EXPORT QDebug operator<<(QDebug dbg, const QTimeZone &tz);
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QTIMEZONE_H
diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp
deleted file mode 100644
index 569b343187..0000000000
--- a/src/corelib/tools/qtimezoneprivate.cpp
+++ /dev/null
@@ -1,926 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 John Layt <jlayt@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qtimezone.h"
-#include "qtimezoneprivate_p.h"
-#include "qtimezoneprivate_data_p.h"
-
-#include <qdatastream.h>
-#include <qdebug.h>
-
-#include <algorithm>
-
-QT_BEGIN_NAMESPACE
-
-/*
- Static utilities for looking up Windows ID tables
-*/
-
-static const int windowsDataTableSize = sizeof(windowsDataTable) / sizeof(QWindowsData) - 1;
-static const int zoneDataTableSize = sizeof(zoneDataTable) / sizeof(QZoneData) - 1;
-static const int utcDataTableSize = sizeof(utcDataTable) / sizeof(QUtcData) - 1;
-
-
-static const QZoneData *zoneData(quint16 index)
-{
- Q_ASSERT(index < zoneDataTableSize);
- return &zoneDataTable[index];
-}
-
-static const QWindowsData *windowsData(quint16 index)
-{
- Q_ASSERT(index < windowsDataTableSize);
- return &windowsDataTable[index];
-}
-
-static const QUtcData *utcData(quint16 index)
-{
- Q_ASSERT(index < utcDataTableSize);
- return &utcDataTable[index];
-}
-
-// Return the Windows ID literal for a given QWindowsData
-static QByteArray windowsId(const QWindowsData *windowsData)
-{
- return (windowsIdData + windowsData->windowsIdIndex);
-}
-
-// Return the IANA ID literal for a given QWindowsData
-static QByteArray ianaId(const QWindowsData *windowsData)
-{
- return (ianaIdData + windowsData->ianaIdIndex);
-}
-
-// Return the IANA ID literal for a given QZoneData
-static QByteArray ianaId(const QZoneData *zoneData)
-{
- return (ianaIdData + zoneData->ianaIdIndex);
-}
-
-static QByteArray utcId(const QUtcData *utcData)
-{
- return (ianaIdData + utcData->ianaIdIndex);
-}
-
-static quint16 toWindowsIdKey(const QByteArray &winId)
-{
- for (quint16 i = 0; i < windowsDataTableSize; ++i) {
- const QWindowsData *data = windowsData(i);
- if (windowsId(data) == winId)
- return data->windowsIdKey;
- }
- return 0;
-}
-
-static QByteArray toWindowsIdLiteral(quint16 windowsIdKey)
-{
- for (quint16 i = 0; i < windowsDataTableSize; ++i) {
- const QWindowsData *data = windowsData(i);
- if (data->windowsIdKey == windowsIdKey)
- return windowsId(data);
- }
- return QByteArray();
-}
-
-/*
- Base class implementing common utility routines, only intantiate for a null tz.
-*/
-
-QTimeZonePrivate::QTimeZonePrivate()
-{
-}
-
-QTimeZonePrivate::QTimeZonePrivate(const QTimeZonePrivate &other)
- : QSharedData(other), m_id(other.m_id)
-{
-}
-
-QTimeZonePrivate::~QTimeZonePrivate()
-{
-}
-
-QTimeZonePrivate *QTimeZonePrivate::clone() const
-{
- return new QTimeZonePrivate(*this);
-}
-
-bool QTimeZonePrivate::operator==(const QTimeZonePrivate &other) const
-{
- // TODO Too simple, but need to solve problem of comparing different derived classes
- // Should work for all System and ICU classes as names guaranteed unique, but not for Simple.
- // Perhaps once all classes have working transitions can compare full list?
- return (m_id == other.m_id);
-}
-
-bool QTimeZonePrivate::operator!=(const QTimeZonePrivate &other) const
-{
- return !(*this == other);
-}
-
-bool QTimeZonePrivate::isValid() const
-{
- return !m_id.isEmpty();
-}
-
-QByteArray QTimeZonePrivate::id() const
-{
- return m_id;
-}
-
-QLocale::Country QTimeZonePrivate::country() const
-{
- // Default fall-back mode, use the zoneTable to find Region of known Zones
- for (int i = 0; i < zoneDataTableSize; ++i) {
- const QZoneData *data = zoneData(i);
- if (ianaId(data).split(' ').contains(m_id))
- return (QLocale::Country)data->country;
- }
- return QLocale::AnyCountry;
-}
-
-QString QTimeZonePrivate::comment() const
-{
- return QString();
-}
-
-QString QTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
- QTimeZone::NameType nameType,
- const QLocale &locale) const
-{
- if (nameType == QTimeZone::OffsetName)
- return isoOffsetFormat(offsetFromUtc(atMSecsSinceEpoch));
-
- if (isDaylightTime(atMSecsSinceEpoch))
- return displayName(QTimeZone::DaylightTime, nameType, locale);
- else
- return displayName(QTimeZone::StandardTime, nameType, locale);
-}
-
-QString QTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
- QTimeZone::NameType nameType,
- const QLocale &locale) const
-{
- Q_UNUSED(timeType)
- Q_UNUSED(nameType)
- Q_UNUSED(locale)
- return QString();
-}
-
-QString QTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch) const
-{
- Q_UNUSED(atMSecsSinceEpoch)
- return QString();
-}
-
-int QTimeZonePrivate::offsetFromUtc(qint64 atMSecsSinceEpoch) const
-{
- return standardTimeOffset(atMSecsSinceEpoch) + daylightTimeOffset(atMSecsSinceEpoch);
-}
-
-int QTimeZonePrivate::standardTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- Q_UNUSED(atMSecsSinceEpoch)
- return invalidSeconds();
-}
-
-int QTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- Q_UNUSED(atMSecsSinceEpoch)
- return invalidSeconds();
-}
-
-bool QTimeZonePrivate::hasDaylightTime() const
-{
- return false;
-}
-
-bool QTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
-{
- Q_UNUSED(atMSecsSinceEpoch)
- return false;
-}
-
-QTimeZonePrivate::Data QTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
-{
- Q_UNUSED(forMSecsSinceEpoch)
- return invalidData();
-}
-
-// Private only method for use by QDateTime to convert local msecs to epoch msecs
-QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs, int hint) const
-{
- if (!hasDaylightTime()) // No DST means same offset for all local msecs
- return data(forLocalMSecs - standardTimeOffset(forLocalMSecs) * 1000);
-
- /*
- We need a UTC time at which to ask for the offset, in order to be able to
- add that offset to forLocalMSecs, to get the UTC time we
- need. Fortunately, no time-zone offset is more than 14 hours; and DST
- transitions happen (much) more than thirty-two hours apart. So sampling
- offset sixteen hours each side gives us information we can be sure
- brackets the correct time and at most one DST transition.
- */
- const qint64 sixteenHoursInMSecs(16 * 3600 * 1000);
- Q_STATIC_ASSERT(-sixteenHoursInMSecs / 1000 < QTimeZone::MinUtcOffsetSecs
- && sixteenHoursInMSecs / 1000 > QTimeZone::MaxUtcOffsetSecs);
- const qint64 recent = forLocalMSecs - sixteenHoursInMSecs;
- const qint64 imminent = forLocalMSecs + sixteenHoursInMSecs;
- /*
- Offsets are Local - UTC, positive to the east of Greenwich, negative to
- the west; DST offset always exceeds standard offset, when DST applies.
- When we have offsets on either side of a transition, the lower one is
- standard, the higher is DST.
-
- Non-DST transitions (jurisdictions changing time-zone and time-zones
- changing their standard offset, typically) are described below as if they
- were DST transitions (since these are more usual and familiar); the code
- mostly concerns itself with offsets from UTC, described in terms of the
- common case for changes in that. If there is no actual change in offset
- (e.g. a DST transition cancelled by a standard offset change), this code
- should handle it gracefully; without transitions, it'll see early == late
- and take the easy path; with transitions, tran and nextTran get the
- correct UTC time as atMSecsSinceEpoch so comparing to nextStart selects
- the right one. In all other cases, the transition changes offset and the
- reasoning that applies to DST applies just the same. Aside from hinting,
- the only thing that looks at DST-ness at all, other than inferred from
- offset changes, is the case without transition data handling an invalid
- time in the gap that a transition passed over.
-
- The handling of hint (see below) is apt to go wrong in non-DST
- transitions. There isn't really a great deal we can hope to do about that
- without adding yet more unreliable complexity to the heuristics in use for
- already obscure corner-cases.
- */
-
- /*
- The hint (really a QDateTimePrivate::DaylightStatus) is > 0 if caller
- thinks we're in DST, 0 if in standard. A value of -2 means never-DST, so
- should have been handled above; if it slips through, it's wrong but we
- should probably treat it as standard anyway (never-DST means
- always-standard, after all). If the hint turns out to be wrong, fall back
- on trying the other possibility: which makes it harmless to treat -1
- (meaning unknown) as standard (i.e. try standard first, then try DST). In
- practice, away from a transition, the only difference hint makes is to
- which candidate we try first: if the hint is wrong (or unknown and
- standard fails), we'll try the other candidate and it'll work.
-
- For the obscure (and invalid) case where forLocalMSecs falls in a
- spring-forward's missing hour, a common case is that we started with a
- date/time for which the hint was valid and adjusted it naively; for that
- case, we should correct the adjustment by shunting across the transition
- into where hint is wrong. So half-way through the gap, arrived at from
- the DST side, should be read as an hour earlier, in standard time; but, if
- arrived at from the standard side, should be read as an hour later, in
- DST. (This shall be wrong in some cases; for example, when a country
- changes its transition dates and changing a date/time by more than six
- months lands it on a transition. However, these cases are even more
- obscure than those where the heuristic is good.)
- */
-
- if (hasTransitions()) {
- /*
- We have transitions.
-
- Each transition gives the offsets to use until the next; so we need the
- most recent transition before the time forLocalMSecs describes. If it
- describes a time *in* a transition, we'll need both that transition and
- the one before it. So find one transition that's probably after (and not
- much before, otherwise) and another that's definitely before, then work
- out which one to use. When both or neither work on forLocalMSecs, use
- hint to disambiguate.
- */
-
- // Get a transition definitely before the local MSecs; usually all we need.
- // Only around the transition times might we need another.
- Data tran = previousTransition(recent);
- Q_ASSERT(forLocalMSecs < 0 || // Pre-epoch TZ info may be unavailable
- forLocalMSecs - tran.offsetFromUtc * 1000 >= tran.atMSecsSinceEpoch);
- Data nextTran = nextTransition(tran.atMSecsSinceEpoch);
- /*
- Now walk those forward until they bracket forLocalMSecs with transitions.
-
- One of the transitions should then be telling us the right offset to use.
- In a transition, we need the transition before it (to describe the run-up
- to the transition) and the transition itself; so we need to stop when
- nextTran is that transition.
- */
- while (nextTran.atMSecsSinceEpoch != invalidMSecs()
- && forLocalMSecs > nextTran.atMSecsSinceEpoch + nextTran.offsetFromUtc * 1000) {
- Data newTran = nextTransition(nextTran.atMSecsSinceEpoch);
- if (newTran.atMSecsSinceEpoch == invalidMSecs()
- || newTran.atMSecsSinceEpoch + newTran.offsetFromUtc * 1000 > imminent) {
- // Definitely not a relevant tansition: too far in the future.
- break;
- }
- tran = nextTran;
- nextTran = newTran;
- }
-
- // Check we do *really* have transitions for this zone:
- if (tran.atMSecsSinceEpoch != invalidMSecs()) {
-
- /*
- So now tran is definitely before and nextTran is either after or only
- slightly before. One is standard time; we interpret the other as DST
- (although the transition might in fact by a change in standard offset). Our
- hint tells us which of those to use (defaulting to standard if no hint): try
- it first; if that fails, try the other; if both fail, life's tricky.
- */
- Q_ASSERT(forLocalMSecs < 0
- || forLocalMSecs - tran.offsetFromUtc * 1000 > tran.atMSecsSinceEpoch);
- const qint64 nextStart = nextTran.atMSecsSinceEpoch;
- // Work out the UTC values it might make sense to return:
- nextTran.atMSecsSinceEpoch = forLocalMSecs - nextTran.offsetFromUtc * 1000;
- tran.atMSecsSinceEpoch = forLocalMSecs - tran.offsetFromUtc * 1000;
-
- // If both or neither have zero DST, treat the one with lower offset as standard:
- const bool nextIsDst = !nextTran.daylightTimeOffset == !tran.daylightTimeOffset
- ? tran.offsetFromUtc < nextTran.offsetFromUtc : nextTran.daylightTimeOffset;
- // If that agrees with hint > 0, our first guess is to use nextTran; else tran.
- const bool nextFirst = nextIsDst == (hint > 0) && nextStart != invalidMSecs();
- for (int i = 0; i < 2; i++) {
- /*
- On the first pass, the case we consider is what hint told us to expect
- (except when hint was -1 and didn't actually tell us what to expect),
- so it's likely right. We only get a second pass if the first failed,
- by which time the second case, that we're trying, is likely right. If
- an overwhelming majority of calls have hint == -1, the Q_LIKELY here
- shall be wrong half the time; otherwise, its errors shall be rarer
- than that.
- */
- if (nextFirst ? i == 0 : i) {
- Q_ASSERT(nextStart != invalidMSecs());
- if (Q_LIKELY(nextStart <= nextTran.atMSecsSinceEpoch))
- return nextTran;
- } else {
- // If next is invalid, nextFirst is false, to route us here first:
- if (nextStart == invalidMSecs() || Q_LIKELY(nextStart > tran.atMSecsSinceEpoch))
- return tran;
- }
- }
-
- /*
- Neither is valid (e.g. in a spring-forward's gap) and
- nextTran.atMSecsSinceEpoch < nextStart <= tran.atMSecsSinceEpoch, so
- 0 < tran.atMSecsSinceEpoch - nextTran.atMSecsSinceEpoch
- = (nextTran.offsetFromUtc - tran.offsetFromUtc) * 1000
- */
- int dstStep = (nextTran.offsetFromUtc - tran.offsetFromUtc) * 1000;
- Q_ASSERT(dstStep > 0); // How else could we get here ?
- if (nextFirst) { // hint thought we needed nextTran, so use tran
- tran.atMSecsSinceEpoch -= dstStep;
- return tran;
- }
- nextTran.atMSecsSinceEpoch += dstStep;
- return nextTran;
- }
- // System has transitions but not for this zone.
- // Try falling back to offsetFromUtc
- }
-
- /* Bracket and refine to discover offset. */
- qint64 utcEpochMSecs;
-
- int early = offsetFromUtc(recent);
- int late = offsetFromUtc(imminent);
- if (Q_LIKELY(early == late)) { // > 99% of the time
- utcEpochMSecs = forLocalMSecs - early * 1000;
- } else {
- // Close to a DST transition: early > late is near a fall-back,
- // early < late is near a spring-forward.
- const int offsetInDst = qMax(early, late);
- const int offsetInStd = qMin(early, late);
- // Candidate values for utcEpochMSecs (if forLocalMSecs is valid):
- const qint64 forDst = forLocalMSecs - offsetInDst * 1000;
- const qint64 forStd = forLocalMSecs - offsetInStd * 1000;
- // Best guess at the answer:
- const qint64 hinted = hint > 0 ? forDst : forStd;
- if (Q_LIKELY(offsetFromUtc(hinted) == (hint > 0 ? offsetInDst : offsetInStd))) {
- utcEpochMSecs = hinted;
- } else if (hint <= 0 && offsetFromUtc(forDst) == offsetInDst) {
- utcEpochMSecs = forDst;
- } else if (hint > 0 && offsetFromUtc(forStd) == offsetInStd) {
- utcEpochMSecs = forStd;
- } else {
- // Invalid forLocalMSecs: in spring-forward gap.
- const int dstStep = daylightTimeOffset(early < late ? imminent : recent) * 1000;
- Q_ASSERT(dstStep); // There can't be a transition without it !
- utcEpochMSecs = (hint > 0) ? forStd - dstStep : forDst + dstStep;
- }
- }
-
- return data(utcEpochMSecs);
-}
-
-bool QTimeZonePrivate::hasTransitions() const
-{
- return false;
-}
-
-QTimeZonePrivate::Data QTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const
-{
- Q_UNUSED(afterMSecsSinceEpoch)
- return invalidData();
-}
-
-QTimeZonePrivate::Data QTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
-{
- Q_UNUSED(beforeMSecsSinceEpoch)
- return invalidData();
-}
-
-QTimeZonePrivate::DataList QTimeZonePrivate::transitions(qint64 fromMSecsSinceEpoch,
- qint64 toMSecsSinceEpoch) const
-{
- DataList list;
- if (toMSecsSinceEpoch >= fromMSecsSinceEpoch) {
- // fromMSecsSinceEpoch is inclusive but nextTransitionTime() is exclusive so go back 1 msec
- Data next = nextTransition(fromMSecsSinceEpoch - 1);
- while (next.atMSecsSinceEpoch != invalidMSecs()
- && next.atMSecsSinceEpoch <= toMSecsSinceEpoch) {
- list.append(next);
- next = nextTransition(next.atMSecsSinceEpoch);
- }
- }
- return list;
-}
-
-QByteArray QTimeZonePrivate::systemTimeZoneId() const
-{
- return QByteArray();
-}
-
-bool QTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray& ianaId) const
-{
- // Fall-back implementation, can be made faster in subclasses
- const QList<QByteArray> tzIds = availableTimeZoneIds();
- return std::binary_search(tzIds.begin(), tzIds.end(), ianaId);
-}
-
-QList<QByteArray> QTimeZonePrivate::availableTimeZoneIds() const
-{
- return QList<QByteArray>();
-}
-
-QList<QByteArray> QTimeZonePrivate::availableTimeZoneIds(QLocale::Country country) const
-{
- // Default fall-back mode, use the zoneTable to find Region of know Zones
- QList<QByteArray> regions;
-
- // First get all Zones in the Zones table belonging to the Region
- for (int i = 0; i < zoneDataTableSize; ++i) {
- if (zoneData(i)->country == country)
- regions += ianaId(zoneData(i)).split(' ');
- }
-
- std::sort(regions.begin(), regions.end());
- regions.erase(std::unique(regions.begin(), regions.end()), regions.end());
-
- // Then select just those that are available
- const QList<QByteArray> all = availableTimeZoneIds();
- QList<QByteArray> result;
- result.reserve(qMin(all.size(), regions.size()));
- std::set_intersection(all.begin(), all.end(), regions.cbegin(), regions.cend(),
- std::back_inserter(result));
- return result;
-}
-
-QList<QByteArray> QTimeZonePrivate::availableTimeZoneIds(int offsetFromUtc) const
-{
- // Default fall-back mode, use the zoneTable to find Offset of know Zones
- QList<QByteArray> offsets;
- // First get all Zones in the table using the Offset
- for (int i = 0; i < windowsDataTableSize; ++i) {
- const QWindowsData *winData = windowsData(i);
- if (winData->offsetFromUtc == offsetFromUtc) {
- for (int j = 0; j < zoneDataTableSize; ++j) {
- const QZoneData *data = zoneData(j);
- if (data->windowsIdKey == winData->windowsIdKey)
- offsets += ianaId(data).split(' ');
- }
- }
- }
-
- std::sort(offsets.begin(), offsets.end());
- offsets.erase(std::unique(offsets.begin(), offsets.end()), offsets.end());
-
- // Then select just those that are available
- const QList<QByteArray> all = availableTimeZoneIds();
- QList<QByteArray> result;
- result.reserve(qMin(all.size(), offsets.size()));
- std::set_intersection(all.begin(), all.end(), offsets.cbegin(), offsets.cend(),
- std::back_inserter(result));
- return result;
-}
-
-#ifndef QT_NO_DATASTREAM
-void QTimeZonePrivate::serialize(QDataStream &ds) const
-{
- ds << QString::fromUtf8(m_id);
-}
-#endif // QT_NO_DATASTREAM
-
-// Static Utility Methods
-
-QTimeZonePrivate::Data QTimeZonePrivate::invalidData()
-{
- Data data;
- data.atMSecsSinceEpoch = invalidMSecs();
- data.offsetFromUtc = invalidSeconds();
- data.standardTimeOffset = invalidSeconds();
- data.daylightTimeOffset = invalidSeconds();
- return data;
-}
-
-QTimeZone::OffsetData QTimeZonePrivate::invalidOffsetData()
-{
- QTimeZone::OffsetData offsetData;
- offsetData.atUtc = QDateTime();
- offsetData.offsetFromUtc = invalidSeconds();
- offsetData.standardTimeOffset = invalidSeconds();
- offsetData.daylightTimeOffset = invalidSeconds();
- return offsetData;
-}
-
-QTimeZone::OffsetData QTimeZonePrivate::toOffsetData(const QTimeZonePrivate::Data &data)
-{
- QTimeZone::OffsetData offsetData = invalidOffsetData();
- if (data.atMSecsSinceEpoch != invalidMSecs()) {
- offsetData.atUtc = QDateTime::fromMSecsSinceEpoch(data.atMSecsSinceEpoch, Qt::UTC);
- offsetData.offsetFromUtc = data.offsetFromUtc;
- offsetData.standardTimeOffset = data.standardTimeOffset;
- offsetData.daylightTimeOffset = data.daylightTimeOffset;
- offsetData.abbreviation = data.abbreviation;
- }
- return offsetData;
-}
-
-// Is the format of the ID valid ?
-bool QTimeZonePrivate::isValidId(const QByteArray &ianaId)
-{
- /*
- Main rules for defining TZ/IANA names as per ftp://ftp.iana.org/tz/code/Theory
- 1. Use only valid POSIX file name components
- 2. Within a file name component, use only ASCII letters, `.', `-' and `_'.
- 3. Do not use digits (except in a [+-]\d+ suffix, when used).
- 4. A file name component must not exceed 14 characters or start with `-'
- However, the rules are really guidelines - a later one says
- - Do not change established names if they only marginally violate the
- above rules.
- We may, therefore, need to be a bit slack in our check here, if we hit
- legitimate exceptions in real time-zone databases.
-
- In particular, aliases such as "Etc/GMT+7" and "SystemV/EST5EDT" are valid
- so we need to accept digits, ':', and '+'; aliases typically have the form
- of POSIX TZ strings, which allow a suffix to a proper IANA name. A POSIX
- suffix starts with an offset (as in GMT+7) and may continue with another
- name (as in EST5EDT, giving the DST name of the zone); a further offset is
- allowed (for DST). The ("hard to describe and [...] error-prone in
- practice") POSIX form even allows a suffix giving the dates (and
- optionally times) of the annual DST transitions. Hopefully, no TZ aliases
- go that far, but we at least need to accept an offset and (single
- fragment) DST-name.
-
- But for the legacy complications, the following would be preferable if
- QRegExp would work on QByteArrays directly:
- const QRegExp rx(QStringLiteral("[a-z+._][a-z+._-]{,13}"
- "(?:/[a-z+._][a-z+._-]{,13})*"
- // Optional suffix:
- "(?:[+-]?\d{1,2}(?::\d{1,2}){,2}" // offset
- // one name fragment (DST):
- "(?:[a-z+._][a-z+._-]{,13})?)"),
- Qt::CaseInsensitive);
- return rx.exactMatch(ianaId);
- */
-
- // Somewhat slack hand-rolled version:
- const int MinSectionLength = 1;
- const int MaxSectionLength = 14;
- int sectionLength = 0;
- for (const char *it = ianaId.begin(), * const end = ianaId.end(); it != end; ++it, ++sectionLength) {
- const char ch = *it;
- if (ch == '/') {
- if (sectionLength < MinSectionLength || sectionLength > MaxSectionLength)
- return false; // violates (4)
- sectionLength = -1;
- } else if (ch == '-') {
- if (sectionLength == 0)
- return false; // violates (4)
- } else if (!(ch >= 'a' && ch <= 'z')
- && !(ch >= 'A' && ch <= 'Z')
- && !(ch == '_')
- && !(ch == '.')
- // Should ideally check these only happen as an offset:
- && !(ch >= '0' && ch <= '9')
- && !(ch == '+')
- && !(ch == ':')) {
- return false; // violates (2)
- }
- }
- if (sectionLength < MinSectionLength || sectionLength > MaxSectionLength)
- return false; // violates (4)
- return true;
-}
-
-QString QTimeZonePrivate::isoOffsetFormat(int offsetFromUtc)
-{
- const int mins = offsetFromUtc / 60;
- return QString::fromUtf8("UTC%1%2:%3").arg(mins >= 0 ? QLatin1Char('+') : QLatin1Char('-'))
- .arg(qAbs(mins) / 60, 2, 10, QLatin1Char('0'))
- .arg(qAbs(mins) % 60, 2, 10, QLatin1Char('0'));
-}
-
-QByteArray QTimeZonePrivate::ianaIdToWindowsId(const QByteArray &id)
-{
- for (int i = 0; i < zoneDataTableSize; ++i) {
- const QZoneData *data = zoneData(i);
- if (ianaId(data).split(' ').contains(id))
- return toWindowsIdLiteral(data->windowsIdKey);
- }
- return QByteArray();
-}
-
-QByteArray QTimeZonePrivate::windowsIdToDefaultIanaId(const QByteArray &windowsId)
-{
- const quint16 windowsIdKey = toWindowsIdKey(windowsId);
- for (int i = 0; i < windowsDataTableSize; ++i) {
- const QWindowsData *data = windowsData(i);
- if (data->windowsIdKey == windowsIdKey)
- return ianaId(data);
- }
- return QByteArray();
-}
-
-QByteArray QTimeZonePrivate::windowsIdToDefaultIanaId(const QByteArray &windowsId,
- QLocale::Country country)
-{
- const QList<QByteArray> list = windowsIdToIanaIds(windowsId, country);
- if (list.count() > 0)
- return list.first();
- else
- return QByteArray();
-}
-
-QList<QByteArray> QTimeZonePrivate::windowsIdToIanaIds(const QByteArray &windowsId)
-{
- const quint16 windowsIdKey = toWindowsIdKey(windowsId);
- QList<QByteArray> list;
-
- for (int i = 0; i < zoneDataTableSize; ++i) {
- const QZoneData *data = zoneData(i);
- if (data->windowsIdKey == windowsIdKey)
- list << ianaId(data).split(' ');
- }
-
- // Return the full list in alpha order
- std::sort(list.begin(), list.end());
- return list;
-}
-
-QList<QByteArray> QTimeZonePrivate::windowsIdToIanaIds(const QByteArray &windowsId,
- QLocale::Country country)
-{
- const quint16 windowsIdKey = toWindowsIdKey(windowsId);
- for (int i = 0; i < zoneDataTableSize; ++i) {
- const QZoneData *data = zoneData(i);
- // Return the region matches in preference order
- if (data->windowsIdKey == windowsIdKey && data->country == (quint16) country)
- return ianaId(data).split(' ');
- }
-
- return QList<QByteArray>();
-}
-
-// Define template for derived classes to reimplement so QSharedDataPointer clone() works correctly
-template<> QTimeZonePrivate *QSharedDataPointer<QTimeZonePrivate>::clone()
-{
- return d->clone();
-}
-
-/*
- UTC Offset implementation, used when QT_NO_SYSTEMLOCALE set and ICU is not being used,
- or for QDateTimes with a Qt:Spec of Qt::OffsetFromUtc.
-*/
-
-// Create default UTC time zone
-QUtcTimeZonePrivate::QUtcTimeZonePrivate()
-{
- const QString name = utcQString();
- init(utcQByteArray(), 0, name, name, QLocale::AnyCountry, name);
-}
-
-// Create a named UTC time zone
-QUtcTimeZonePrivate::QUtcTimeZonePrivate(const QByteArray &id)
-{
- // Look for the name in the UTC list, if found set the values
- for (int i = 0; i < utcDataTableSize; ++i) {
- const QUtcData *data = utcData(i);
- const QByteArray uid = utcId(data);
- if (uid == id) {
- QString name = QString::fromUtf8(id);
- init(id, data->offsetFromUtc, name, name, QLocale::AnyCountry, name);
- break;
- }
- }
-}
-
-// Create offset from UTC
-QUtcTimeZonePrivate::QUtcTimeZonePrivate(qint32 offsetSeconds)
-{
- QString utcId;
-
- if (offsetSeconds == 0)
- utcId = utcQString();
- else
- utcId = isoOffsetFormat(offsetSeconds);
-
- init(utcId.toUtf8(), offsetSeconds, utcId, utcId, QLocale::AnyCountry, utcId);
-}
-
-QUtcTimeZonePrivate::QUtcTimeZonePrivate(const QByteArray &zoneId, int offsetSeconds,
- const QString &name, const QString &abbreviation,
- QLocale::Country country, const QString &comment)
-{
- init(zoneId, offsetSeconds, name, abbreviation, country, comment);
-}
-
-QUtcTimeZonePrivate::QUtcTimeZonePrivate(const QUtcTimeZonePrivate &other)
- : QTimeZonePrivate(other), m_name(other.m_name),
- m_abbreviation(other.m_abbreviation),
- m_comment(other.m_comment),
- m_country(other.m_country),
- m_offsetFromUtc(other.m_offsetFromUtc)
-{
-}
-
-QUtcTimeZonePrivate::~QUtcTimeZonePrivate()
-{
-}
-
-QUtcTimeZonePrivate *QUtcTimeZonePrivate::clone() const
-{
- return new QUtcTimeZonePrivate(*this);
-}
-
-QTimeZonePrivate::Data QUtcTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
-{
- Data d;
- d.abbreviation = m_abbreviation;
- d.atMSecsSinceEpoch = forMSecsSinceEpoch;
- d.standardTimeOffset = d.offsetFromUtc = m_offsetFromUtc;
- d.daylightTimeOffset = 0;
- return d;
-}
-
-void QUtcTimeZonePrivate::init(const QByteArray &zoneId)
-{
- m_id = zoneId;
-}
-
-void QUtcTimeZonePrivate::init(const QByteArray &zoneId, int offsetSeconds, const QString &name,
- const QString &abbreviation, QLocale::Country country,
- const QString &comment)
-{
- m_id = zoneId;
- m_offsetFromUtc = offsetSeconds;
- m_name = name;
- m_abbreviation = abbreviation;
- m_country = country;
- m_comment = comment;
-}
-
-QLocale::Country QUtcTimeZonePrivate::country() const
-{
- return m_country;
-}
-
-QString QUtcTimeZonePrivate::comment() const
-{
- return m_comment;
-}
-
-QString QUtcTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
- QTimeZone::NameType nameType,
- const QLocale &locale) const
-{
- Q_UNUSED(timeType)
- Q_UNUSED(locale)
- if (nameType == QTimeZone::ShortName)
- return m_abbreviation;
- else if (nameType == QTimeZone::OffsetName)
- return isoOffsetFormat(m_offsetFromUtc);
- return m_name;
-}
-
-QString QUtcTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch) const
-{
- Q_UNUSED(atMSecsSinceEpoch)
- return m_abbreviation;
-}
-
-qint32 QUtcTimeZonePrivate::standardTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- Q_UNUSED(atMSecsSinceEpoch)
- return m_offsetFromUtc;
-}
-
-qint32 QUtcTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- Q_UNUSED(atMSecsSinceEpoch)
- return 0;
-}
-
-QByteArray QUtcTimeZonePrivate::systemTimeZoneId() const
-{
- return utcQByteArray();
-}
-
-bool QUtcTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
-{
- for (int i = 0; i < utcDataTableSize; ++i) {
- const QUtcData *data = utcData(i);
- if (utcId(data) == ianaId) {
- return true;
- }
- }
- return false;
-}
-
-QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds() const
-{
- QList<QByteArray> result;
- result.reserve(utcDataTableSize);
- for (int i = 0; i < utcDataTableSize; ++i)
- result << utcId(utcData(i));
- std::sort(result.begin(), result.end()); // ### or already sorted??
- // ### assuming no duplicates
- return result;
-}
-
-QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds(QLocale::Country country) const
-{
- // If AnyCountry then is request for all non-region offset codes
- if (country == QLocale::AnyCountry)
- return availableTimeZoneIds();
- return QList<QByteArray>();
-}
-
-QList<QByteArray> QUtcTimeZonePrivate::availableTimeZoneIds(qint32 offsetSeconds) const
-{
- QList<QByteArray> result;
- for (int i = 0; i < utcDataTableSize; ++i) {
- const QUtcData *data = utcData(i);
- if (data->offsetFromUtc == offsetSeconds)
- result << utcId(data);
- }
- std::sort(result.begin(), result.end()); // ### or already sorted??
- // ### assuming no duplicates
- return result;
-}
-
-#ifndef QT_NO_DATASTREAM
-void QUtcTimeZonePrivate::serialize(QDataStream &ds) const
-{
- ds << QStringLiteral("OffsetFromUtc") << QString::fromUtf8(m_id) << m_offsetFromUtc << m_name
- << m_abbreviation << (qint32) m_country << m_comment;
-}
-#endif // QT_NO_DATASTREAM
-
-QT_END_NAMESPACE
diff --git a/src/corelib/tools/qtimezoneprivate_android.cpp b/src/corelib/tools/qtimezoneprivate_android.cpp
deleted file mode 100644
index be4f374fdd..0000000000
--- a/src/corelib/tools/qtimezoneprivate_android.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Drew Parsons <dparsons@emerall.com>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/QSet>
-#include "qtimezone.h"
-#include "qtimezoneprivate_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*
- Private
-
- Android implementation
-*/
-
-// Create the system default time zone
-QAndroidTimeZonePrivate::QAndroidTimeZonePrivate()
- : QTimeZonePrivate()
-{
- // start with system time zone
- androidTimeZone = QJNIObjectPrivate::callStaticObjectMethod("java.util.TimeZone", "getDefault", "()Ljava/util/TimeZone;");
- init("UTC");
-}
-
-// Create a named time zone
-QAndroidTimeZonePrivate::QAndroidTimeZonePrivate(const QByteArray &ianaId)
- : QTimeZonePrivate()
-{
- init(ianaId);
-}
-
-QAndroidTimeZonePrivate::QAndroidTimeZonePrivate(const QAndroidTimeZonePrivate &other)
- : QTimeZonePrivate(other)
-{
- androidTimeZone = other.androidTimeZone;
- m_id = other.id();
-}
-
-QAndroidTimeZonePrivate::~QAndroidTimeZonePrivate()
-{
-}
-
-
-void QAndroidTimeZonePrivate::init(const QByteArray &ianaId)
-{
- QJNIObjectPrivate jo_ianaId = QJNIObjectPrivate::fromString( QString::fromUtf8(ianaId) );
- androidTimeZone = QJNIObjectPrivate::callStaticObjectMethod( "java.util.TimeZone", "getTimeZone", "(Ljava/lang/String;)Ljava/util/TimeZone;", static_cast<jstring>(jo_ianaId.object()) );
-
- // Painfully, JNI gives us back a default zone object if it doesn't
- // recognize the name; so check for whether ianaId is a recognized name of
- // the zone object we got and ignore the zone if not.
- // Try checking ianaId against getID(), getDisplayName():
- QJNIObjectPrivate jname = androidTimeZone.callObjectMethod("getID", "()Ljava/lang/String;");
- bool found = (jname.toString().toUtf8() == ianaId);
- for (int style = 1; !found && style-- > 0;) {
- for (int dst = 1; !found && dst-- > 0;) {
- jname = androidTimeZone.callObjectMethod("getDisplayName", "(ZI;)Ljava/lang/String;",
- bool(dst), style);
- found = (jname.toString().toUtf8() == ianaId);
- }
- }
-
- if (!found)
- m_id.clear();
- else if (ianaId.isEmpty())
- m_id = systemTimeZoneId();
- else
- m_id = ianaId;
-}
-
-QAndroidTimeZonePrivate *QAndroidTimeZonePrivate::clone() const
-{
- return new QAndroidTimeZonePrivate(*this);
-}
-
-
-QString QAndroidTimeZonePrivate::displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType,
- const QLocale &locale) const
-{
- QString name;
-
- if (androidTimeZone.isValid()) {
- jboolean daylightTime = (timeType == QTimeZone::DaylightTime); // treat QTimeZone::GenericTime as QTimeZone::StandardTime
-
- // treat all NameTypes as java TimeZone style LONG (value 1), except of course QTimeZone::ShortName which is style SHORT (value 0);
- jint style = (nameType == QTimeZone::ShortName ? 0 : 1);
-
- QJNIObjectPrivate jlanguage = QJNIObjectPrivate::fromString(QLocale::languageToString(locale.language()));
- QJNIObjectPrivate jcountry = QJNIObjectPrivate::fromString(QLocale::countryToString(locale.country()));
- QJNIObjectPrivate jvariant = QJNIObjectPrivate::fromString(QLocale::scriptToString(locale.script()));
- QJNIObjectPrivate jlocale("java.util.Locale", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", static_cast<jstring>(jlanguage.object()), static_cast<jstring>(jcountry.object()), static_cast<jstring>(jvariant.object()));
-
- QJNIObjectPrivate jname = androidTimeZone.callObjectMethod("getDisplayName", "(ZILjava/util/Locale;)Ljava/lang/String;", daylightTime, style, jlocale.object());
-
- name = jname.toString();
- }
-
- return name;
-}
-
-QString QAndroidTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch) const
-{
- if ( isDaylightTime( atMSecsSinceEpoch ) )
- return displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, QLocale() );
- else
- return displayName(QTimeZone::StandardTime, QTimeZone::ShortName, QLocale() );
-}
-
-int QAndroidTimeZonePrivate::offsetFromUtc(qint64 atMSecsSinceEpoch) const
-{
- // offsetFromUtc( ) is invoked when androidTimeZone may not yet be set at startup,
- // so a validity test is needed here
- if ( androidTimeZone.isValid() )
- // the java method getOffset() returns milliseconds, but QTimeZone returns seconds
- return androidTimeZone.callMethod<jint>( "getOffset", "(J)I", static_cast<jlong>(atMSecsSinceEpoch) ) / 1000;
- else
- return 0;
-}
-
-int QAndroidTimeZonePrivate::standardTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- // the java method does not use a reference time
- Q_UNUSED( atMSecsSinceEpoch );
- if ( androidTimeZone.isValid() )
- // the java method getRawOffset() returns milliseconds, but QTimeZone returns seconds
- return androidTimeZone.callMethod<jint>( "getRawOffset" ) / 1000;
- else
- return 0;
-}
-
-int QAndroidTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- return ( offsetFromUtc(atMSecsSinceEpoch) - standardTimeOffset(atMSecsSinceEpoch) );
-}
-
-bool QAndroidTimeZonePrivate::hasDaylightTime() const
-{
- if ( androidTimeZone.isValid() )
- /* note: the Java function only tests for future DST transtions, not past */
- return androidTimeZone.callMethod<jboolean>("useDaylightTime" );
- else
- return false;
-}
-
-bool QAndroidTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
-{
- if ( androidTimeZone.isValid() ) {
- QJNIObjectPrivate jDate( "java/util/Date", "(J)V", static_cast<jlong>(atMSecsSinceEpoch) );
- return androidTimeZone.callMethod<jboolean>("inDaylightTime", "(Ljava/util/Date;)Z", jDate.object() );
- }
- else
- return false;
-}
-
-QTimeZonePrivate::Data QAndroidTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
-{
- if (androidTimeZone.isValid()) {
- Data data;
- data.atMSecsSinceEpoch = forMSecsSinceEpoch;
- data.standardTimeOffset = standardTimeOffset(forMSecsSinceEpoch);
- data.offsetFromUtc = offsetFromUtc(forMSecsSinceEpoch);
- data.daylightTimeOffset = data.offsetFromUtc - data.standardTimeOffset;
- data.abbreviation = abbreviation(forMSecsSinceEpoch);
- return data;
- } else {
- return invalidData();
- }
-}
-
-bool QAndroidTimeZonePrivate::hasTransitions() const
-{
- // java.util.TimeZone does not directly provide transitions
- return false;
-}
-
-QTimeZonePrivate::Data QAndroidTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const
-{
- // transitions not available on Android, so return an invalid data object
- Q_UNUSED( afterMSecsSinceEpoch );
- return invalidData();
-}
-
-QTimeZonePrivate::Data QAndroidTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
-{
- // transitions not available on Android, so return an invalid data object
- Q_UNUSED( beforeMSecsSinceEpoch );
- return invalidData();
-}
-
-QByteArray QAndroidTimeZonePrivate::systemTimeZoneId() const
-{
- QJNIObjectPrivate androidSystemTimeZone = QJNIObjectPrivate::callStaticObjectMethod("java.util.TimeZone", "getDefault", "()Ljava/util/TimeZone;");
- QJNIObjectPrivate systemTZIdAndroid = androidSystemTimeZone.callObjectMethod<jstring>("getID");
- QByteArray systemTZid = systemTZIdAndroid.toString().toUtf8();
-
- return systemTZid;
-}
-
-QList<QByteArray> QAndroidTimeZonePrivate::availableTimeZoneIds() const
-{
- QList<QByteArray> availableTimeZoneIdList;
- QJNIObjectPrivate androidAvailableIdList = QJNIObjectPrivate::callStaticObjectMethod("java.util.TimeZone", "getAvailableIDs", "()[Ljava/lang/String;");
-
- QJNIEnvironmentPrivate jniEnv;
- int androidTZcount = jniEnv->GetArrayLength( static_cast<jarray>(androidAvailableIdList.object()) );
-
- // need separate jobject and QAndroidJniObject here so that we can delete (DeleteLocalRef) the reference to the jobject
- // (or else the JNI reference table fills after 512 entries from GetObjectArrayElement)
- jobject androidTZobject;
- QJNIObjectPrivate androidTZ;
- for (int i=0; i<androidTZcount; i++ ) {
- androidTZobject = jniEnv->GetObjectArrayElement( static_cast<jobjectArray>( androidAvailableIdList.object() ), i );
- androidTZ = androidTZobject;
- availableTimeZoneIdList.append( androidTZ.toString().toUtf8() );
- jniEnv->DeleteLocalRef(androidTZobject);
- }
-
- return availableTimeZoneIdList;
-}
-
-QT_END_NAMESPACE
diff --git a/src/corelib/tools/qtimezoneprivate_data_p.h b/src/corelib/tools/qtimezoneprivate_data_p.h
deleted file mode 100644
index 40d6c972c2..0000000000
--- a/src/corelib/tools/qtimezoneprivate_data_p.h
+++ /dev/null
@@ -1,1257 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 John Layt <jlayt@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QTIMEZONEPRIVATE_DATA_P_H
-#define QTIMEZONEPRIVATE_DATA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of internal files. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/private/qglobal_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/*
- Windows Zone ID support, included in default base class build so can be used on all platforms,
- e.g. an app running on Linux may need to communicate with a Windows Outlook server. These
- tables can also be used to look-up Region Codes and UTC Offsets on platforms that don't directly
- support them., e.g. Mac does not support availableTimeZones() filtering by region or offset.
-
- Another data table is provided for generic UTC+00:00 format time zones to be used as a
- fall-back if no system time zones are available (QT_NO_SYSTEMLOCALE is set) or for QDateTimes
- with a QT:Spec of OffsetFromUTC
-
- These tables are automatically adapted from the CLDR supplemental/windowsZones.xml data file
- using a script in qtbase/util/locale_database. Please do not edit this data directly. In the
- future if ICU is made a hard dependency then the ICU resource can be used directly and this
- table removed
-*/
-
-struct QZoneData {
- quint16 windowsIdKey; // Windows ID Key
- quint16 country; // Country of IANA ID's, AnyCountry means No Country
- quint16 ianaIdIndex; // All IANA ID's for the Windows ID and Country, space separated
-};
-
-struct QWindowsData {
- quint16 windowsIdKey; // Windows ID Key
- quint16 windowsIdIndex; // Windows ID Literal
- quint16 ianaIdIndex; // Default IANA ID for the Windows ID
- qint32 offsetFromUtc; // Standard Time Offset from UTC, used for quick look-ups
-};
-
-struct QUtcData {
- quint16 ianaIdIndex; // IANA ID's
- qint32 offsetFromUtc; // Offset form UTC is seconds
-};
-
-/*
- COPYRIGHT AND PERMISSION NOTICE
-
- Copyright © 1991-2012 Unicode, Inc. All rights reserved. Distributed under
- the Terms of Use in http://www.unicode.org/copyright.html.
-
- Permission is hereby granted, free of charge, to any person obtaining a
- copy of the Unicode data files and any associated documentation (the "Data
- Files") or Unicode software and any associated documentation (the "Software")
- to deal in the Data Files or Software without restriction, including without
- limitation the rights to use, copy, modify, merge, publish, distribute, and/or
- sell copies of the Data Files or Software, and to permit persons to whom the
- Data Files or Software are furnished to do so, provided that (a) the above
- copyright notice(s) and this permission notice appear with all copies of the
- Data Files or Software, (b) both the above copyright notice(s) and this
- permission notice appear in associated documentation, and (c) there is clear
- notice in each modified Data File or in the Software as well as in the
- documentation associated with the Data File(s) or Software that the data or
- software has been modified.
-*/
-
-// GENERATED PART STARTS HERE
-
-/*
- This part of the file was generated on 2019-05-28 from the
- Common Locale Data Repository v35.1 supplemental/windowsZones.xml file $Revision: 14742 $
-
- http://www.unicode.org/cldr/
-
- Do not edit this code: run cldr2qtimezone.py on updated (or
- edited) CLDR data; see qtbase/util/locale_database/.
-*/
-
-// Windows ID Key, Country Enum, IANA ID Index
-static const QZoneData zoneDataTable[] = {
- { 131, 143, 0 }, // W. Mongolia Standard Time / Mongolia
- { 124, 112, 10 }, // UTC+12 / Kiribati
- { 52, 94, 25 }, // Haiti Standard Time / Haiti
- { 32, 44, 48 }, // China Standard Time / China
- { 95, 244, 62 }, // SA Western Standard Time / Saint Barthelemy
- { 25, 116, 84 }, // Central Asia Standard Time / Kyrgyzstan
- { 36, 8, 97 }, // E. Africa Standard Time / Antarctica
- { 33, 154, 114 }, // Chatham Islands Standard Time / New Zealand
- { 95, 144, 130 }, // SA Western Standard Time / Montserrat
- { 37, 13, 149 }, // E. Australia Standard Time / Australia
- { 61, 0, 187 }, // Line Islands Standard Time / AnyCountry
- { 132, 218, 198 }, // West Asia Standard Time / Turkmenistan
- { 122, 30, 212 }, // UTC-02 / Brazil
- { 24, 52, 228 }, // Central America Standard Time / Costa Rica
- { 36, 67, 247 }, // E. Africa Standard Time / Eritrea
- { 128, 8, 261 }, // W. Australia Standard Time / Antarctica
- { 101, 101, 278 }, // SE Asia Standard Time / Indonesia
- { 93, 8, 306 }, // SA Eastern Standard Time / Antarctica
- { 4, 178, 325 }, // Altai Standard Time / Russia
- { 95, 256, 338 }, // SA Western Standard Time / Sint Maarten
- { 95, 60, 360 }, // SA Western Standard Time / Dominica
- { 134, 167, 377 }, // West Pacific Standard Time / Papua New Guinea
- { 13, 13, 398 }, // AUS Eastern Standard Time / Australia
- { 69, 236, 435 }, // Morocco Standard Time / Western Sahara
- { 39, 30, 451 }, // E. South America Standard Time / Brazil
- { 124, 134, 469 }, // UTC+12 / Marshall Islands
- { 125, 112, 502 }, // UTC+13 / Kiribati
- { 103, 146, 520 }, // South Africa Standard Time / Mozambique
- { 94, 30, 534 }, // SA Pacific Standard Time / Brazil
- { 88, 74, 570 }, // Romance Standard Time / France
- { 71, 38, 583 }, // Mountain Standard Time / Canada
- { 72, 147, 657 }, // Myanmar Standard Time / Myanmar
- { 26, 30, 670 }, // Central Brazilian Standard Time / Brazil
- { 130, 123, 706 }, // W. Europe Standard Time / Liechtenstein
- { 46, 73, 719 }, // FLE Standard Time / Finland
- { 93, 70, 735 }, // SA Eastern Standard Time / Falkland Islands
- { 78, 159, 752 }, // Norfolk Standard Time / Norfolk Island
- { 53, 0, 768 }, // Hawaiian Standard Time / AnyCountry
- { 28, 54, 779 }, // Central European Standard Time / Croatia
- { 75, 150, 793 }, // Nepal Standard Time / Nepal
- { 46, 33, 807 }, // FLE Standard Time / Bulgaria
- { 6, 162, 820 }, // Arabian Standard Time / Oman
- { 132, 131, 832 }, // West Asia Standard Time / Maldives
- { 88, 197, 848 }, // Romance Standard Time / Spain
- { 50, 91, 875 }, // Greenwich Standard Time / Guinea
- { 5, 237, 890 }, // Arab Standard Time / Yemen
- { 92, 222, 900 }, // Russian Standard Time / Ukraine
- { 103, 204, 918 }, // South Africa Standard Time / Swaziland
- { 130, 203, 933 }, // W. Europe Standard Time / Svalbard And Jan Mayen Islands
- { 7, 103, 953 }, // Arabic Standard Time / Iraq
- { 119, 226, 966 }, // UTC-11 / United States Minor Outlying Islands
- { 5, 115, 981 }, // Arab Standard Time / Kuwait
- { 50, 189, 993 }, // Greenwich Standard Time / Sierra Leone
- { 31, 0, 1009 }, // Central Standard Time / AnyCountry
- { 53, 51, 1017 }, // Hawaiian Standard Time / Cook Islands
- { 129, 50, 1035 }, // W. Central Africa Standard Time / Congo Brazzaville
- { 64, 43, 1054 }, // Magallanes Standard Time / Chile
- { 119, 0, 1075 }, // UTC-11 / AnyCountry
- { 84, 38, 1086 }, // Pacific Standard Time / Canada
- { 22, 11, 1138 }, // Caucasus Standard Time / Armenia
- { 130, 142, 1151 }, // W. Europe Standard Time / Monaco
- { 103, 239, 1165 }, // South Africa Standard Time / Zambia
- { 46, 222, 1179 }, // FLE Standard Time / Ukraine
- { 87, 168, 1225 }, // Paraguay Standard Time / Paraguay
- { 57, 109, 1242 }, // Jordan Standard Time / Jordan
- { 109, 30, 1253 }, // Tocantins Standard Time / Brazil
- { 55, 102, 1271 }, // Iran Standard Time / Iran
- { 101, 8, 1283 }, // SE Asia Standard Time / Antarctica
- { 27, 57, 1300 }, // Central Europe Standard Time / Czech Republic
- { 95, 215, 1314 }, // SA Western Standard Time / Trinidad And Tobago
- { 103, 28, 1336 }, // South Africa Standard Time / Botswana
- { 132, 0, 1352 }, // West Asia Standard Time / AnyCountry
- { 94, 63, 1362 }, // SA Pacific Standard Time / Ecuador
- { 51, 85, 1380 }, // GTB Standard Time / Greece
- { 36, 128, 1394 }, // E. Africa Standard Time / Madagascar
- { 53, 226, 1414 }, // Hawaiian Standard Time / United States Minor Outlying Islands
- { 94, 107, 1431 }, // SA Pacific Standard Time / Jamaica
- { 104, 198, 1447 }, // Sri Lanka Standard Time / Sri Lanka
- { 27, 243, 1460 }, // Central Europe Standard Time / Serbia
- { 25, 110, 1476 }, // Central Asia Standard Time / Kazakhstan
- { 125, 0, 1502 }, // UTC+13 / AnyCountry
- { 94, 38, 1513 }, // SA Pacific Standard Time / Canada
- { 25, 31, 1535 }, // Central Asia Standard Time / British Indian Ocean Territory
- { 108, 13, 1549 }, // Tasmania Standard Time / Australia
- { 95, 174, 1583 }, // SA Western Standard Time / Puerto Rico
- { 95, 180, 1603 }, // SA Western Standard Time / Saint Kitts And Nevis
- { 130, 206, 1620 }, // W. Europe Standard Time / Switzerland
- { 117, 225, 1634 }, // US Eastern Standard Time / United States
- { 29, 140, 1701 }, // Central Pacific Standard Time / Micronesia
- { 120, 77, 1731 }, // UTC-09 / French Polynesia
- { 129, 156, 1747 }, // W. Central Africa Standard Time / Niger
- { 118, 139, 1761 }, // US Mountain Standard Time / Mexico
- { 36, 194, 1780 }, // E. Africa Standard Time / Somalia
- { 118, 0, 1797 }, // US Mountain Standard Time / AnyCountry
- { 10, 24, 1807 }, // Atlantic Standard Time / Bermuda
- { 103, 240, 1824 }, // South Africa Standard Time / Zimbabwe
- { 32, 126, 1838 }, // China Standard Time / Macau
- { 129, 66, 1849 }, // W. Central Africa Standard Time / Equatorial Guinea
- { 66, 137, 1863 }, // Mauritius Standard Time / Mauritius
- { 46, 68, 1880 }, // FLE Standard Time / Estonia
- { 50, 187, 1895 }, // Greenwich Standard Time / Senegal
- { 132, 110, 1908 }, // West Asia Standard Time / Kazakhstan
- { 25, 44, 1968 }, // Central Asia Standard Time / China
- { 130, 106, 1980 }, // W. Europe Standard Time / Italy
- { 48, 251, 1992 }, // GMT Standard Time / Isle Of Man
- { 36, 210, 2011 }, // E. Africa Standard Time / Tanzania
- { 10, 86, 2032 }, // Atlantic Standard Time / Greenland
- { 123, 86, 2046 }, // UTC / Greenland
- { 20, 38, 2067 }, // Canada Central Standard Time / Canada
- { 15, 86, 2104 }, // Azores Standard Time / Greenland
- { 69, 145, 2125 }, // Morocco Standard Time / Morocco
- { 115, 219, 2143 }, // Turks And Caicos Standard Time / Turks And Caicos Islands
- { 50, 80, 2162 }, // Greenwich Standard Time / Gambia
- { 129, 42, 2176 }, // W. Central Africa Standard Time / Chad
- { 56, 105, 2192 }, // Israel Standard Time / Israel
- { 64, 8, 2207 }, // Magallanes Standard Time / Antarctica
- { 12, 13, 2225 }, // Aus Central W. Standard Time / Australia
- { 24, 155, 2241 }, // Central America Standard Time / Nicaragua
- { 102, 170, 2257 }, // Singapore Standard Time / Philippines
- { 134, 160, 2269 }, // West Pacific Standard Time / Northern Mariana Islands
- { 43, 64, 2284 }, // Egypt Standard Time / Egypt
- { 88, 21, 2297 }, // Romance Standard Time / Belgium
- { 76, 8, 2313 }, // New Zealand Standard Time / Antarctica
- { 51, 177, 2332 }, // GTB Standard Time / Romania
- { 103, 0, 2349 }, // South Africa Standard Time / AnyCountry
- { 41, 225, 2359 }, // Eastern Standard Time / United States
- { 129, 23, 2516 }, // W. Central Africa Standard Time / Benin
- { 79, 178, 2534 }, // North Asia East Standard Time / Russia
- { 116, 143, 2547 }, // Ulaanbaatar Standard Time / Mongolia
- { 130, 14, 2580 }, // W. Europe Standard Time / Austria
- { 41, 38, 2594 }, // Eastern Standard Time / Canada
- { 95, 255, 2699 }, // SA Western Standard Time / Bonaire
- { 124, 149, 2718 }, // UTC+12 / Nauru
- { 134, 8, 2732 }, // West Pacific Standard Time / Antarctica
- { 63, 178, 2758 }, // Magadan Standard Time / Russia
- { 130, 161, 2771 }, // W. Europe Standard Time / Norway
- { 110, 0, 2783 }, // Tokyo Standard Time / AnyCountry
- { 24, 63, 2793 }, // Central America Standard Time / Ecuador
- { 103, 35, 2811 }, // South Africa Standard Time / Burundi
- { 10, 38, 2828 }, // Atlantic Standard Time / Canada
- { 29, 0, 2896 }, // Central Pacific Standard Time / AnyCountry
- { 95, 87, 2907 }, // SA Western Standard Time / Grenada
- { 29, 153, 2923 }, // Central Pacific Standard Time / New Caledonia
- { 42, 139, 2938 }, // Eastern Standard Time (Mexico) / Mexico
- { 2, 225, 2953 }, // Alaskan Standard Time / United States
- { 49, 86, 3029 }, // Greenland Standard Time / Greenland
- { 50, 92, 3045 }, // Greenwich Standard Time / Guinea Bissau
- { 130, 184, 3059 }, // W. Europe Standard Time / San Marino
- { 27, 98, 3077 }, // Central Europe Standard Time / Hungary
- { 24, 96, 3093 }, // Central America Standard Time / Honduras
- { 62, 13, 3113 }, // Lord Howe Standard Time / Australia
- { 36, 0, 3133 }, // E. Africa Standard Time / AnyCountry
- { 129, 79, 3143 }, // W. Central Africa Standard Time / Gabon
- { 95, 182, 3161 }, // SA Western Standard Time / Saint Vincent And The Grenadines
- { 48, 224, 3180 }, // GMT Standard Time / United Kingdom
- { 68, 227, 3194 }, // Montevideo Standard Time / Uruguay
- { 124, 0, 3213 }, // UTC+12 / AnyCountry
- { 130, 230, 3224 }, // W. Europe Standard Time / Vatican City State
- { 50, 99, 3239 }, // Greenwich Standard Time / Iceland
- { 34, 55, 3258 }, // Cuba Standard Time / Cuba
- { 41, 16, 3273 }, // Eastern Standard Time / Bahamas
- { 122, 196, 3288 }, // UTC-02 / South Georgia And The South Sandwich Islands
- { 24, 65, 3311 }, // Central America Standard Time / El Salvador
- { 31, 225, 3331 }, // Central Standard Time / United States
- { 95, 0, 3499 }, // SA Western Standard Time / AnyCountry
- { 94, 166, 3509 }, // SA Pacific Standard Time / Panama
- { 94, 47, 3524 }, // SA Pacific Standard Time / Colombia
- { 70, 139, 3539 }, // Mountain Standard Time (Mexico) / Mexico
- { 124, 220, 3574 }, // UTC+12 / Tuvalu
- { 130, 84, 3591 }, // W. Europe Standard Time / Gibraltar
- { 82, 178, 3608 }, // Omsk Standard Time / Russia
- { 60, 122, 3618 }, // Libya Standard Time / Libya
- { 25, 8, 3633 }, // Central Asia Standard Time / Antarctica
- { 95, 12, 3651 }, // SA Western Standard Time / Aruba
- { 67, 119, 3665 }, // Middle East Standard Time / Lebanon
- { 102, 0, 3677 }, // Singapore Standard Time / AnyCountry
- { 74, 148, 3687 }, // Namibia Standard Time / Namibia
- { 126, 231, 3703 }, // Venezuela Standard Time / Venezuela
- { 95, 234, 3719 }, // SA Western Standard Time / United States Virgin Islands
- { 21, 0, 3737 }, // Cape Verde Standard Time / AnyCountry
- { 95, 9, 3747 }, // SA Western Standard Time / Antigua And Barbuda
- { 94, 169, 3763 }, // SA Pacific Standard Time / Peru
- { 46, 248, 3776 }, // FLE Standard Time / Aland Islands
- { 50, 199, 3793 }, // Greenwich Standard Time / Saint Helena
- { 134, 140, 3812 }, // West Pacific Standard Time / Micronesia
- { 102, 190, 3825 }, // Singapore Standard Time / Singapore
- { 95, 61, 3840 }, // SA Western Standard Time / Dominican Republic
- { 103, 129, 3862 }, // South Africa Standard Time / Malawi
- { 30, 139, 3878 }, // Central Standard Time (Mexico) / Mexico
- { 102, 130, 3954 }, // Singapore Standard Time / Malaysia
- { 45, 72, 3985 }, // Fiji Standard Time / Fiji
- { 118, 225, 3998 }, // US Mountain Standard Time / United States
- { 17, 25, 4014 }, // Bangladesh Standard Time / Bhutan
- { 130, 133, 4027 }, // W. Europe Standard Time / Malta
- { 92, 178, 4040 }, // Russian Standard Time / Russia
- { 95, 135, 4084 }, // SA Western Standard Time / Martinique
- { 35, 0, 4103 }, // Dateline Standard Time / AnyCountry
- { 135, 178, 4114 }, // Yakutsk Standard Time / Russia
- { 1, 1, 4141 }, // Afghanistan Standard Time / Afghanistan
- { 123, 0, 4152 }, // UTC / AnyCountry
- { 31, 139, 4168 }, // Central Standard Time / Mexico
- { 6, 0, 4186 }, // Arabian Standard Time / AnyCountry
- { 101, 45, 4196 }, // SE Asia Standard Time / Christmas Island
- { 15, 173, 4213 }, // Azores Standard Time / Portugal
- { 129, 0, 4229 }, // W. Central Africa Standard Time / AnyCountry
- { 17, 18, 4239 }, // Bangladesh Standard Time / Bangladesh
- { 31, 38, 4250 }, // Central Standard Time / Canada
- { 94, 0, 4325 }, // SA Pacific Standard Time / AnyCountry
- { 125, 213, 4335 }, // UTC+13 / Tokelau
- { 73, 178, 4351 }, // N. Central Asia Standard Time / Russia
- { 133, 165, 4368 }, // West Bank Standard Time / Palestinian Territories
- { 114, 217, 4390 }, // Turkey Standard Time / Turkey
- { 3, 225, 4406 }, // Aleutian Standard Time / United States
- { 101, 0, 4419 }, // SE Asia Standard Time / AnyCountry
- { 71, 225, 4429 }, // Mountain Standard Time / United States
- { 36, 69, 4458 }, // E. Africa Standard Time / Ethiopia
- { 130, 151, 4477 }, // W. Europe Standard Time / Netherlands
- { 95, 245, 4494 }, // SA Western Standard Time / Saint Martin
- { 48, 173, 4510 }, // GMT Standard Time / Portugal
- { 46, 124, 4541 }, // FLE Standard Time / Lithuania
- { 130, 82, 4556 }, // W. Europe Standard Time / Germany
- { 65, 77, 4586 }, // Marquesas Standard Time / French Polynesia
- { 80, 178, 4604 }, // North Asia Standard Time / Russia
- { 61, 112, 4639 }, // Line Islands Standard Time / Kiribati
- { 96, 200, 4658 }, // Saint Pierre Standard Time / Saint Pierre And Miquelon
- { 48, 104, 4675 }, // GMT Standard Time / Ireland
- { 5, 186, 4689 }, // Arab Standard Time / Saudi Arabia
- { 83, 43, 4701 }, // Pacific SA Standard Time / Chile
- { 91, 178, 4718 }, // Russia Time Zone 11 / Russia
- { 36, 48, 4745 }, // E. Africa Standard Time / Comoros
- { 95, 152, 4759 }, // SA Western Standard Time / Cura Sao
- { 38, 141, 4775 }, // E. Europe Standard Time / Moldova
- { 24, 22, 4791 }, // Central America Standard Time / Belize
- { 103, 195, 4806 }, // South Africa Standard Time / South Africa
- { 127, 178, 4826 }, // Vladivostok Standard Time / Russia
- { 122, 0, 4857 }, // UTC-02 / AnyCountry
- { 106, 207, 4867 }, // Syria Standard Time / Syria
- { 93, 76, 4881 }, // SA Eastern Standard Time / French Guiana
- { 50, 136, 4897 }, // Greenwich Standard Time / Mauritania
- { 41, 0, 4915 }, // Eastern Standard Time / AnyCountry
- { 16, 30, 4923 }, // Bahia Standard Time / Brazil
- { 40, 43, 4937 }, // Easter Island Standard Time / Chile
- { 93, 0, 4952 }, // SA Eastern Standard Time / AnyCountry
- { 9, 178, 4962 }, // Astrakhan Standard Time / Russia
- { 95, 30, 4996 }, // SA Western Standard Time / Brazil
- { 18, 20, 5049 }, // Belarus Standard Time / Belarus
- { 95, 181, 5062 }, // SA Western Standard Time / Saint Lucia
- { 129, 6, 5079 }, // W. Central Africa Standard Time / Angola
- { 129, 157, 5093 }, // W. Central Africa Standard Time / Nigeria
- { 130, 5, 5106 }, // W. Europe Standard Time / Andorra
- { 58, 178, 5121 }, // Kaliningrad Standard Time / Russia
- { 71, 0, 5140 }, // Mountain Standard Time / AnyCountry
- { 95, 7, 5148 }, // SA Western Standard Time / Anguilla
- { 124, 235, 5165 }, // UTC+12 / Wallis And Futuna Islands
- { 6, 223, 5180 }, // Arabian Standard Time / United Arab Emirates
- { 94, 40, 5191 }, // SA Pacific Standard Time / Cayman Islands
- { 101, 211, 5206 }, // SE Asia Standard Time / Thailand
- { 29, 193, 5219 }, // Central Pacific Standard Time / Solomon Islands
- { 47, 81, 5239 }, // Georgian Standard Time / Georgia
- { 101, 36, 5252 }, // SE Asia Standard Time / Cambodia
- { 132, 228, 5268 }, // West Asia Standard Time / Uzbekistan
- { 51, 56, 5297 }, // GTB Standard Time / Cyprus
- { 95, 88, 5325 }, // SA Western Standard Time / Guadeloupe
- { 101, 232, 5344 }, // SE Asia Standard Time / Vietnam
- { 113, 178, 5356 }, // Transbaikal Standard Time / Russia
- { 50, 121, 5367 }, // Greenwich Standard Time / Liberia
- { 95, 233, 5383 }, // SA Western Standard Time / British Virgin Islands
- { 129, 49, 5399 }, // W. Central Africa Standard Time / Congo Kinshasa
- { 97, 178, 5415 }, // Sakhalin Standard Time / Russia
- { 124, 226, 5429 }, // UTC+12 / United States Minor Outlying Islands
- { 50, 83, 5442 }, // Greenwich Standard Time / Ghana
- { 76, 154, 5455 }, // New Zealand Standard Time / New Zealand
- { 23, 13, 5472 }, // Cen. Australia Standard Time / Australia
- { 53, 77, 5513 }, // Hawaiian Standard Time / French Polynesia
- { 50, 34, 5528 }, // Greenwich Standard Time / Burkina Faso
- { 132, 78, 5547 }, // West Asia Standard Time / French Southern Territories
- { 121, 0, 5564 }, // UTC-08 / AnyCountry
- { 27, 2, 5574 }, // Central Europe Standard Time / Albania
- { 107, 208, 5588 }, // Taipei Standard Time / Taiwan
- { 88, 58, 5600 }, // Romance Standard Time / Denmark
- { 36, 221, 5618 }, // E. Africa Standard Time / Uganda
- { 95, 19, 5633 }, // SA Western Standard Time / Barbados
- { 14, 15, 5650 }, // Azerbaijan Standard Time / Azerbaijan
- { 32, 97, 5660 }, // China Standard Time / Hong Kong
- { 110, 101, 5675 }, // Tokyo Standard Time / Indonesia
- { 53, 225, 5689 }, // Hawaiian Standard Time / United States
- { 36, 111, 5706 }, // E. Africa Standard Time / Kenya
- { 134, 89, 5721 }, // West Pacific Standard Time / Guam
- { 36, 254, 5734 }, // E. Africa Standard Time / South Sudan
- { 48, 71, 5746 }, // GMT Standard Time / Faroe Islands
- { 90, 178, 5762 }, // Russia Time Zone 10 / Russia
- { 119, 158, 5781 }, // UTC-11 / Niue
- { 129, 3, 5794 }, // W. Central Africa Standard Time / Algeria
- { 110, 62, 5809 }, // Tokyo Standard Time / East Timor
- { 93, 30, 5819 }, // SA Eastern Standard Time / Brazil
- { 27, 242, 5898 }, // Central Europe Standard Time / Montenegro
- { 129, 37, 5915 }, // W. Central Africa Standard Time / Cameroon
- { 101, 117, 5929 }, // SE Asia Standard Time / Laos
- { 85, 139, 5944 }, // Pacific Standard Time (Mexico) / Mexico
- { 50, 212, 5981 }, // Greenwich Standard Time / Togo
- { 46, 118, 5993 }, // FLE Standard Time / Latvia
- { 95, 38, 6005 }, // SA Western Standard Time / Canada
- { 132, 209, 6026 }, // West Asia Standard Time / Tajikistan
- { 77, 38, 6040 }, // Newfoundland Standard Time / Canada
- { 110, 108, 6057 }, // Tokyo Standard Time / Japan
- { 25, 0, 6068 }, // Central Asia Standard Time / AnyCountry
- { 28, 27, 6078 }, // Central European Standard Time / Bosnia And Herzegowina
- { 27, 191, 6094 }, // Central Europe Standard Time / Slovakia
- { 95, 93, 6112 }, // SA Western Standard Time / Guyana
- { 48, 197, 6127 }, // GMT Standard Time / Spain
- { 19, 167, 6143 }, // Bougainville Standard Time / Papua New Guinea
- { 5, 17, 6164 }, // Arab Standard Time / Bahrain
- { 24, 90, 6177 }, // Central America Standard Time / Guatemala
- { 95, 26, 6195 }, // SA Western Standard Time / Bolivia
- { 81, 113, 6210 }, // North Korea Standard Time / North Korea
- { 119, 4, 6225 }, // UTC-11 / American Samoa
- { 66, 176, 6243 }, // Mauritius Standard Time / Reunion
- { 103, 120, 6258 }, // South Africa Standard Time / Lesotho
- { 84, 0, 6272 }, // Pacific Standard Time / AnyCountry
- { 120, 0, 6280 }, // UTC-09 / AnyCountry
- { 129, 216, 6290 }, // W. Central Africa Standard Time / Tunisia
- { 99, 185, 6303 }, // Sao Tome Standard Time / Sao Tome And Principe
- { 100, 178, 6319 }, // Saratov Standard Time / Russia
- { 105, 201, 6334 }, // Sudan Standard Time / Sudan
- { 48, 252, 6350 }, // GMT Standard Time / Jersey
- { 29, 13, 6364 }, // Central Pacific Standard Time / Australia
- { 71, 139, 6385 }, // Mountain Standard Time / Mexico
- { 21, 39, 6401 }, // Cape Verde Standard Time / Cape Verde
- { 102, 101, 6421 }, // Singapore Standard Time / Indonesia
- { 27, 192, 6435 }, // Central Europe Standard Time / Slovenia
- { 48, 75, 6452 }, // GMT Standard Time / Guernsey
- { 132, 8, 6468 }, // West Asia Standard Time / Antarctica
- { 8, 10, 6486 }, // Argentina Standard Time / Argentina
- { 98, 183, 6759 }, // Samoa Standard Time / Samoa
- { 129, 41, 6772 }, // W. Central Africa Standard Time / Central African Republic
- { 111, 178, 6786 }, // Tomsk Standard Time / Russia
- { 110, 164, 6797 }, // Tokyo Standard Time / Palau
- { 11, 13, 6811 }, // AUS Central Standard Time / Australia
- { 121, 171, 6828 }, // UTC-08 / Pitcairn
- { 102, 32, 6845 }, // Singapore Standard Time / Brunei
- { 112, 214, 6857 }, // Tonga Standard Time / Tonga
- { 89, 178, 6875 }, // Russia Time Zone 3 / Russia
- { 128, 13, 6889 }, // W. Australia Standard Time / Australia
- { 28, 172, 6905 }, // Central European Standard Time / Poland
- { 72, 46, 6919 }, // Myanmar Standard Time / Cocos Islands
- { 66, 188, 6932 }, // Mauritius Standard Time / Seychelles
- { 84, 225, 6944 }, // Pacific Standard Time / United States
- { 54, 100, 6983 }, // India Standard Time / India
- { 50, 53, 6997 }, // Greenwich Standard Time / Ivory Coast
- { 24, 0, 7012 }, // Central America Standard Time / AnyCountry
- { 29, 229, 7022 }, // Central Pacific Standard Time / Vanuatu
- { 130, 125, 7036 }, // W. Europe Standard Time / Luxembourg
- { 50, 132, 7054 }, // Greenwich Standard Time / Mali
- { 103, 179, 7068 }, // South Africa Standard Time / Rwanda
- { 5, 175, 7082 }, // Arab Standard Time / Qatar
- { 86, 163, 7093 }, // Pakistan Standard Time / Pakistan
- { 134, 0, 7106 }, // West Pacific Standard Time / AnyCountry
- { 36, 59, 7117 }, // E. Africa Standard Time / Djibouti
- { 44, 178, 7133 }, // Ekaterinburg Standard Time / Russia
- { 118, 38, 7152 }, // US Mountain Standard Time / Canada
- { 36, 138, 7209 }, // E. Africa Standard Time / Mayotte
- { 28, 127, 7224 }, // Central European Standard Time / Macedonia
- { 59, 114, 7238 }, // Korea Standard Time / South Korea
- { 93, 202, 7249 }, // SA Eastern Standard Time / Suriname
- { 130, 205, 7268 }, // W. Europe Standard Time / Sweden
- { 103, 49, 7285 }, // South Africa Standard Time / Congo Kinshasa
- { 0, 0, 0 } // Trailing zeroes
-};
-
-// Windows ID Key, Windows ID Index, IANA ID Index, UTC Offset
-static const QWindowsData windowsDataTable[] = {
- { 1, 0, 4141, 16200 }, // Afghanistan Standard Time
- { 2, 26, 7303,-32400 }, // Alaskan Standard Time
- { 3, 48, 4406,-36000 }, // Aleutian Standard Time
- { 4, 71, 325, 25200 }, // Altai Standard Time
- { 5, 91, 4689, 10800 }, // Arab Standard Time
- { 6, 110, 5180, 14400 }, // Arabian Standard Time
- { 7, 132, 953, 10800 }, // Arabic Standard Time
- { 8, 153, 7321,-10800 }, // Argentina Standard Time
- { 9, 177, 7342, 14400 }, // Astrakhan Standard Time
- { 10, 201, 7359,-14400 }, // Atlantic Standard Time
- { 11, 224, 6811, 34200 }, // AUS Central Standard Time
- { 12, 250, 2225, 31500 }, // Aus Central W. Standard Time
- { 13, 279, 7375, 36000 }, // AUS Eastern Standard Time
- { 14, 305, 5650, 14400 }, // Azerbaijan Standard Time
- { 15, 330, 4213, -3600 }, // Azores Standard Time
- { 16, 351, 4923,-10800 }, // Bahia Standard Time
- { 17, 371, 4239, 21600 }, // Bangladesh Standard Time
- { 18, 396, 5049, 10800 }, // Belarus Standard Time
- { 19, 418, 6143, 39600 }, // Bougainville Standard Time
- { 20, 445, 7392,-21600 }, // Canada Central Standard Time
- { 21, 474, 6401, -3600 }, // Cape Verde Standard Time
- { 22, 499, 1138, 14400 }, // Caucasus Standard Time
- { 23, 522, 7407, 34200 }, // Cen. Australia Standard Time
- { 24, 551, 6177,-21600 }, // Central America Standard Time
- { 25, 581, 7426, 21600 }, // Central Asia Standard Time
- { 26, 608, 7438,-14400 }, // Central Brazilian Standard Time
- { 27, 640, 3077, 3600 }, // Central Europe Standard Time
- { 28, 669, 6905, 3600 }, // Central European Standard Time
- { 29, 700, 5219, 39600 }, // Central Pacific Standard Time
- { 30, 730, 7453,-21600 }, // Central Standard Time (Mexico)
- { 31, 761, 7473,-21600 }, // Central Standard Time
- { 32, 783, 48, 28800 }, // China Standard Time
- { 33, 803, 114, 45900 }, // Chatham Islands Standard Time
- { 34, 833, 3258,-18000 }, // Cuba Standard Time
- { 35, 852, 4103,-43200 }, // Dateline Standard Time
- { 36, 875, 5706, 10800 }, // E. Africa Standard Time
- { 37, 899, 7489, 36000 }, // E. Australia Standard Time
- { 38, 926, 4775, 7200 }, // E. Europe Standard Time
- { 39, 950, 451,-10800 }, // E. South America Standard Time
- { 40, 981, 4937,-21600 }, // Easter Island Standard Time
- { 41, 1009, 7508,-18000 }, // Eastern Standard Time
- { 42, 1031, 2938,-18000 }, // Eastern Standard Time (Mexico)
- { 43, 1062, 2284, 7200 }, // Egypt Standard Time
- { 44, 1082, 7133, 18000 }, // Ekaterinburg Standard Time
- { 45, 1109, 3985, 43200 }, // Fiji Standard Time
- { 46, 1128, 7525, 7200 }, // FLE Standard Time
- { 47, 1146, 5239, 14400 }, // Georgian Standard Time
- { 48, 1169, 3180, 0 }, // GMT Standard Time
- { 49, 1187, 3029,-10800 }, // Greenland Standard Time
- { 50, 1211, 3239, 0 }, // Greenwich Standard Time
- { 51, 1235, 2332, 7200 }, // GTB Standard Time
- { 52, 1253, 25,-18000 }, // Haiti Standard Time
- { 53, 1273, 5689,-36000 }, // Hawaiian Standard Time
- { 54, 1296, 6983, 19800 }, // India Standard Time
- { 55, 1316, 1271, 12600 }, // Iran Standard Time
- { 56, 1335, 2192, 7200 }, // Israel Standard Time
- { 57, 1356, 1242, 7200 }, // Jordan Standard Time
- { 58, 1377, 5121, 7200 }, // Kaliningrad Standard Time
- { 59, 1403, 7238, 32400 }, // Korea Standard Time
- { 60, 1423, 3618, 7200 }, // Libya Standard Time
- { 61, 1443, 4639, 50400 }, // Line Islands Standard Time
- { 62, 1470, 3113, 37800 }, // Lord Howe Standard Time
- { 63, 1494, 2758, 36000 }, // Magadan Standard Time
- { 64, 1516, 1054,-10800 }, // Magallanes Standard Time
- { 65, 1541, 4586,-34200 }, // Marquesas Standard Time
- { 66, 1565, 1863, 14400 }, // Mauritius Standard Time
- { 67, 1589, 3665, 7200 }, // Middle East Standard Time
- { 68, 1615, 3194,-10800 }, // Montevideo Standard Time
- { 69, 1640, 2125, 0 }, // Morocco Standard Time
- { 70, 1662, 7537,-25200 }, // Mountain Standard Time (Mexico)
- { 71, 1694, 7555,-25200 }, // Mountain Standard Time
- { 72, 1717, 657, 23400 }, // Myanmar Standard Time
- { 73, 1739, 4351, 21600 }, // N. Central Asia Standard Time
- { 74, 1769, 3687, 3600 }, // Namibia Standard Time
- { 75, 1791, 793, 20700 }, // Nepal Standard Time
- { 76, 1811, 5455, 43200 }, // New Zealand Standard Time
- { 77, 1837, 6040,-12600 }, // Newfoundland Standard Time
- { 78, 1864, 752, 39600 }, // Norfolk Standard Time
- { 79, 1886, 2534, 28800 }, // North Asia East Standard Time
- { 80, 1916, 7570, 25200 }, // North Asia Standard Time
- { 81, 1941, 6210, 30600 }, // North Korea Standard Time
- { 82, 1967, 3608, 21600 }, // Omsk Standard Time
- { 83, 1986, 4701,-10800 }, // Pacific SA Standard Time
- { 84, 2011, 7587,-28800 }, // Pacific Standard Time
- { 85, 2033, 7607,-28800 }, // Pacific Standard Time (Mexico)
- { 86, 2064, 7093, 18000 }, // Pakistan Standard Time
- { 87, 2087, 1225,-14400 }, // Paraguay Standard Time
- { 88, 2110, 570, 3600 }, // Romance Standard Time
- { 89, 2132, 6875, 14400 }, // Russia Time Zone 3
- { 90, 2151, 5762, 39600 }, // Russia Time Zone 10
- { 91, 2171, 7623, 43200 }, // Russia Time Zone 11
- { 92, 2191, 7638, 10800 }, // Russian Standard Time
- { 93, 2213, 4881,-10800 }, // SA Eastern Standard Time
- { 94, 2238, 3524,-18000 }, // SA Pacific Standard Time
- { 95, 2263, 6195,-14400 }, // SA Western Standard Time
- { 96, 2288, 4658,-10800 }, // Saint Pierre Standard Time
- { 97, 2315, 5415, 39600 }, // Sakhalin Standard Time
- { 98, 2338, 6759, 46800 }, // Samoa Standard Time
- { 99, 2358, 6303, 0 }, // Sao Tome Standard Time
- { 100, 2381, 6319, 14400 }, // Saratov Standard Time
- { 101, 2403, 5206, 25200 }, // SE Asia Standard Time
- { 102, 2425, 3825, 28800 }, // Singapore Standard Time
- { 103, 2449, 4806, 7200 }, // South Africa Standard Time
- { 104, 2476, 1447, 19800 }, // Sri Lanka Standard Time
- { 105, 2500, 6334, 7200 }, // Sudan Standard Time
- { 106, 2520, 4867, 7200 }, // Syria Standard Time
- { 107, 2540, 5588, 28800 }, // Taipei Standard Time
- { 108, 2561, 7652, 36000 }, // Tasmania Standard Time
- { 109, 2584, 1253,-10800 }, // Tocantins Standard Time
- { 110, 2608, 6057, 32400 }, // Tokyo Standard Time
- { 111, 2628, 6786, 25200 }, // Tomsk Standard Time
- { 112, 2648, 6857, 46800 }, // Tonga Standard Time
- { 113, 2668, 5356, 32400 }, // Transbaikal Standard Time
- { 114, 2694, 4390, 7200 }, // Turkey Standard Time
- { 115, 2715, 2143,-14400 }, // Turks And Caicos Standard Time
- { 116, 2746, 7669, 28800 }, // Ulaanbaatar Standard Time
- { 117, 2772, 7686,-18000 }, // US Eastern Standard Time
- { 118, 2797, 3998,-25200 }, // US Mountain Standard Time
- { 119, 2823, 1075,-39600 }, // UTC-11
- { 120, 2830, 6280,-32400 }, // UTC-09
- { 121, 2837, 5564,-28800 }, // UTC-08
- { 122, 2844, 4857, -7200 }, // UTC-02
- { 123, 2851, 7707, 0 }, // UTC
- { 124, 2855, 3213, 43200 }, // UTC+12
- { 125, 2862, 1502, 46800 }, // UTC+13
- { 126, 2869, 3703,-16200 }, // Venezuela Standard Time
- { 127, 2893, 7715, 36000 }, // Vladivostok Standard Time
- { 128, 2919, 6889, 28800 }, // W. Australia Standard Time
- { 129, 2946, 5093, 3600 }, // W. Central Africa Standard Time
- { 130, 2978, 7732, 3600 }, // W. Europe Standard Time
- { 131, 3002, 0, 25200 }, // W. Mongolia Standard Time
- { 132, 3028, 7746, 18000 }, // West Asia Standard Time
- { 133, 3052, 7760, 7200 }, // West Bank Standard Time
- { 134, 3076, 377, 36000 }, // West Pacific Standard Time
- { 135, 3103, 7772, 32400 }, // Yakutsk Standard Time
- { 0, 0, 0, 0 } // Trailing zeroes
-};
-
-// IANA ID Index, UTC Offset
-static const QUtcData utcDataTable[] = {
- { 7785, 0 }, // UTC
- { 7789,-50400 }, // UTC-14:00
- { 7799,-46800 }, // UTC-13:00
- { 7809,-43200 }, // UTC-12:00
- { 7819,-39600 }, // UTC-11:00
- { 7829,-36000 }, // UTC-10:00
- { 7839,-32400 }, // UTC-09:00
- { 7849,-28800 }, // UTC-08:00
- { 7859,-25200 }, // UTC-07:00
- { 7869,-21600 }, // UTC-06:00
- { 7879,-18000 }, // UTC-05:00
- { 7889,-16200 }, // UTC-04:30
- { 7899,-14400 }, // UTC-04:00
- { 7909,-12600 }, // UTC-03:30
- { 7919,-10800 }, // UTC-03:00
- { 7929, -7200 }, // UTC-02:00
- { 7939, -3600 }, // UTC-01:00
- { 7949, 0 }, // UTC-00:00
- { 7959, 0 }, // UTC+00:00
- { 7969, 3600 }, // UTC+01:00
- { 7979, 7200 }, // UTC+02:00
- { 7989, 10800 }, // UTC+03:00
- { 7999, 12600 }, // UTC+03:30
- { 8009, 14400 }, // UTC+04:00
- { 8019, 16200 }, // UTC+04:30
- { 8029, 18000 }, // UTC+05:00
- { 8039, 19800 }, // UTC+05:30
- { 8049, 20700 }, // UTC+05:45
- { 8059, 21600 }, // UTC+06:00
- { 8069, 23400 }, // UTC+06:30
- { 8079, 25200 }, // UTC+07:00
- { 8089, 28800 }, // UTC+08:00
- { 8099, 30600 }, // UTC+08:30
- { 8109, 32400 }, // UTC+09:00
- { 8119, 34200 }, // UTC+09:30
- { 8129, 36000 }, // UTC+10:00
- { 8139, 39600 }, // UTC+11:00
- { 8149, 43200 }, // UTC+12:00
- { 8159, 46800 }, // UTC+13:00
- { 8169, 50400 }, // UTC+14:00
- { 0, 0 } // Trailing zeroes
-};
-
-static const char windowsIdData[] = {
-0x41, 0x66, 0x67, 0x68, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64,
-0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x41, 0x6c, 0x61, 0x73, 0x6b, 0x61, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61,
-0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x41, 0x6c, 0x65, 0x75, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x53, 0x74, 0x61,
-0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x41, 0x6c, 0x74, 0x61, 0x69, 0x20, 0x53, 0x74, 0x61,
-0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x41, 0x72, 0x61, 0x62, 0x20, 0x53, 0x74, 0x61, 0x6e,
-0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x41, 0x72, 0x61, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x53, 0x74,
-0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x41, 0x72, 0x61, 0x62, 0x69, 0x63, 0x20, 0x53,
-0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69,
-0x6e, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x41, 0x73, 0x74,
-0x72, 0x61, 0x6b, 0x68, 0x61, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65,
-0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54,
-0x69, 0x6d, 0x65, 0x0, 0x41, 0x55, 0x53, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x53, 0x74, 0x61, 0x6e,
-0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x41, 0x75, 0x73, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61,
-0x6c, 0x20, 0x57, 0x2e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x41,
-0x55, 0x53, 0x20, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20,
-0x54, 0x69, 0x6d, 0x65, 0x0, 0x41, 0x7a, 0x65, 0x72, 0x62, 0x61, 0x69, 0x6a, 0x61, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e,
-0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x41, 0x7a, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x53, 0x74, 0x61,
-0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x42, 0x61, 0x68, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61,
-0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x42, 0x61, 0x6e, 0x67, 0x6c, 0x61, 0x64, 0x65, 0x73,
-0x68, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x42, 0x65, 0x6c, 0x61,
-0x72, 0x75, 0x73, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x42, 0x6f,
-0x75, 0x67, 0x61, 0x69, 0x6e, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20,
-0x54, 0x69, 0x6d, 0x65, 0x0, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x61, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20,
-0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x43, 0x61, 0x70, 0x65, 0x20, 0x56,
-0x65, 0x72, 0x64, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x43,
-0x61, 0x75, 0x63, 0x61, 0x73, 0x75, 0x73, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d,
-0x65, 0x0, 0x43, 0x65, 0x6e, 0x2e, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61,
-0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65,
-0x0, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x41, 0x73, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61,
-0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x42, 0x72, 0x61, 0x7a,
-0x69, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0,
-0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64,
-0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x45, 0x75, 0x72,
-0x6f, 0x70, 0x65, 0x61, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0,
-0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x53, 0x74, 0x61, 0x6e,
-0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x53, 0x74,
-0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x28, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x29,
-0x0, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69,
-0x6d, 0x65, 0x0, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69,
-0x6d, 0x65, 0x0, 0x43, 0x68, 0x61, 0x74, 0x68, 0x61, 0x6d, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x53,
-0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x43, 0x75, 0x62, 0x61, 0x20, 0x53, 0x74,
-0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x44, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6e, 0x65,
-0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x45, 0x2e, 0x20, 0x41, 0x66,
-0x72, 0x69, 0x63, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x45,
-0x2e, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64,
-0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x45, 0x2e, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6e,
-0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x45, 0x2e, 0x20, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65,
-0x0, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64,
-0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x53, 0x74, 0x61,
-0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x53,
-0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x28, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f,
-0x29, 0x0, 0x45, 0x67, 0x79, 0x70, 0x74, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d,
-0x65, 0x0, 0x45, 0x6b, 0x61, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x62, 0x75, 0x72, 0x67, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64,
-0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x46, 0x69, 0x6a, 0x69, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61,
-0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x46, 0x4c, 0x45, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64,
-0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x47, 0x65, 0x6f, 0x72, 0x67, 0x69, 0x61, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64,
-0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x47, 0x4d, 0x54, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72,
-0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x53, 0x74, 0x61,
-0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x47, 0x72, 0x65, 0x65, 0x6e, 0x77, 0x69, 0x63, 0x68,
-0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x47, 0x54, 0x42, 0x20, 0x53,
-0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x48, 0x61, 0x69, 0x74, 0x69, 0x20, 0x53,
-0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x48, 0x61, 0x77, 0x61, 0x69, 0x69, 0x61,
-0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x49, 0x6e, 0x64, 0x69,
-0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x49, 0x72, 0x61, 0x6e,
-0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x49, 0x73, 0x72, 0x61, 0x65,
-0x6c, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4a, 0x6f, 0x72, 0x64,
-0x61, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4b, 0x61, 0x6c,
-0x69, 0x6e, 0x69, 0x6e, 0x67, 0x72, 0x61, 0x64, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69,
-0x6d, 0x65, 0x0, 0x4b, 0x6f, 0x72, 0x65, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69,
-0x6d, 0x65, 0x0, 0x4c, 0x69, 0x62, 0x79, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69,
-0x6d, 0x65, 0x0, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x53, 0x74, 0x61, 0x6e,
-0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4c, 0x6f, 0x72, 0x64, 0x20, 0x48, 0x6f, 0x77, 0x65, 0x20,
-0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4d, 0x61, 0x67, 0x61, 0x64, 0x61,
-0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4d, 0x61, 0x67, 0x61,
-0x6c, 0x6c, 0x61, 0x6e, 0x65, 0x73, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65,
-0x0, 0x4d, 0x61, 0x72, 0x71, 0x75, 0x65, 0x73, 0x61, 0x73, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20,
-0x54, 0x69, 0x6d, 0x65, 0x0, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x75, 0x73, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64,
-0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x20, 0x45, 0x61, 0x73, 0x74,
-0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4d, 0x6f, 0x6e, 0x74, 0x65,
-0x76, 0x69, 0x64, 0x65, 0x6f, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0,
-0x4d, 0x6f, 0x72, 0x6f, 0x63, 0x63, 0x6f, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d,
-0x65, 0x0, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20,
-0x54, 0x69, 0x6d, 0x65, 0x20, 0x28, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x29, 0x0, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x61,
-0x69, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4d, 0x79, 0x61,
-0x6e, 0x6d, 0x61, 0x72, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4e,
-0x2e, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x41, 0x73, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64,
-0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61,
-0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4e, 0x65, 0x70, 0x61, 0x6c, 0x20, 0x53, 0x74, 0x61,
-0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61,
-0x6e, 0x64, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4e, 0x65, 0x77,
-0x66, 0x6f, 0x75, 0x6e, 0x64, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54,
-0x69, 0x6d, 0x65, 0x0, 0x4e, 0x6f, 0x72, 0x66, 0x6f, 0x6c, 0x6b, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64,
-0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x20, 0x41, 0x73, 0x69, 0x61, 0x20, 0x45, 0x61, 0x73,
-0x74, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4e, 0x6f, 0x72, 0x74,
-0x68, 0x20, 0x41, 0x73, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65,
-0x0, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x20, 0x4b, 0x6f, 0x72, 0x65, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72,
-0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4f, 0x6d, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64,
-0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x53, 0x41, 0x20, 0x53, 0x74, 0x61,
-0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x53,
-0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63,
-0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x28, 0x4d, 0x65, 0x78, 0x69,
-0x63, 0x6f, 0x29, 0x0, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72,
-0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x50, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x20, 0x53, 0x74, 0x61, 0x6e,
-0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x52, 0x6f, 0x6d, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x53, 0x74,
-0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x52, 0x75, 0x73, 0x73, 0x69, 0x61, 0x20, 0x54,
-0x69, 0x6d, 0x65, 0x20, 0x5a, 0x6f, 0x6e, 0x65, 0x20, 0x33, 0x0, 0x52, 0x75, 0x73, 0x73, 0x69, 0x61, 0x20, 0x54, 0x69,
-0x6d, 0x65, 0x20, 0x5a, 0x6f, 0x6e, 0x65, 0x20, 0x31, 0x30, 0x0, 0x52, 0x75, 0x73, 0x73, 0x69, 0x61, 0x20, 0x54, 0x69,
-0x6d, 0x65, 0x20, 0x5a, 0x6f, 0x6e, 0x65, 0x20, 0x31, 0x31, 0x0, 0x52, 0x75, 0x73, 0x73, 0x69, 0x61, 0x6e, 0x20, 0x53,
-0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x53, 0x41, 0x20, 0x45, 0x61, 0x73, 0x74,
-0x65, 0x72, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x53, 0x41,
-0x20, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69,
-0x6d, 0x65, 0x0, 0x53, 0x41, 0x20, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61,
-0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x50, 0x69, 0x65, 0x72, 0x72, 0x65,
-0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x53, 0x61, 0x6b, 0x68, 0x61,
-0x6c, 0x69, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x53, 0x61,
-0x6d, 0x6f, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x53, 0x61,
-0x6f, 0x20, 0x54, 0x6f, 0x6d, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65,
-0x0, 0x53, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x76, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69,
-0x6d, 0x65, 0x0, 0x53, 0x45, 0x20, 0x41, 0x73, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20,
-0x54, 0x69, 0x6d, 0x65, 0x0, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64,
-0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x53, 0x72, 0x69, 0x20,
-0x4c, 0x61, 0x6e, 0x6b, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0,
-0x53, 0x75, 0x64, 0x61, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0,
-0x53, 0x79, 0x72, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0,
-0x54, 0x61, 0x69, 0x70, 0x65, 0x69, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65,
-0x0, 0x54, 0x61, 0x73, 0x6d, 0x61, 0x6e, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54,
-0x69, 0x6d, 0x65, 0x0, 0x54, 0x6f, 0x63, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x73, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61,
-0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x54, 0x6f, 0x6b, 0x79, 0x6f, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61,
-0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x54, 0x6f, 0x6d, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61,
-0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61,
-0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x62, 0x61, 0x69, 0x6b, 0x61, 0x6c, 0x20,
-0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x54, 0x75, 0x72, 0x6b, 0x65, 0x79,
-0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x54, 0x75, 0x72, 0x6b, 0x73,
-0x20, 0x41, 0x6e, 0x64, 0x20, 0x43, 0x61, 0x69, 0x63, 0x6f, 0x73, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64,
-0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x55, 0x6c, 0x61, 0x61, 0x6e, 0x62, 0x61, 0x61, 0x74, 0x61, 0x72, 0x20, 0x53, 0x74,
-0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x55, 0x53, 0x20, 0x45, 0x61, 0x73, 0x74, 0x65,
-0x72, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x55, 0x53, 0x20,
-0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69,
-0x6d, 0x65, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x31, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x39, 0x0, 0x55, 0x54, 0x43,
-0x2d, 0x30, 0x38, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x32, 0x0, 0x55, 0x54, 0x43, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31,
-0x32, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x33, 0x0, 0x56, 0x65, 0x6e, 0x65, 0x7a, 0x75, 0x65, 0x6c, 0x61, 0x20, 0x53,
-0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x56, 0x6c, 0x61, 0x64, 0x69, 0x76, 0x6f,
-0x73, 0x74, 0x6f, 0x6b, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x57,
-0x2e, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64,
-0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x57, 0x2e, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x20, 0x41, 0x66, 0x72,
-0x69, 0x63, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x57, 0x2e,
-0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d,
-0x65, 0x0, 0x57, 0x2e, 0x20, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61,
-0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x57, 0x65, 0x73, 0x74, 0x20, 0x41, 0x73, 0x69, 0x61, 0x20, 0x53, 0x74,
-0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x57, 0x65, 0x73, 0x74, 0x20, 0x42, 0x61, 0x6e,
-0x6b, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x57, 0x65, 0x73, 0x74,
-0x20, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69,
-0x6d, 0x65, 0x0, 0x59, 0x61, 0x6b, 0x75, 0x74, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20,
-0x54, 0x69, 0x6d, 0x65, 0x0
-};
-
-static const char ianaIdData[] = {
-0x41, 0x73, 0x69, 0x61, 0x2f, 0x48, 0x6f, 0x76, 0x64, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x54, 0x61,
-0x72, 0x61, 0x77, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x2d, 0x61, 0x75,
-0x2d, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x68, 0x61, 0x6e, 0x67, 0x68, 0x61,
-0x69, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x42, 0x61, 0x72, 0x74, 0x68, 0x65, 0x6c,
-0x65, 0x6d, 0x79, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x69, 0x73, 0x68, 0x6b, 0x65, 0x6b, 0x0, 0x41, 0x6e, 0x74,
-0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x79, 0x6f, 0x77, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69,
-0x63, 0x2f, 0x43, 0x68, 0x61, 0x74, 0x68, 0x61, 0x6d, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f,
-0x6e, 0x74, 0x73, 0x65, 0x72, 0x72, 0x61, 0x74, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x42,
-0x72, 0x69, 0x73, 0x62, 0x61, 0x6e, 0x65, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x4c, 0x69,
-0x6e, 0x64, 0x65, 0x6d, 0x61, 0x6e, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x34, 0x0, 0x41, 0x73,
-0x69, 0x61, 0x2f, 0x41, 0x73, 0x68, 0x67, 0x61, 0x62, 0x61, 0x74, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x4e, 0x6f, 0x72, 0x6f, 0x6e, 0x68, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x6f, 0x73, 0x74,
-0x61, 0x5f, 0x52, 0x69, 0x63, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x73, 0x6d, 0x65, 0x72, 0x61,
-0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x73, 0x65, 0x79, 0x0, 0x41, 0x73,
-0x69, 0x61, 0x2f, 0x4a, 0x61, 0x6b, 0x61, 0x72, 0x74, 0x61, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x50, 0x6f, 0x6e, 0x74,
-0x69, 0x61, 0x6e, 0x61, 0x6b, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x6f, 0x74,
-0x68, 0x65, 0x72, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x61, 0x72, 0x6e, 0x61, 0x75, 0x6c, 0x0, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x65, 0x73, 0x0,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x0, 0x50, 0x61, 0x63,
-0x69, 0x66, 0x69, 0x63, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x5f, 0x4d, 0x6f, 0x72, 0x65, 0x73, 0x62, 0x79, 0x0, 0x41, 0x75,
-0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x53, 0x79, 0x64, 0x6e, 0x65, 0x79, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72,
-0x61, 0x6c, 0x69, 0x61, 0x2f, 0x4d, 0x65, 0x6c, 0x62, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x45, 0x6c, 0x5f, 0x41, 0x61, 0x69, 0x75, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53,
-0x61, 0x6f, 0x5f, 0x50, 0x61, 0x75, 0x6c, 0x6f, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4d, 0x61, 0x6a,
-0x75, 0x72, 0x6f, 0x20, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4b, 0x77, 0x61, 0x6a, 0x61, 0x6c, 0x65, 0x69,
-0x6e, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x45, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x75, 0x72, 0x79, 0x0,
-0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x70, 0x75, 0x74, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x52, 0x69, 0x6f, 0x5f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x45, 0x69, 0x72, 0x75, 0x6e, 0x65, 0x70, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x50, 0x61, 0x72,
-0x69, 0x73, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x45, 0x64, 0x6d, 0x6f, 0x6e, 0x74, 0x6f, 0x6e, 0x20,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, 0x42, 0x61,
-0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x75, 0x76, 0x69, 0x6b, 0x20, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x59, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6b, 0x6e, 0x69, 0x66, 0x65, 0x0, 0x41, 0x73, 0x69,
-0x61, 0x2f, 0x52, 0x61, 0x6e, 0x67, 0x6f, 0x6f, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x75,
-0x69, 0x61, 0x62, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x6d, 0x70, 0x6f, 0x5f, 0x47,
-0x72, 0x61, 0x6e, 0x64, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56, 0x61, 0x64, 0x75, 0x7a, 0x0, 0x45,
-0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x48, 0x65, 0x6c, 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e,
-0x74, 0x69, 0x63, 0x2f, 0x53, 0x74, 0x61, 0x6e, 0x6c, 0x65, 0x79, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f,
-0x4e, 0x6f, 0x72, 0x66, 0x6f, 0x6c, 0x6b, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x31, 0x30, 0x0, 0x45,
-0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x5a, 0x61, 0x67, 0x72, 0x65, 0x62, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x61,
-0x74, 0x6d, 0x61, 0x6e, 0x64, 0x75, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x6f, 0x66, 0x69, 0x61, 0x0,
-0x41, 0x73, 0x69, 0x61, 0x2f, 0x4d, 0x75, 0x73, 0x63, 0x61, 0x74, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4d,
-0x61, 0x6c, 0x64, 0x69, 0x76, 0x65, 0x73, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x61, 0x64, 0x72, 0x69,
-0x64, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x65, 0x75, 0x74, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x43, 0x6f, 0x6e, 0x61, 0x6b, 0x72, 0x79, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x64, 0x65, 0x6e, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x69, 0x6d, 0x66, 0x65, 0x72, 0x6f, 0x70, 0x6f, 0x6c, 0x0, 0x41, 0x66,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x62, 0x61, 0x62, 0x61, 0x6e, 0x65, 0x0, 0x41, 0x72, 0x63, 0x74, 0x69, 0x63, 0x2f,
-0x4c, 0x6f, 0x6e, 0x67, 0x79, 0x65, 0x61, 0x72, 0x62, 0x79, 0x65, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x61,
-0x67, 0x68, 0x64, 0x61, 0x64, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4d, 0x69, 0x64, 0x77, 0x61, 0x79,
-0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x75, 0x77, 0x61, 0x69, 0x74, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x46, 0x72, 0x65, 0x65, 0x74, 0x6f, 0x77, 0x6e, 0x0, 0x43, 0x53, 0x54, 0x36, 0x43, 0x44, 0x54, 0x0, 0x50, 0x61, 0x63,
-0x69, 0x66, 0x69, 0x63, 0x2f, 0x52, 0x61, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x42, 0x72, 0x61, 0x7a, 0x7a, 0x61, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x50, 0x75, 0x6e, 0x74, 0x61, 0x5f, 0x41, 0x72, 0x65, 0x6e, 0x61, 0x73, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47,
-0x4d, 0x54, 0x2b, 0x31, 0x31, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x56, 0x61, 0x6e, 0x63, 0x6f, 0x75,
-0x76, 0x65, 0x72, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x61, 0x77, 0x73, 0x6f, 0x6e, 0x20, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x57, 0x68, 0x69, 0x74, 0x65, 0x68, 0x6f, 0x72, 0x73, 0x65, 0x0, 0x41, 0x73,
-0x69, 0x61, 0x2f, 0x59, 0x65, 0x72, 0x65, 0x76, 0x61, 0x6e, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x6f,
-0x6e, 0x61, 0x63, 0x6f, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x75, 0x73, 0x61, 0x6b, 0x61, 0x0, 0x45,
-0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4b, 0x69, 0x65, 0x76, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x55, 0x7a,
-0x68, 0x67, 0x6f, 0x72, 0x6f, 0x64, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x5a, 0x61, 0x70, 0x6f, 0x72, 0x6f,
-0x7a, 0x68, 0x79, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x73, 0x75, 0x6e, 0x63, 0x69, 0x6f,
-0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x6d, 0x6d, 0x61, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x41, 0x72, 0x61, 0x67, 0x75, 0x61, 0x69, 0x6e, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x65, 0x68, 0x72,
-0x61, 0x6e, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x61, 0x76, 0x69, 0x73, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x50, 0x72, 0x61, 0x67, 0x75, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x66, 0x5f, 0x53, 0x70, 0x61, 0x69, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x47, 0x61, 0x62, 0x6f, 0x72, 0x6f, 0x6e, 0x65, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d,
-0x35, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x75, 0x61, 0x79, 0x61, 0x71, 0x75, 0x69, 0x6c, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x41, 0x74, 0x68, 0x65, 0x6e, 0x73, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e,
-0x2f, 0x41, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x76, 0x6f, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69,
-0x63, 0x2f, 0x4a, 0x6f, 0x68, 0x6e, 0x73, 0x74, 0x6f, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a,
-0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x6f, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x65, 0x6c, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61,
-0x2f, 0x41, 0x6c, 0x6d, 0x61, 0x74, 0x79, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x51, 0x6f, 0x73, 0x74, 0x61, 0x6e, 0x61,
-0x79, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x33, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x43, 0x6f, 0x72, 0x61, 0x6c, 0x5f, 0x48, 0x61, 0x72, 0x62, 0x6f, 0x75, 0x72, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61,
-0x6e, 0x2f, 0x43, 0x68, 0x61, 0x67, 0x6f, 0x73, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x48,
-0x6f, 0x62, 0x61, 0x72, 0x74, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x43, 0x75, 0x72, 0x72,
-0x69, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x75, 0x65, 0x72, 0x74, 0x6f, 0x5f, 0x52, 0x69,
-0x63, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x4b, 0x69, 0x74, 0x74, 0x73, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x5a, 0x75, 0x72, 0x69, 0x63, 0x68, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x70, 0x6f, 0x6c, 0x69, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x4d, 0x61, 0x72, 0x65, 0x6e, 0x67, 0x6f, 0x20, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x56, 0x65, 0x76, 0x61, 0x79,
-0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x50, 0x6f, 0x6e, 0x61, 0x70, 0x65, 0x20, 0x50, 0x61, 0x63, 0x69,
-0x66, 0x69, 0x63, 0x2f, 0x4b, 0x6f, 0x73, 0x72, 0x61, 0x65, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x47,
-0x61, 0x6d, 0x62, 0x69, 0x65, 0x72, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x69, 0x61, 0x6d, 0x65, 0x79,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x65, 0x72, 0x6d, 0x6f, 0x73, 0x69, 0x6c, 0x6c, 0x6f, 0x0,
-0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x67, 0x61, 0x64, 0x69, 0x73, 0x68, 0x75, 0x0, 0x45, 0x74, 0x63,
-0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x37, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x42, 0x65, 0x72, 0x6d,
-0x75, 0x64, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x61, 0x72, 0x61, 0x72, 0x65, 0x0, 0x41, 0x73,
-0x69, 0x61, 0x2f, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x6c, 0x61,
-0x62, 0x6f, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x75, 0x73, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x54, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x44, 0x61, 0x6b, 0x61, 0x72, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4f, 0x72, 0x61, 0x6c, 0x20, 0x41, 0x73,
-0x69, 0x61, 0x2f, 0x41, 0x71, 0x74, 0x61, 0x75, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x71, 0x74, 0x6f, 0x62, 0x65,
-0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x74, 0x79, 0x72, 0x61, 0x75, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x51, 0x79,
-0x7a, 0x79, 0x6c, 0x6f, 0x72, 0x64, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x55, 0x72, 0x75, 0x6d, 0x71, 0x69, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x52, 0x6f, 0x6d, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x49,
-0x73, 0x6c, 0x65, 0x5f, 0x6f, 0x66, 0x5f, 0x4d, 0x61, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x61,
-0x72, 0x5f, 0x65, 0x73, 0x5f, 0x53, 0x61, 0x6c, 0x61, 0x61, 0x6d, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x54, 0x68, 0x75, 0x6c, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x61, 0x6e, 0x6d, 0x61, 0x72,
-0x6b, 0x73, 0x68, 0x61, 0x76, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x65, 0x67, 0x69, 0x6e,
-0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x43, 0x75, 0x72, 0x72,
-0x65, 0x6e, 0x74, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x62, 0x79,
-0x73, 0x75, 0x6e, 0x64, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x73, 0x61, 0x62, 0x6c, 0x61, 0x6e,
-0x63, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x54, 0x75, 0x72,
-0x6b, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x6e, 0x6a, 0x75, 0x6c, 0x0, 0x41, 0x66, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x4e, 0x64, 0x6a, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4a, 0x65, 0x72,
-0x75, 0x73, 0x61, 0x6c, 0x65, 0x6d, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x61,
-0x6c, 0x6d, 0x65, 0x72, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x45, 0x75, 0x63, 0x6c, 0x61,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x75, 0x61, 0x0, 0x41, 0x73, 0x69,
-0x61, 0x2f, 0x4d, 0x61, 0x6e, 0x69, 0x6c, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x53, 0x61, 0x69,
-0x70, 0x61, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x69, 0x72, 0x6f, 0x0, 0x45, 0x75, 0x72,
-0x6f, 0x70, 0x65, 0x2f, 0x42, 0x72, 0x75, 0x73, 0x73, 0x65, 0x6c, 0x73, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74,
-0x69, 0x63, 0x61, 0x2f, 0x4d, 0x63, 0x4d, 0x75, 0x72, 0x64, 0x6f, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42,
-0x75, 0x63, 0x68, 0x61, 0x72, 0x65, 0x73, 0x74, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x32, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x65, 0x77, 0x5f, 0x59, 0x6f, 0x72, 0x6b, 0x20, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x44, 0x65, 0x74, 0x72, 0x6f, 0x69, 0x74, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x50, 0x65, 0x74, 0x65, 0x72, 0x73, 0x62, 0x75, 0x72, 0x67, 0x20, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x56, 0x69, 0x6e, 0x63, 0x65,
-0x6e, 0x6e, 0x65, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61,
-0x2f, 0x57, 0x69, 0x6e, 0x61, 0x6d, 0x61, 0x63, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x65, 0x6e,
-0x74, 0x75, 0x63, 0x6b, 0x79, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x69, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f, 0x75, 0x69, 0x73, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x6f, 0x2d, 0x4e, 0x6f, 0x76, 0x6f, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x49,
-0x72, 0x6b, 0x75, 0x74, 0x73, 0x6b, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x55, 0x6c, 0x61, 0x61, 0x6e, 0x62, 0x61, 0x61,
-0x74, 0x61, 0x72, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x43, 0x68, 0x6f, 0x69, 0x62, 0x61, 0x6c, 0x73, 0x61, 0x6e, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56, 0x69, 0x65, 0x6e, 0x6e, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x54, 0x6f, 0x72, 0x6f, 0x6e, 0x74, 0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x71,
-0x61, 0x6c, 0x75, 0x69, 0x74, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x72, 0x65,
-0x61, 0x6c, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x69, 0x70, 0x69, 0x67, 0x6f, 0x6e, 0x20, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x61, 0x6e, 0x67, 0x6e, 0x69, 0x72, 0x74, 0x75, 0x6e, 0x67, 0x20, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x42, 0x61, 0x79, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x72, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x69, 0x6a, 0x6b, 0x0, 0x50, 0x61,
-0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4e, 0x61, 0x75, 0x72, 0x75, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69,
-0x63, 0x61, 0x2f, 0x44, 0x75, 0x6d, 0x6f, 0x6e, 0x74, 0x44, 0x55, 0x72, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x0, 0x41, 0x73,
-0x69, 0x61, 0x2f, 0x4d, 0x61, 0x67, 0x61, 0x64, 0x61, 0x6e, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4f, 0x73,
-0x6c, 0x6f, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x39, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63,
-0x2f, 0x47, 0x61, 0x6c, 0x61, 0x70, 0x61, 0x67, 0x6f, 0x73, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x75,
-0x6a, 0x75, 0x6d, 0x62, 0x75, 0x72, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x61, 0x6c, 0x69,
-0x66, 0x61, 0x78, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x6c, 0x61, 0x63, 0x65, 0x5f, 0x42, 0x61,
-0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x6f, 0x6f, 0x73, 0x65, 0x5f, 0x42, 0x61, 0x79, 0x20,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x63, 0x74, 0x6f, 0x6e, 0x0, 0x45, 0x74, 0x63, 0x2f,
-0x47, 0x4d, 0x54, 0x2d, 0x31, 0x31, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x72, 0x65, 0x6e, 0x61,
-0x64, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4e, 0x6f, 0x75, 0x6d, 0x65, 0x61, 0x0, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x6e, 0x63, 0x75, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a,
-0x75, 0x6e, 0x65, 0x61, 0x75, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x6d, 0x65, 0x20, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x69, 0x74, 0x6b, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x59, 0x61, 0x6b, 0x75, 0x74, 0x61, 0x74, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x6f, 0x64,
-0x74, 0x68, 0x61, 0x62, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x69, 0x73, 0x73, 0x61, 0x75, 0x0, 0x45,
-0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x61, 0x6e, 0x5f, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x0, 0x45, 0x75, 0x72,
-0x6f, 0x70, 0x65, 0x2f, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x54, 0x65, 0x67, 0x75, 0x63, 0x69, 0x67, 0x61, 0x6c, 0x70, 0x61, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c,
-0x69, 0x61, 0x2f, 0x4c, 0x6f, 0x72, 0x64, 0x5f, 0x48, 0x6f, 0x77, 0x65, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54,
-0x2d, 0x33, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x65, 0x76, 0x69, 0x6c, 0x6c, 0x65,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4c, 0x6f, 0x6e, 0x64, 0x6f, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54,
-0x2d, 0x31, 0x32, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x0, 0x41,
-0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x52, 0x65, 0x79, 0x6b, 0x6a, 0x61, 0x76, 0x69, 0x6b, 0x0, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x61, 0x76, 0x61, 0x6e, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x4e, 0x61, 0x73, 0x73, 0x61, 0x75, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x53, 0x6f, 0x75,
-0x74, 0x68, 0x5f, 0x47, 0x65, 0x6f, 0x72, 0x67, 0x69, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x45,
-0x6c, 0x5f, 0x53, 0x61, 0x6c, 0x76, 0x61, 0x64, 0x6f, 0x72, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43,
-0x68, 0x69, 0x63, 0x61, 0x67, 0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61,
-0x6e, 0x61, 0x2f, 0x4b, 0x6e, 0x6f, 0x78, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69,
-0x61, 0x6e, 0x61, 0x2f, 0x54, 0x65, 0x6c, 0x6c, 0x5f, 0x43, 0x69, 0x74, 0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x4d, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x6e, 0x65, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x4e, 0x6f, 0x72, 0x74, 0x68, 0x5f, 0x44, 0x61, 0x6b, 0x6f, 0x74, 0x61, 0x2f, 0x42, 0x65, 0x75, 0x6c, 0x61, 0x68, 0x20,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x5f, 0x44, 0x61, 0x6b, 0x6f, 0x74, 0x61,
-0x2f, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x72, 0x74,
-0x68, 0x5f, 0x44, 0x61, 0x6b, 0x6f, 0x74, 0x61, 0x2f, 0x4e, 0x65, 0x77, 0x5f, 0x53, 0x61, 0x6c, 0x65, 0x6d, 0x0, 0x45,
-0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x34, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x61, 0x6e,
-0x61, 0x6d, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x6f, 0x67, 0x6f, 0x74, 0x61, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x68, 0x69, 0x68, 0x75, 0x61, 0x68, 0x75, 0x61, 0x20, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x7a, 0x61, 0x74, 0x6c, 0x61, 0x6e, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69,
-0x63, 0x2f, 0x46, 0x75, 0x6e, 0x61, 0x66, 0x75, 0x74, 0x69, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x47, 0x69,
-0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4f, 0x6d, 0x73, 0x6b, 0x0, 0x41, 0x66,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x72, 0x69, 0x70, 0x6f, 0x6c, 0x69, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74,
-0x69, 0x63, 0x61, 0x2f, 0x56, 0x6f, 0x73, 0x74, 0x6f, 0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41,
-0x72, 0x75, 0x62, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x65, 0x69, 0x72, 0x75, 0x74, 0x0, 0x45, 0x74, 0x63,
-0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x38, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x57, 0x69, 0x6e, 0x64, 0x68, 0x6f,
-0x65, 0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x72, 0x61, 0x63, 0x61, 0x73, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x54, 0x68, 0x6f, 0x6d, 0x61, 0x73, 0x0, 0x45, 0x74, 0x63,
-0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x31, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6e, 0x74, 0x69, 0x67,
-0x75, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x69, 0x6d, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f,
-0x70, 0x65, 0x2f, 0x4d, 0x61, 0x72, 0x69, 0x65, 0x68, 0x61, 0x6d, 0x6e, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69,
-0x63, 0x2f, 0x53, 0x74, 0x5f, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f,
-0x54, 0x72, 0x75, 0x6b, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x0,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x74, 0x6f, 0x5f, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67,
-0x6f, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x6c, 0x61, 0x6e, 0x74, 0x79, 0x72, 0x65, 0x0, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x5f, 0x43, 0x69, 0x74, 0x79, 0x20, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x68, 0x69, 0x61, 0x5f, 0x42, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x61, 0x73,
-0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x65, 0x72, 0x69, 0x64, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x65, 0x79, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b,
-0x75, 0x61, 0x6c, 0x61, 0x5f, 0x4c, 0x75, 0x6d, 0x70, 0x75, 0x72, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x75, 0x63,
-0x68, 0x69, 0x6e, 0x67, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x46, 0x69, 0x6a, 0x69, 0x0, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x68, 0x6f, 0x65, 0x6e, 0x69, 0x78, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54,
-0x68, 0x69, 0x6d, 0x70, 0x68, 0x75, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x61, 0x6c, 0x74, 0x61, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x6f, 0x73, 0x63, 0x6f, 0x77, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65,
-0x2f, 0x4b, 0x69, 0x72, 0x6f, 0x76, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56, 0x6f, 0x6c, 0x67, 0x6f, 0x67,
-0x72, 0x61, 0x64, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x71,
-0x75, 0x65, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x31, 0x32, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x59,
-0x61, 0x6b, 0x75, 0x74, 0x73, 0x6b, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x68, 0x61, 0x6e, 0x64, 0x79, 0x67, 0x61,
-0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x61, 0x62, 0x75, 0x6c, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x20,
-0x45, 0x74, 0x63, 0x2f, 0x55, 0x54, 0x43, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x74, 0x61,
-0x6d, 0x6f, 0x72, 0x6f, 0x73, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x34, 0x0, 0x49, 0x6e, 0x64, 0x69,
-0x61, 0x6e, 0x2f, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x6d, 0x61, 0x73, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69,
-0x63, 0x2f, 0x41, 0x7a, 0x6f, 0x72, 0x65, 0x73, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x0, 0x41,
-0x73, 0x69, 0x61, 0x2f, 0x44, 0x68, 0x61, 0x6b, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x57, 0x69,
-0x6e, 0x6e, 0x69, 0x70, 0x65, 0x67, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x61, 0x69, 0x6e, 0x79,
-0x5f, 0x52, 0x69, 0x76, 0x65, 0x72, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x61, 0x6e, 0x6b, 0x69,
-0x6e, 0x5f, 0x49, 0x6e, 0x6c, 0x65, 0x74, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x65, 0x73, 0x6f,
-0x6c, 0x75, 0x74, 0x65, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x35, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66,
-0x69, 0x63, 0x2f, 0x46, 0x61, 0x6b, 0x61, 0x6f, 0x66, 0x6f, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4e, 0x6f, 0x76, 0x6f,
-0x73, 0x69, 0x62, 0x69, 0x72, 0x73, 0x6b, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x48, 0x65, 0x62, 0x72, 0x6f, 0x6e, 0x20,
-0x41, 0x73, 0x69, 0x61, 0x2f, 0x47, 0x61, 0x7a, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x49, 0x73, 0x74,
-0x61, 0x6e, 0x62, 0x75, 0x6c, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x64, 0x61, 0x6b, 0x0, 0x45,
-0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x37, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x65, 0x6e,
-0x76, 0x65, 0x72, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x6f, 0x69, 0x73, 0x65, 0x0, 0x41, 0x66,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x64, 0x64, 0x69, 0x73, 0x5f, 0x41, 0x62, 0x61, 0x62, 0x61, 0x0, 0x45, 0x75, 0x72,
-0x6f, 0x70, 0x65, 0x2f, 0x41, 0x6d, 0x73, 0x74, 0x65, 0x72, 0x64, 0x61, 0x6d, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x4d, 0x61, 0x72, 0x69, 0x67, 0x6f, 0x74, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4c, 0x69, 0x73,
-0x62, 0x6f, 0x6e, 0x20, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x4d, 0x61, 0x64, 0x65, 0x69, 0x72, 0x61,
-0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56, 0x69, 0x6c, 0x6e, 0x69, 0x75, 0x73, 0x0, 0x45, 0x75, 0x72, 0x6f,
-0x70, 0x65, 0x2f, 0x42, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x75, 0x73,
-0x69, 0x6e, 0x67, 0x65, 0x6e, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4d, 0x61, 0x72, 0x71, 0x75, 0x65,
-0x73, 0x61, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x72, 0x61, 0x73, 0x6e, 0x6f, 0x79, 0x61, 0x72, 0x73, 0x6b,
-0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4e, 0x6f, 0x76, 0x6f, 0x6b, 0x75, 0x7a, 0x6e, 0x65, 0x74, 0x73, 0x6b, 0x0, 0x50,
-0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4b, 0x69, 0x72, 0x69, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x69, 0x0, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x69, 0x71, 0x75, 0x65, 0x6c, 0x6f, 0x6e, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70,
-0x65, 0x2f, 0x44, 0x75, 0x62, 0x6c, 0x69, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x52, 0x69, 0x79, 0x61, 0x64, 0x68,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x74, 0x69, 0x61, 0x67, 0x6f, 0x0, 0x41, 0x73,
-0x69, 0x61, 0x2f, 0x4b, 0x61, 0x6d, 0x63, 0x68, 0x61, 0x74, 0x6b, 0x61, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x6e,
-0x61, 0x64, 0x79, 0x72, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x43, 0x6f, 0x6d, 0x6f, 0x72, 0x6f, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x75, 0x72, 0x61, 0x63, 0x61, 0x6f, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70,
-0x65, 0x2f, 0x43, 0x68, 0x69, 0x73, 0x69, 0x6e, 0x61, 0x75, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42,
-0x65, 0x6c, 0x69, 0x7a, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a, 0x6f, 0x68, 0x61, 0x6e, 0x6e, 0x65,
-0x73, 0x62, 0x75, 0x72, 0x67, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x56, 0x6c, 0x61, 0x64, 0x69, 0x76, 0x6f, 0x73, 0x74,
-0x6f, 0x6b, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x55, 0x73, 0x74, 0x2d, 0x4e, 0x65, 0x72, 0x61, 0x0, 0x45, 0x74, 0x63,
-0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x32, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x44, 0x61, 0x6d, 0x61, 0x73, 0x63, 0x75, 0x73,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x79, 0x65, 0x6e, 0x6e, 0x65, 0x0, 0x41, 0x66, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x75, 0x61, 0x6b, 0x63, 0x68, 0x6f, 0x74, 0x74, 0x0, 0x45, 0x53, 0x54, 0x35, 0x45,
-0x44, 0x54, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x68, 0x69, 0x61, 0x0, 0x50, 0x61, 0x63,
-0x69, 0x66, 0x69, 0x63, 0x2f, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b,
-0x33, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x41, 0x73, 0x74, 0x72, 0x61, 0x6b, 0x68, 0x61, 0x6e, 0x20, 0x45,
-0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x55, 0x6c, 0x79, 0x61, 0x6e, 0x6f, 0x76, 0x73, 0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x6e, 0x61, 0x75, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42,
-0x6f, 0x61, 0x5f, 0x56, 0x69, 0x73, 0x74, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x6f, 0x72,
-0x74, 0x6f, 0x5f, 0x56, 0x65, 0x6c, 0x68, 0x6f, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x69, 0x6e, 0x73,
-0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x4c, 0x75, 0x63, 0x69, 0x61, 0x0, 0x41,
-0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x75, 0x61, 0x6e, 0x64, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x4c, 0x61, 0x67, 0x6f, 0x73, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x41, 0x6e, 0x64, 0x6f, 0x72, 0x72, 0x61,
-0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4b, 0x61, 0x6c, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x72, 0x61, 0x64, 0x0,
-0x4d, 0x53, 0x54, 0x37, 0x4d, 0x44, 0x54, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6e, 0x67, 0x75,
-0x69, 0x6c, 0x6c, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x57, 0x61, 0x6c, 0x6c, 0x69, 0x73, 0x0,
-0x41, 0x73, 0x69, 0x61, 0x2f, 0x44, 0x75, 0x62, 0x61, 0x69, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43,
-0x61, 0x79, 0x6d, 0x61, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x61, 0x6e, 0x67, 0x6b, 0x6f, 0x6b, 0x0, 0x50,
-0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x47, 0x75, 0x61, 0x64, 0x61, 0x6c, 0x63, 0x61, 0x6e, 0x61, 0x6c, 0x0, 0x41,
-0x73, 0x69, 0x61, 0x2f, 0x54, 0x62, 0x69, 0x6c, 0x69, 0x73, 0x69, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x50, 0x68, 0x6e,
-0x6f, 0x6d, 0x5f, 0x50, 0x65, 0x6e, 0x68, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x61, 0x73, 0x68, 0x6b, 0x65, 0x6e,
-0x74, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x61, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x6e, 0x64, 0x0, 0x41, 0x73, 0x69,
-0x61, 0x2f, 0x46, 0x61, 0x6d, 0x61, 0x67, 0x75, 0x73, 0x74, 0x61, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4e, 0x69, 0x63,
-0x6f, 0x73, 0x69, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x75, 0x61, 0x64, 0x65, 0x6c, 0x6f,
-0x75, 0x70, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x61, 0x69, 0x67, 0x6f, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61,
-0x2f, 0x43, 0x68, 0x69, 0x74, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x72, 0x6f, 0x76,
-0x69, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x6f, 0x72, 0x74, 0x6f, 0x6c, 0x61, 0x0, 0x41,
-0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x69, 0x6e, 0x73, 0x68, 0x61, 0x73, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f,
-0x53, 0x61, 0x6b, 0x68, 0x61, 0x6c, 0x69, 0x6e, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x57, 0x61, 0x6b,
-0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x63, 0x63, 0x72, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66,
-0x69, 0x63, 0x2f, 0x41, 0x75, 0x63, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69,
-0x61, 0x2f, 0x41, 0x64, 0x65, 0x6c, 0x61, 0x69, 0x64, 0x65, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61,
-0x2f, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x48, 0x69, 0x6c, 0x6c, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63,
-0x2f, 0x54, 0x61, 0x68, 0x69, 0x74, 0x69, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4f, 0x75, 0x61, 0x67, 0x61,
-0x64, 0x6f, 0x75, 0x67, 0x6f, 0x75, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4b, 0x65, 0x72, 0x67, 0x75, 0x65,
-0x6c, 0x65, 0x6e, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x38, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65,
-0x2f, 0x54, 0x69, 0x72, 0x61, 0x6e, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x61, 0x69, 0x70, 0x65, 0x69, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x43, 0x6f, 0x70, 0x65, 0x6e, 0x68, 0x61, 0x67, 0x65, 0x6e, 0x0, 0x41, 0x66,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x61, 0x6d, 0x70, 0x61, 0x6c, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x6f, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x61, 0x6b, 0x75, 0x0,
-0x41, 0x73, 0x69, 0x61, 0x2f, 0x48, 0x6f, 0x6e, 0x67, 0x5f, 0x4b, 0x6f, 0x6e, 0x67, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f,
-0x4a, 0x61, 0x79, 0x61, 0x70, 0x75, 0x72, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x48, 0x6f, 0x6e,
-0x6f, 0x6c, 0x75, 0x6c, 0x75, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x61, 0x69, 0x72, 0x6f, 0x62, 0x69,
-0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x47, 0x75, 0x61, 0x6d, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x4a, 0x75, 0x62, 0x61, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x46, 0x61, 0x65, 0x72, 0x6f,
-0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x72, 0x65, 0x64, 0x6e, 0x65, 0x6b, 0x6f, 0x6c, 0x79, 0x6d, 0x73, 0x6b,
-0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4e, 0x69, 0x75, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x41, 0x6c, 0x67, 0x69, 0x65, 0x72, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x44, 0x69, 0x6c, 0x69, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x46, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x65, 0x7a, 0x61, 0x20, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x65, 0x6c, 0x65, 0x6d, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d,
-0x61, 0x63, 0x65, 0x69, 0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x65, 0x63, 0x69, 0x66, 0x65,
-0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x74, 0x61, 0x72, 0x65, 0x6d, 0x0, 0x45, 0x75,
-0x72, 0x6f, 0x70, 0x65, 0x2f, 0x50, 0x6f, 0x64, 0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x44, 0x6f, 0x75, 0x61, 0x6c, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x56, 0x69, 0x65, 0x6e, 0x74, 0x69,
-0x61, 0x6e, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x69, 0x6a, 0x75, 0x61, 0x6e, 0x61, 0x20,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x74, 0x61, 0x5f, 0x49, 0x73, 0x61, 0x62, 0x65, 0x6c,
-0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f, 0x6d, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f,
-0x52, 0x69, 0x67, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x6c, 0x61, 0x6e, 0x63, 0x2d, 0x53,
-0x61, 0x62, 0x6c, 0x6f, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x44, 0x75, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x65, 0x0,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x4a, 0x6f, 0x68, 0x6e, 0x73, 0x0, 0x41, 0x73, 0x69,
-0x61, 0x2f, 0x54, 0x6f, 0x6b, 0x79, 0x6f, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x36, 0x0, 0x45, 0x75,
-0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x61, 0x72, 0x61, 0x6a, 0x65, 0x76, 0x6f, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65,
-0x2f, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6c, 0x61, 0x76, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x43, 0x61, 0x6e, 0x61,
-0x72, 0x79, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x42, 0x6f, 0x75, 0x67, 0x61, 0x69, 0x6e, 0x76, 0x69,
-0x6c, 0x6c, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x61, 0x68, 0x72, 0x61, 0x69, 0x6e, 0x0, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x4c, 0x61, 0x5f, 0x50, 0x61, 0x7a, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x50, 0x79, 0x6f, 0x6e, 0x67,
-0x79, 0x61, 0x6e, 0x67, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x50, 0x61, 0x67, 0x6f, 0x5f, 0x50, 0x61,
-0x67, 0x6f, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x52, 0x65, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x0, 0x41, 0x66,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x73, 0x65, 0x72, 0x75, 0x0, 0x50, 0x53, 0x54, 0x38, 0x50, 0x44, 0x54, 0x0,
-0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x39, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x75, 0x6e,
-0x69, 0x73, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6f, 0x5f, 0x54, 0x6f, 0x6d, 0x65, 0x0, 0x45,
-0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x61, 0x72, 0x61, 0x74, 0x6f, 0x76, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x4b, 0x68, 0x61, 0x72, 0x74, 0x6f, 0x75, 0x6d, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4a, 0x65, 0x72,
-0x73, 0x65, 0x79, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x63, 0x71, 0x75,
-0x61, 0x72, 0x69, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4f, 0x6a, 0x69, 0x6e, 0x61, 0x67, 0x61,
-0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x43, 0x61, 0x70, 0x65, 0x5f, 0x56, 0x65, 0x72, 0x64, 0x65,
-0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4d, 0x61, 0x6b, 0x61, 0x73, 0x73, 0x61, 0x72, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70,
-0x65, 0x2f, 0x4c, 0x6a, 0x75, 0x62, 0x6c, 0x6a, 0x61, 0x6e, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x47,
-0x75, 0x65, 0x72, 0x6e, 0x73, 0x65, 0x79, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x4d,
-0x61, 0x77, 0x73, 0x6f, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x75, 0x65, 0x6e, 0x6f, 0x73,
-0x5f, 0x41, 0x69, 0x72, 0x65, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e,
-0x74, 0x69, 0x6e, 0x61, 0x2f, 0x4c, 0x61, 0x5f, 0x52, 0x69, 0x6f, 0x6a, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x52, 0x69, 0x6f, 0x5f, 0x47, 0x61, 0x6c, 0x6c,
-0x65, 0x67, 0x6f, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69,
-0x6e, 0x61, 0x2f, 0x53, 0x61, 0x6c, 0x74, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67,
-0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x5f, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x5f, 0x4c, 0x75,
-0x69, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61,
-0x2f, 0x54, 0x75, 0x63, 0x75, 0x6d, 0x61, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67,
-0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x55, 0x73, 0x68, 0x75, 0x61, 0x69, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x43, 0x61, 0x74, 0x61, 0x6d, 0x61, 0x72, 0x63, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x43, 0x6f, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a, 0x75, 0x6a,
-0x75, 0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x65, 0x6e, 0x64, 0x6f, 0x7a, 0x61, 0x0, 0x50,
-0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x41, 0x70, 0x69, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42,
-0x61, 0x6e, 0x67, 0x75, 0x69, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x6f, 0x6d, 0x73, 0x6b, 0x0, 0x50, 0x61, 0x63,
-0x69, 0x66, 0x69, 0x63, 0x2f, 0x50, 0x61, 0x6c, 0x61, 0x75, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61,
-0x2f, 0x44, 0x61, 0x72, 0x77, 0x69, 0x6e, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x50, 0x69, 0x74, 0x63,
-0x61, 0x69, 0x72, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x0, 0x50, 0x61, 0x63,
-0x69, 0x66, 0x69, 0x63, 0x2f, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x74, 0x61, 0x70, 0x75, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70,
-0x65, 0x2f, 0x53, 0x61, 0x6d, 0x61, 0x72, 0x61, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x50,
-0x65, 0x72, 0x74, 0x68, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x57, 0x61, 0x72, 0x73, 0x61, 0x77, 0x0, 0x49,
-0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x43, 0x6f, 0x63, 0x6f, 0x73, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4d,
-0x61, 0x68, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f, 0x73, 0x5f, 0x41, 0x6e, 0x67, 0x65,
-0x6c, 0x65, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x65, 0x74, 0x6c, 0x61, 0x6b, 0x61, 0x74,
-0x6c, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x74, 0x74, 0x61, 0x0, 0x41, 0x66, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x41, 0x62, 0x69, 0x64, 0x6a, 0x61, 0x6e, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b,
-0x36, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x45, 0x66, 0x61, 0x74, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f,
-0x70, 0x65, 0x2f, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x6f, 0x75, 0x72, 0x67, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x42, 0x61, 0x6d, 0x61, 0x6b, 0x6f, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x69, 0x67, 0x61, 0x6c,
-0x69, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x51, 0x61, 0x74, 0x61, 0x72, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x61,
-0x72, 0x61, 0x63, 0x68, 0x69, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x30, 0x0, 0x41, 0x66, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x44, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x59, 0x65,
-0x6b, 0x61, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x62, 0x75, 0x72, 0x67, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x44, 0x61, 0x77, 0x73, 0x6f, 0x6e, 0x5f, 0x43, 0x72, 0x65, 0x65, 0x6b, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x43, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x46, 0x6f, 0x72,
-0x74, 0x5f, 0x4e, 0x65, 0x6c, 0x73, 0x6f, 0x6e, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4d, 0x61, 0x79, 0x6f,
-0x74, 0x74, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x6b, 0x6f, 0x70, 0x6a, 0x65, 0x0, 0x41, 0x73,
-0x69, 0x61, 0x2f, 0x53, 0x65, 0x6f, 0x75, 0x6c, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x61, 0x72,
-0x61, 0x6d, 0x61, 0x72, 0x69, 0x62, 0x6f, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x74, 0x6f, 0x63, 0x6b,
-0x68, 0x6f, 0x6c, 0x6d, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x75, 0x62, 0x75, 0x6d, 0x62, 0x61, 0x73,
-0x68, 0x69, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x61, 0x67, 0x65,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x75, 0x65, 0x6e, 0x6f, 0x73, 0x5f, 0x41, 0x69, 0x72, 0x65,
-0x73, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x41, 0x73, 0x74, 0x72, 0x61, 0x6b, 0x68, 0x61, 0x6e, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x61, 0x6c, 0x69, 0x66, 0x61, 0x78, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72,
-0x61, 0x6c, 0x69, 0x61, 0x2f, 0x53, 0x79, 0x64, 0x6e, 0x65, 0x79, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x52, 0x65, 0x67, 0x69, 0x6e, 0x61, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x41, 0x64, 0x65,
-0x6c, 0x61, 0x69, 0x64, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x6c, 0x6d, 0x61, 0x74, 0x79, 0x0, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x75, 0x69, 0x61, 0x62, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x5f, 0x43, 0x69, 0x74, 0x79, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x43, 0x68, 0x69, 0x63, 0x61, 0x67, 0x6f, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x42,
-0x72, 0x69, 0x73, 0x62, 0x61, 0x6e, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x65, 0x77, 0x5f,
-0x59, 0x6f, 0x72, 0x6b, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4b, 0x69, 0x65, 0x76, 0x0, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x68, 0x69, 0x68, 0x75, 0x61, 0x68, 0x75, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x44, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x72, 0x61, 0x73, 0x6e,
-0x6f, 0x79, 0x61, 0x72, 0x73, 0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f, 0x73, 0x5f, 0x41,
-0x6e, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x69, 0x6a, 0x75, 0x61,
-0x6e, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x61, 0x6d, 0x63, 0x68, 0x61, 0x74, 0x6b, 0x61, 0x0, 0x45, 0x75,
-0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x6f, 0x73, 0x63, 0x6f, 0x77, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69,
-0x61, 0x2f, 0x48, 0x6f, 0x62, 0x61, 0x72, 0x74, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x55, 0x6c, 0x61, 0x61, 0x6e, 0x62,
-0x61, 0x61, 0x74, 0x61, 0x72, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e,
-0x61, 0x70, 0x6f, 0x6c, 0x69, 0x73, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f,
-0x56, 0x6c, 0x61, 0x64, 0x69, 0x76, 0x6f, 0x73, 0x74, 0x6f, 0x6b, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42,
-0x65, 0x72, 0x6c, 0x69, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x61, 0x73, 0x68, 0x6b, 0x65, 0x6e, 0x74, 0x0,
-0x41, 0x73, 0x69, 0x61, 0x2f, 0x48, 0x65, 0x62, 0x72, 0x6f, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x59, 0x61, 0x6b,
-0x75, 0x74, 0x73, 0x6b, 0x0, 0x55, 0x54, 0x43, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x34, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2d, 0x31, 0x33, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x32, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2d, 0x31, 0x31, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x30, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2d, 0x30, 0x39, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x38, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2d, 0x30, 0x37, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x36, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2d, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x34, 0x3a, 0x33, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2d, 0x30, 0x34, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x33, 0x3a, 0x33, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2d, 0x30, 0x33, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x32, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2d, 0x30, 0x31, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x31, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x33, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2b, 0x30, 0x33, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x34, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2b, 0x30, 0x34, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2b, 0x30, 0x35, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x35, 0x3a, 0x34, 0x35, 0x0, 0x55,
-0x54, 0x43, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x36, 0x3a, 0x33, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2b, 0x30, 0x37, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x38, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2b, 0x30, 0x38, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x39, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2b, 0x30, 0x39, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x30, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2b, 0x31, 0x31, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x32, 0x3a, 0x30, 0x30, 0x0, 0x55,
-0x54, 0x43, 0x2b, 0x31, 0x33, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x34, 0x3a, 0x30, 0x30, 0x0
-};
-// GENERATED PART ENDS HERE
-
-QT_END_NAMESPACE
-
-#endif // QTIMEZONEPRIVATE_DATA_P_H
diff --git a/src/corelib/tools/qtimezoneprivate_icu.cpp b/src/corelib/tools/qtimezoneprivate_icu.cpp
deleted file mode 100644
index 5570ce7571..0000000000
--- a/src/corelib/tools/qtimezoneprivate_icu.cpp
+++ /dev/null
@@ -1,508 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 John Layt <jlayt@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtimezone.h"
-#include "qtimezoneprivate_p.h"
-
-#include <unicode/ucal.h>
-
-#include <qdebug.h>
-#include <qlist.h>
-
-#include <algorithm>
-
-QT_BEGIN_NAMESPACE
-
-/*
- Private
-
- ICU implementation
-*/
-
-// ICU utilities
-
-// Convert TimeType and NameType into ICU UCalendarDisplayNameType
-static UCalendarDisplayNameType ucalDisplayNameType(QTimeZone::TimeType timeType, QTimeZone::NameType nameType)
-{
- // TODO ICU C UCalendarDisplayNameType does not support full set of C++ TimeZone::EDisplayType
- switch (nameType) {
- case QTimeZone::ShortName :
- case QTimeZone::OffsetName :
- if (timeType == QTimeZone::DaylightTime)
- return UCAL_SHORT_DST;
- // Includes GenericTime
- return UCAL_SHORT_STANDARD;
- case QTimeZone::DefaultName :
- case QTimeZone::LongName :
- if (timeType == QTimeZone::DaylightTime)
- return UCAL_DST;
- // Includes GenericTime
- return UCAL_STANDARD;
- }
- return UCAL_STANDARD;
-}
-
-// Qt wrapper around ucal_getDefaultTimeZone()
-static QByteArray ucalDefaultTimeZoneId()
-{
- int32_t size = 30;
- QString result(size, Qt::Uninitialized);
- UErrorCode status = U_ZERO_ERROR;
-
- // size = ucal_getDefaultTimeZone(result, resultLength, status)
- size = ucal_getDefaultTimeZone(reinterpret_cast<UChar *>(result.data()), size, &status);
-
- // If overflow, then resize and retry
- if (status == U_BUFFER_OVERFLOW_ERROR) {
- result.resize(size);
- status = U_ZERO_ERROR;
- size = ucal_getDefaultTimeZone(reinterpret_cast<UChar *>(result.data()), size, &status);
- }
-
- // If successful on first or second go, resize and return
- if (U_SUCCESS(status)) {
- result.resize(size);
- return std::move(result).toUtf8();
- }
-
- return QByteArray();
-}
-
-// Qt wrapper around ucal_getTimeZoneDisplayName()
-static QString ucalTimeZoneDisplayName(UCalendar *ucal, QTimeZone::TimeType timeType,
- QTimeZone::NameType nameType,
- const QString &localeCode)
-{
- int32_t size = 50;
- QString result(size, Qt::Uninitialized);
- UErrorCode status = U_ZERO_ERROR;
-
- // size = ucal_getTimeZoneDisplayName(cal, type, locale, result, resultLength, status)
- size = ucal_getTimeZoneDisplayName(ucal,
- ucalDisplayNameType(timeType, nameType),
- localeCode.toUtf8(),
- reinterpret_cast<UChar *>(result.data()),
- size,
- &status);
-
- // If overflow, then resize and retry
- if (status == U_BUFFER_OVERFLOW_ERROR) {
- result.resize(size);
- status = U_ZERO_ERROR;
- size = ucal_getTimeZoneDisplayName(ucal,
- ucalDisplayNameType(timeType, nameType),
- localeCode.toUtf8(),
- reinterpret_cast<UChar *>(result.data()),
- size,
- &status);
- }
-
- // If successful on first or second go, resize and return
- if (U_SUCCESS(status)) {
- result.resize(size);
- return result;
- }
-
- return QString();
-}
-
-// Qt wrapper around ucal_get() for offsets
-static bool ucalOffsetsAtTime(UCalendar *m_ucal, qint64 atMSecsSinceEpoch,
- int *utcOffset, int *dstOffset)
-{
- *utcOffset = 0;
- *dstOffset = 0;
-
- // Clone the ucal so we don't change the shared object
- UErrorCode status = U_ZERO_ERROR;
- UCalendar *ucal = ucal_clone(m_ucal, &status);
- if (!U_SUCCESS(status))
- return false;
-
- // Set the date to find the offset for
- status = U_ZERO_ERROR;
- ucal_setMillis(ucal, atMSecsSinceEpoch, &status);
-
- int32_t utc = 0;
- if (U_SUCCESS(status)) {
- status = U_ZERO_ERROR;
- // Returns msecs
- utc = ucal_get(ucal, UCAL_ZONE_OFFSET, &status) / 1000;
- }
-
- int32_t dst = 0;
- if (U_SUCCESS(status)) {
- status = U_ZERO_ERROR;
- // Returns msecs
- dst = ucal_get(ucal, UCAL_DST_OFFSET, &status) / 1000;
- }
-
- ucal_close(ucal);
- if (U_SUCCESS(status)) {
- *utcOffset = utc;
- *dstOffset = dst;
- return true;
- }
- return false;
-}
-
-// ICU Draft api in v50, should be stable in ICU v51. Available in C++ api from ICU v3.8
-#if U_ICU_VERSION_MAJOR_NUM == 50
-// Qt wrapper around qt_ucal_getTimeZoneTransitionDate & ucal_get
-static QTimeZonePrivate::Data ucalTimeZoneTransition(UCalendar *m_ucal,
- UTimeZoneTransitionType type,
- qint64 atMSecsSinceEpoch)
-{
- QTimeZonePrivate::Data tran = QTimeZonePrivate::invalidData();
-
- // Clone the ucal so we don't change the shared object
- UErrorCode status = U_ZERO_ERROR;
- UCalendar *ucal = ucal_clone(m_ucal, &status);
- if (!U_SUCCESS(status))
- return tran;
-
- // Set the date to find the transition for
- status = U_ZERO_ERROR;
- ucal_setMillis(ucal, atMSecsSinceEpoch, &status);
-
- // Find the transition time
- UDate tranMSecs = 0;
- status = U_ZERO_ERROR;
- bool ok = ucal_getTimeZoneTransitionDate(ucal, type, &tranMSecs, &status);
-
- // Set the transition time to find the offsets for
- if (U_SUCCESS(status) && ok) {
- status = U_ZERO_ERROR;
- ucal_setMillis(ucal, tranMSecs, &status);
- }
-
- int32_t utc = 0;
- if (U_SUCCESS(status) && ok) {
- status = U_ZERO_ERROR;
- utc = ucal_get(ucal, UCAL_ZONE_OFFSET, &status) / 1000;
- }
-
- int32_t dst = 0;
- if (U_SUCCESS(status) && ok) {
- status = U_ZERO_ERROR;
- dst = ucal_get(ucal, UCAL_DST_OFFSET, &status) / 1000;
- }
-
- ucal_close(ucal);
- if (!U_SUCCESS(status) || !ok)
- return tran;
- tran.atMSecsSinceEpoch = tranMSecs;
- tran.offsetFromUtc = utc + dst;
- tran.standardTimeOffset = utc;
- tran.daylightTimeOffset = dst;
- // TODO No ICU API, use short name instead
- if (dst == 0)
- tran.abbreviation = ucalTimeZoneDisplayName(m_ucal, QTimeZone::StandardTime,
- QTimeZone::ShortName, QLocale().name());
- else
- tran.abbreviation = ucalTimeZoneDisplayName(m_ucal, QTimeZone::DaylightTime,
- QTimeZone::ShortName, QLocale().name());
- return tran;
-}
-#endif // U_ICU_VERSION_SHORT
-
-// Convert a uenum to a QList<QByteArray>
-static QList<QByteArray> uenumToIdList(UEnumeration *uenum)
-{
- QList<QByteArray> list;
- int32_t size = 0;
- UErrorCode status = U_ZERO_ERROR;
- // TODO Perhaps use uenum_unext instead?
- QByteArray result = uenum_next(uenum, &size, &status);
- while (U_SUCCESS(status) && !result.isEmpty()) {
- list << result;
- status = U_ZERO_ERROR;
- result = uenum_next(uenum, &size, &status);
- }
- std::sort(list.begin(), list.end());
- list.erase(std::unique(list.begin(), list.end()), list.end());
- return list;
-}
-
-// Qt wrapper around ucal_getDSTSavings()
-static int ucalDaylightOffset(const QByteArray &id)
-{
- UErrorCode status = U_ZERO_ERROR;
- const int32_t dstMSecs = ucal_getDSTSavings(reinterpret_cast<const UChar *>(id.data()), &status);
- if (U_SUCCESS(status))
- return (dstMSecs / 1000);
- else
- return 0;
-}
-
-// Create the system default time zone
-QIcuTimeZonePrivate::QIcuTimeZonePrivate()
- : m_ucal(0)
-{
- // TODO No ICU C API to obtain sysem tz, assume default hasn't been changed
- init(ucalDefaultTimeZoneId());
-}
-
-// Create a named time zone
-QIcuTimeZonePrivate::QIcuTimeZonePrivate(const QByteArray &ianaId)
- : m_ucal(0)
-{
- // Need to check validity here as ICu will create a GMT tz if name is invalid
- if (availableTimeZoneIds().contains(ianaId))
- init(ianaId);
-}
-
-QIcuTimeZonePrivate::QIcuTimeZonePrivate(const QIcuTimeZonePrivate &other)
- : QTimeZonePrivate(other), m_ucal(0)
-{
- // Clone the ucal so we don't close the shared object
- UErrorCode status = U_ZERO_ERROR;
- m_ucal = ucal_clone(other.m_ucal, &status);
- if (!U_SUCCESS(status)) {
- m_id.clear();
- m_ucal = 0;
- }
-}
-
-QIcuTimeZonePrivate::~QIcuTimeZonePrivate()
-{
- ucal_close(m_ucal);
-}
-
-QIcuTimeZonePrivate *QIcuTimeZonePrivate::clone() const
-{
- return new QIcuTimeZonePrivate(*this);
-}
-
-void QIcuTimeZonePrivate::init(const QByteArray &ianaId)
-{
- m_id = ianaId;
-
- const QString id = QString::fromUtf8(m_id);
- UErrorCode status = U_ZERO_ERROR;
- //TODO Use UCAL_GREGORIAN for now to match QLocale, change to UCAL_DEFAULT once full ICU support
- m_ucal = ucal_open(reinterpret_cast<const UChar *>(id.data()), id.size(),
- QLocale().name().toUtf8(), UCAL_GREGORIAN, &status);
-
- if (!U_SUCCESS(status)) {
- m_id.clear();
- m_ucal = 0;
- }
-}
-
-QString QIcuTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
- QTimeZone::NameType nameType,
- const QLocale &locale) const
-{
- // Return standard offset format name as ICU C api doesn't support it yet
- if (nameType == QTimeZone::OffsetName) {
- const Data nowData = data(QDateTime::currentMSecsSinceEpoch());
- // We can't use transitions reliably to find out right dst offset
- // Instead use dst offset api to try get it if needed
- if (timeType == QTimeZone::DaylightTime)
- return isoOffsetFormat(nowData.standardTimeOffset + ucalDaylightOffset(m_id));
- else
- return isoOffsetFormat(nowData.standardTimeOffset);
- }
- return ucalTimeZoneDisplayName(m_ucal, timeType, nameType, locale.name());
-}
-
-QString QIcuTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch) const
-{
- // TODO No ICU API, use short name instead
- if (isDaylightTime(atMSecsSinceEpoch))
- return displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, QString());
- else
- return displayName(QTimeZone::StandardTime, QTimeZone::ShortName, QString());
-}
-
-int QIcuTimeZonePrivate::offsetFromUtc(qint64 atMSecsSinceEpoch) const
-{
- int stdOffset = 0;
- int dstOffset = 0;
- ucalOffsetsAtTime(m_ucal, atMSecsSinceEpoch, &stdOffset, & dstOffset);
- return stdOffset + dstOffset;
-}
-
-int QIcuTimeZonePrivate::standardTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- int stdOffset = 0;
- int dstOffset = 0;
- ucalOffsetsAtTime(m_ucal, atMSecsSinceEpoch, &stdOffset, & dstOffset);
- return stdOffset;
-}
-
-int QIcuTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- int stdOffset = 0;
- int dstOffset = 0;
- ucalOffsetsAtTime(m_ucal, atMSecsSinceEpoch, &stdOffset, & dstOffset);
- return dstOffset;
-}
-
-bool QIcuTimeZonePrivate::hasDaylightTime() const
-{
- // TODO No direct ICU C api, work-around below not reliable? Find a better way?
- return (ucalDaylightOffset(m_id) != 0);
-}
-
-bool QIcuTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
-{
- // Clone the ucal so we don't change the shared object
- UErrorCode status = U_ZERO_ERROR;
- UCalendar *ucal = ucal_clone(m_ucal, &status);
- if (!U_SUCCESS(status))
- return false;
-
- // Set the date to find the offset for
- status = U_ZERO_ERROR;
- ucal_setMillis(ucal, atMSecsSinceEpoch, &status);
-
- bool result = false;
- if (U_SUCCESS(status)) {
- status = U_ZERO_ERROR;
- result = ucal_inDaylightTime(ucal, &status);
- }
-
- ucal_close(ucal);
- return result;
-}
-
-QTimeZonePrivate::Data QIcuTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
-{
- // Available in ICU C++ api, and draft C api in v50
- // TODO When v51 released see if api is stable
- QTimeZonePrivate::Data data = invalidData();
-#if U_ICU_VERSION_MAJOR_NUM == 50
- data = ucalTimeZoneTransition(m_ucal, UCAL_TZ_TRANSITION_PREVIOUS_INCLUSIVE,
- forMSecsSinceEpoch);
-#else
- ucalOffsetsAtTime(m_ucal, forMSecsSinceEpoch, &data.standardTimeOffset,
- &data.daylightTimeOffset);
- data.offsetFromUtc = data.standardTimeOffset + data.daylightTimeOffset;
- data.abbreviation = abbreviation(forMSecsSinceEpoch);
-#endif // U_ICU_VERSION_MAJOR_NUM == 50
- data.atMSecsSinceEpoch = forMSecsSinceEpoch;
- return data;
-}
-
-bool QIcuTimeZonePrivate::hasTransitions() const
-{
- // Available in ICU C++ api, and draft C api in v50
- // TODO When v51 released see if api is stable
-#if U_ICU_VERSION_MAJOR_NUM == 50
- return true;
-#else
- return false;
-#endif // U_ICU_VERSION_MAJOR_NUM == 50
-}
-
-QTimeZonePrivate::Data QIcuTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const
-{
- // Available in ICU C++ api, and draft C api in v50
- // TODO When v51 released see if api is stable
-#if U_ICU_VERSION_MAJOR_NUM == 50
- return ucalTimeZoneTransition(m_ucal, UCAL_TZ_TRANSITION_NEXT, afterMSecsSinceEpoch);
-#else
- Q_UNUSED(afterMSecsSinceEpoch)
- return invalidData();
-#endif // U_ICU_VERSION_MAJOR_NUM == 50
-}
-
-QTimeZonePrivate::Data QIcuTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
-{
- // Available in ICU C++ api, and draft C api in v50
- // TODO When v51 released see if api is stable
-#if U_ICU_VERSION_MAJOR_NUM == 50
- return ucalTimeZoneTransition(m_ucal, UCAL_TZ_TRANSITION_PREVIOUS, beforeMSecsSinceEpoch);
-#else
- Q_UNUSED(beforeMSecsSinceEpoch)
- return invalidData();
-#endif // U_ICU_VERSION_MAJOR_NUM == 50
-}
-
-QByteArray QIcuTimeZonePrivate::systemTimeZoneId() const
-{
- // No ICU C API to obtain sysem tz
- // TODO Assume default hasn't been changed and is the latests system
- return ucalDefaultTimeZoneId();
-}
-
-QList<QByteArray> QIcuTimeZonePrivate::availableTimeZoneIds() const
-{
- UErrorCode status = U_ZERO_ERROR;
- UEnumeration *uenum = ucal_openTimeZones(&status);
- QList<QByteArray> result;
- if (U_SUCCESS(status))
- result = uenumToIdList(uenum);
- uenum_close(uenum);
- return result;
-}
-
-QList<QByteArray> QIcuTimeZonePrivate::availableTimeZoneIds(QLocale::Country country) const
-{
- const QLatin1String regionCode = QLocalePrivate::countryToCode(country);
- const QByteArray regionCodeUtf8 = QString(regionCode).toUtf8();
- UErrorCode status = U_ZERO_ERROR;
- UEnumeration *uenum = ucal_openCountryTimeZones(regionCodeUtf8.data(), &status);
- QList<QByteArray> result;
- if (U_SUCCESS(status))
- result = uenumToIdList(uenum);
- uenum_close(uenum);
- return result;
-}
-
-QList<QByteArray> QIcuTimeZonePrivate::availableTimeZoneIds(int offsetFromUtc) const
-{
-// TODO Available directly in C++ api but not C api, from 4.8 onwards new filter method works
-#if U_ICU_VERSION_MAJOR_NUM >= 49 || (U_ICU_VERSION_MAJOR_NUM == 4 && U_ICU_VERSION_MINOR_NUM == 8)
- UErrorCode status = U_ZERO_ERROR;
- UEnumeration *uenum = ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_ANY, 0,
- &offsetFromUtc, &status);
- QList<QByteArray> result;
- if (U_SUCCESS(status))
- result = uenumToIdList(uenum);
- uenum_close(uenum);
- return result;
-#else
- return QTimeZonePrivate::availableTimeZoneIds(offsetFromUtc);
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/corelib/tools/qtimezoneprivate_mac.mm b/src/corelib/tools/qtimezoneprivate_mac.mm
deleted file mode 100644
index d3c4fbe5da..0000000000
--- a/src/corelib/tools/qtimezoneprivate_mac.mm
+++ /dev/null
@@ -1,333 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 John Layt <jlayt@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtimezone.h"
-#include "qtimezoneprivate_p.h"
-
-#include "private/qcore_mac_p.h"
-#include "qstringlist.h"
-
-#include <Foundation/NSTimeZone.h>
-
-#include <qdebug.h>
-
-#include <algorithm>
-
-QT_BEGIN_NAMESPACE
-
-/*
- Private
-
- OS X system implementation
-*/
-
-// Create the system default time zone
-QMacTimeZonePrivate::QMacTimeZonePrivate()
- : m_nstz(0)
-{
- init(systemTimeZoneId());
-}
-
-// Create a named time zone
-QMacTimeZonePrivate::QMacTimeZonePrivate(const QByteArray &ianaId)
- : m_nstz(0)
-{
- init(ianaId);
-}
-
-QMacTimeZonePrivate::QMacTimeZonePrivate(const QMacTimeZonePrivate &other)
- : QTimeZonePrivate(other), m_nstz(0)
-{
- m_nstz = [other.m_nstz copy];
-}
-
-QMacTimeZonePrivate::~QMacTimeZonePrivate()
-{
- [m_nstz release];
-}
-
-QMacTimeZonePrivate *QMacTimeZonePrivate::clone() const
-{
- return new QMacTimeZonePrivate(*this);
-}
-
-void QMacTimeZonePrivate::init(const QByteArray &ianaId)
-{
- if (availableTimeZoneIds().contains(ianaId)) {
- m_nstz = [[NSTimeZone timeZoneWithName:QString::fromUtf8(ianaId).toNSString()] retain];
- if (m_nstz)
- m_id = ianaId;
- }
-}
-
-QString QMacTimeZonePrivate::comment() const
-{
- return QString::fromNSString([m_nstz description]);
-}
-
-QString QMacTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
- QTimeZone::NameType nameType,
- const QLocale &locale) const
-{
- // TODO Mac doesn't support OffsetName yet so use standard offset name
- if (nameType == QTimeZone::OffsetName) {
- const Data nowData = data(QDateTime::currentMSecsSinceEpoch());
- // TODO Cheat for now, assume if has dst the offset if 1 hour
- if (timeType == QTimeZone::DaylightTime && hasDaylightTime())
- return isoOffsetFormat(nowData.standardTimeOffset + 3600);
- else
- return isoOffsetFormat(nowData.standardTimeOffset);
- }
-
- NSTimeZoneNameStyle style = NSTimeZoneNameStyleStandard;
-
- switch (nameType) {
- case QTimeZone::ShortName :
- if (timeType == QTimeZone::DaylightTime)
- style = NSTimeZoneNameStyleShortDaylightSaving;
- else if (timeType == QTimeZone::GenericTime)
- style = NSTimeZoneNameStyleShortGeneric;
- else
- style = NSTimeZoneNameStyleShortStandard;
- break;
- case QTimeZone::DefaultName :
- case QTimeZone::LongName :
- if (timeType == QTimeZone::DaylightTime)
- style = NSTimeZoneNameStyleDaylightSaving;
- else if (timeType == QTimeZone::GenericTime)
- style = NSTimeZoneNameStyleGeneric;
- else
- style = NSTimeZoneNameStyleStandard;
- break;
- case QTimeZone::OffsetName :
- // Unreachable
- break;
- }
-
- NSString *macLocaleCode = locale.name().toNSString();
- NSLocale *macLocale = [[NSLocale alloc] initWithLocaleIdentifier:macLocaleCode];
- const QString result = QString::fromNSString([m_nstz localizedName:style locale:macLocale]);
- [macLocale release];
- return result;
-}
-
-QString QMacTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch) const
-{
- const NSTimeInterval seconds = atMSecsSinceEpoch / 1000.0;
- return QString::fromNSString([m_nstz abbreviationForDate:[NSDate dateWithTimeIntervalSince1970:seconds]]);
-}
-
-int QMacTimeZonePrivate::offsetFromUtc(qint64 atMSecsSinceEpoch) const
-{
- const NSTimeInterval seconds = atMSecsSinceEpoch / 1000.0;
- return [m_nstz secondsFromGMTForDate:[NSDate dateWithTimeIntervalSince1970:seconds]];
-}
-
-int QMacTimeZonePrivate::standardTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- return offsetFromUtc(atMSecsSinceEpoch) - daylightTimeOffset(atMSecsSinceEpoch);
-}
-
-int QMacTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- const NSTimeInterval seconds = atMSecsSinceEpoch / 1000.0;
- return [m_nstz daylightSavingTimeOffsetForDate:[NSDate dateWithTimeIntervalSince1970:seconds]];
-}
-
-bool QMacTimeZonePrivate::hasDaylightTime() const
-{
- // TODO No Mac API, assume if has transitions
- return hasTransitions();
-}
-
-bool QMacTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
-{
- const NSTimeInterval seconds = atMSecsSinceEpoch / 1000.0;
- return [m_nstz isDaylightSavingTimeForDate:[NSDate dateWithTimeIntervalSince1970:seconds]];
-}
-
-QTimeZonePrivate::Data QMacTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
-{
- const NSTimeInterval seconds = forMSecsSinceEpoch / 1000.0;
- NSDate *date = [NSDate dateWithTimeIntervalSince1970:seconds];
- Data data;
- data.atMSecsSinceEpoch = forMSecsSinceEpoch;
- data.offsetFromUtc = [m_nstz secondsFromGMTForDate:date];
- data.daylightTimeOffset = [m_nstz daylightSavingTimeOffsetForDate:date];
- data.standardTimeOffset = data.offsetFromUtc - data.daylightTimeOffset;
- data.abbreviation = QString::fromNSString([m_nstz abbreviationForDate:date]);
- return data;
-}
-
-bool QMacTimeZonePrivate::hasTransitions() const
-{
- // TODO No direct Mac API, so return if has next after 1970, i.e. since start of tz
- // TODO Not sure what is returned in event of no transitions, assume will be before requested date
- NSDate *epoch = [NSDate dateWithTimeIntervalSince1970:0];
- const NSDate *date = [m_nstz nextDaylightSavingTimeTransitionAfterDate:epoch];
- const bool result = ([date timeIntervalSince1970] > [epoch timeIntervalSince1970]);
- return result;
-}
-
-QTimeZonePrivate::Data QMacTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const
-{
- QTimeZonePrivate::Data tran;
- const NSTimeInterval seconds = afterMSecsSinceEpoch / 1000.0;
- NSDate *nextDate = [NSDate dateWithTimeIntervalSince1970:seconds];
- nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
- const NSTimeInterval nextSecs = [nextDate timeIntervalSince1970];
- if (nextDate == nil || nextSecs <= seconds) {
- [nextDate release];
- return invalidData();
- }
- tran.atMSecsSinceEpoch = nextSecs * 1000;
- tran.offsetFromUtc = [m_nstz secondsFromGMTForDate:nextDate];
- tran.daylightTimeOffset = [m_nstz daylightSavingTimeOffsetForDate:nextDate];
- tran.standardTimeOffset = tran.offsetFromUtc - tran.daylightTimeOffset;
- tran.abbreviation = QString::fromNSString([m_nstz abbreviationForDate:nextDate]);
- return tran;
-}
-
-QTimeZonePrivate::Data QMacTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
-{
- // The native API only lets us search forward, so we need to find an early-enough start:
- const NSTimeInterval lowerBound = std::numeric_limits<NSTimeInterval>::lowest();
- const qint64 endSecs = beforeMSecsSinceEpoch / 1000;
- const int year = 366 * 24 * 3600; // a (long) year, in seconds
- NSTimeInterval prevSecs = endSecs; // sentinel for later check
- NSTimeInterval nextSecs = prevSecs - year;
- NSTimeInterval tranSecs = lowerBound; // time at a transition; may be > endSecs
-
- NSDate *nextDate = [NSDate dateWithTimeIntervalSince1970:nextSecs];
- nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
- if (nextDate != nil
- && (tranSecs = [nextDate timeIntervalSince1970]) < endSecs) {
- // There's a transition within the last year before endSecs:
- nextSecs = tranSecs;
- } else {
- // Need to start our search earlier:
- nextDate = [NSDate dateWithTimeIntervalSince1970:lowerBound];
- nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
- if (nextDate != nil) {
- NSTimeInterval lateSecs = nextSecs;
- nextSecs = [nextDate timeIntervalSince1970];
- Q_ASSERT(nextSecs <= endSecs - year || nextSecs == tranSecs);
- /*
- We're looking at the first ever transition for our zone, at
- nextSecs (and our zone *does* have at least one transition). If
- it's later than endSecs - year, then we must have found it on the
- initial check and therefore set tranSecs to the same transition
- time (which, we can infer here, is >= endSecs). In this case, we
- won't enter the binary-chop loop, below.
-
- In the loop, nextSecs < lateSecs < endSecs: we have a transition
- at nextSecs and there is no transition between lateSecs and
- endSecs. The loop narrows the interval between nextSecs and
- lateSecs by looking for a transition after their mid-point; if it
- finds one < endSecs, nextSecs moves to this transition; otherwise,
- lateSecs moves to the mid-point. This soon enough narrows the gap
- to within a year, after which walking forward one transition at a
- time (the "Wind through" loop, below) is good enough.
- */
-
- // Binary chop to within a year of last transition before endSecs:
- while (nextSecs + year < lateSecs) {
- // Careful about overflow, not fussy about rounding errors:
- NSTimeInterval middle = nextSecs / 2 + lateSecs / 2;
- NSDate *split = [NSDate dateWithTimeIntervalSince1970:middle];
- split = [m_nstz nextDaylightSavingTimeTransitionAfterDate:split];
- if (split != nil
- && (tranSecs = [split timeIntervalSince1970]) < endSecs) {
- nextDate = split;
- nextSecs = tranSecs;
- } else {
- lateSecs = middle;
- }
- }
- Q_ASSERT(nextDate != nil);
- // ... and nextSecs < endSecs unless first transition ever was >= endSecs.
- } // else: we have no data - prevSecs is still endSecs, nextDate is still nil
- }
- // Either nextDate is nil or nextSecs is at its transition.
-
- // Wind through remaining transitions (spanning at most a year), one at a time:
- while (nextDate != nil && nextSecs < endSecs) {
- prevSecs = nextSecs;
- nextDate = [m_nstz nextDaylightSavingTimeTransitionAfterDate:nextDate];
- nextSecs = [nextDate timeIntervalSince1970];
- if (nextSecs <= prevSecs) // presumably no later data available
- break;
- }
- if (prevSecs < endSecs) // i.e. we did make it into that while loop
- return data(qint64(prevSecs * 1e3));
-
- // No transition data; or first transition later than requested time.
- return invalidData();
-}
-
-QByteArray QMacTimeZonePrivate::systemTimeZoneId() const
-{
- // Reset the cached system tz then return the name
- [NSTimeZone resetSystemTimeZone];
- return QString::fromNSString([[NSTimeZone systemTimeZone] name]).toUtf8();
-}
-
-QList<QByteArray> QMacTimeZonePrivate::availableTimeZoneIds() const
-{
- NSEnumerator *enumerator = [[NSTimeZone knownTimeZoneNames] objectEnumerator];
- QByteArray tzid = QString::fromNSString([enumerator nextObject]).toUtf8();
-
- QList<QByteArray> list;
- while (!tzid.isEmpty()) {
- list << tzid;
- tzid = QString::fromNSString([enumerator nextObject]).toUtf8();
- }
-
- std::sort(list.begin(), list.end());
- list.erase(std::unique(list.begin(), list.end()), list.end());
-
- return list;
-}
-
-NSTimeZone *QMacTimeZonePrivate::nsTimeZone() const
-{
- return m_nstz;
-}
-
-QT_END_NAMESPACE
diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h
deleted file mode 100644
index b5e9286f6a..0000000000
--- a/src/corelib/tools/qtimezoneprivate_p.h
+++ /dev/null
@@ -1,493 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 John Layt <jlayt@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QTIMEZONEPRIVATE_P_H
-#define QTIMEZONEPRIVATE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of internal files. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qtimezone.h"
-#include "qlocale_p.h"
-#include "qvector.h"
-
-#if QT_CONFIG(icu)
-#include <unicode/ucal.h>
-#endif
-
-#ifdef Q_OS_DARWIN
-Q_FORWARD_DECLARE_OBJC_CLASS(NSTimeZone);
-#endif // Q_OS_DARWIN
-
-#ifdef Q_OS_WIN
-#include <qt_windows.h>
-#endif // Q_OS_WIN
-
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
-#include <QtCore/private/qjni_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class Q_AUTOTEST_EXPORT QTimeZonePrivate : public QSharedData
-{
-public:
- //Version of QTimeZone::OffsetData struct using msecs for efficiency
- struct Data {
- QString abbreviation;
- qint64 atMSecsSinceEpoch;
- int offsetFromUtc;
- int standardTimeOffset;
- int daylightTimeOffset;
- };
- typedef QVector<Data> DataList;
-
- // Create null time zone
- QTimeZonePrivate();
- QTimeZonePrivate(const QTimeZonePrivate &other);
- virtual ~QTimeZonePrivate();
-
- virtual QTimeZonePrivate *clone() const;
-
- bool operator==(const QTimeZonePrivate &other) const;
- bool operator!=(const QTimeZonePrivate &other) const;
-
- bool isValid() const;
-
- QByteArray id() const;
- virtual QLocale::Country country() const;
- virtual QString comment() const;
-
- virtual QString displayName(qint64 atMSecsSinceEpoch,
- QTimeZone::NameType nameType,
- const QLocale &locale) const;
- virtual QString displayName(QTimeZone::TimeType timeType,
- QTimeZone::NameType nameType,
- const QLocale &locale) const;
- virtual QString abbreviation(qint64 atMSecsSinceEpoch) const;
-
- virtual int offsetFromUtc(qint64 atMSecsSinceEpoch) const;
- virtual int standardTimeOffset(qint64 atMSecsSinceEpoch) const;
- virtual int daylightTimeOffset(qint64 atMSecsSinceEpoch) const;
-
- virtual bool hasDaylightTime() const;
- virtual bool isDaylightTime(qint64 atMSecsSinceEpoch) const;
-
- virtual Data data(qint64 forMSecsSinceEpoch) const;
- Data dataForLocalTime(qint64 forLocalMSecs, int hint) const;
-
- virtual bool hasTransitions() const;
- virtual Data nextTransition(qint64 afterMSecsSinceEpoch) const;
- virtual Data previousTransition(qint64 beforeMSecsSinceEpoch) const;
- DataList transitions(qint64 fromMSecsSinceEpoch, qint64 toMSecsSinceEpoch) const;
-
- virtual QByteArray systemTimeZoneId() const;
-
- virtual bool isTimeZoneIdAvailable(const QByteArray &ianaId) const;
- virtual QList<QByteArray> availableTimeZoneIds() const;
- virtual QList<QByteArray> availableTimeZoneIds(QLocale::Country country) const;
- virtual QList<QByteArray> availableTimeZoneIds(int utcOffset) const;
-
- virtual void serialize(QDataStream &ds) const;
-
- // Static Utility Methods
- static inline qint64 maxMSecs() { return std::numeric_limits<qint64>::max(); }
- static inline qint64 minMSecs() { return std::numeric_limits<qint64>::min() + 1; }
- static inline qint64 invalidMSecs() { return std::numeric_limits<qint64>::min(); }
- static inline qint64 invalidSeconds() { return std::numeric_limits<int>::min(); }
- static Data invalidData();
- static QTimeZone::OffsetData invalidOffsetData();
- static QTimeZone::OffsetData toOffsetData(const Data &data);
- static bool isValidId(const QByteArray &ianaId);
- static QString isoOffsetFormat(int offsetFromUtc);
-
- static QByteArray ianaIdToWindowsId(const QByteArray &ianaId);
- static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId);
- static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId,
- QLocale::Country country);
- static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId);
- static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId,
- QLocale::Country country);
-
- // returns "UTC" QString and QByteArray
- Q_REQUIRED_RESULT static inline QString utcQString()
- {
- return QStringLiteral("UTC");
- }
-
- Q_REQUIRED_RESULT static inline QByteArray utcQByteArray()
- {
- return QByteArrayLiteral("UTC");
- }
-
-protected:
- QByteArray m_id;
-};
-Q_DECLARE_TYPEINFO(QTimeZonePrivate::Data, Q_MOVABLE_TYPE);
-
-template<> QTimeZonePrivate *QSharedDataPointer<QTimeZonePrivate>::clone();
-
-class Q_AUTOTEST_EXPORT QUtcTimeZonePrivate final : public QTimeZonePrivate
-{
-public:
- // Create default UTC time zone
- QUtcTimeZonePrivate();
- // Create named time zone
- QUtcTimeZonePrivate(const QByteArray &utcId);
- // Create offset from UTC
- QUtcTimeZonePrivate(int offsetSeconds);
- // Create custom offset from UTC
- QUtcTimeZonePrivate(const QByteArray &zoneId, int offsetSeconds, const QString &name,
- const QString &abbreviation, QLocale::Country country,
- const QString &comment);
- QUtcTimeZonePrivate(const QUtcTimeZonePrivate &other);
- virtual ~QUtcTimeZonePrivate();
-
- QUtcTimeZonePrivate *clone() const override;
-
- Data data(qint64 forMSecsSinceEpoch) const override;
-
- QLocale::Country country() const override;
- QString comment() const override;
-
- QString displayName(QTimeZone::TimeType timeType,
- QTimeZone::NameType nameType,
- const QLocale &locale) const override;
- QString abbreviation(qint64 atMSecsSinceEpoch) const override;
-
- int standardTimeOffset(qint64 atMSecsSinceEpoch) const override;
- int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override;
-
- QByteArray systemTimeZoneId() const override;
-
- bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override;
- QList<QByteArray> availableTimeZoneIds() const override;
- QList<QByteArray> availableTimeZoneIds(QLocale::Country country) const override;
- QList<QByteArray> availableTimeZoneIds(int utcOffset) const override;
-
- void serialize(QDataStream &ds) const override;
-
-private:
- void init(const QByteArray &zoneId);
- void init(const QByteArray &zoneId, int offsetSeconds, const QString &name,
- const QString &abbreviation, QLocale::Country country,
- const QString &comment);
-
- QString m_name;
- QString m_abbreviation;
- QString m_comment;
- QLocale::Country m_country;
- int m_offsetFromUtc;
-};
-
-#if QT_CONFIG(icu)
-class Q_AUTOTEST_EXPORT QIcuTimeZonePrivate final : public QTimeZonePrivate
-{
-public:
- // Create default time zone
- QIcuTimeZonePrivate();
- // Create named time zone
- QIcuTimeZonePrivate(const QByteArray &ianaId);
- QIcuTimeZonePrivate(const QIcuTimeZonePrivate &other);
- ~QIcuTimeZonePrivate();
-
- QIcuTimeZonePrivate *clone() const override;
-
- QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType,
- const QLocale &locale) const override;
- QString abbreviation(qint64 atMSecsSinceEpoch) const override;
-
- int offsetFromUtc(qint64 atMSecsSinceEpoch) const override;
- int standardTimeOffset(qint64 atMSecsSinceEpoch) const override;
- int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override;
-
- bool hasDaylightTime() const override;
- bool isDaylightTime(qint64 atMSecsSinceEpoch) const override;
-
- Data data(qint64 forMSecsSinceEpoch) const override;
-
- bool hasTransitions() const override;
- Data nextTransition(qint64 afterMSecsSinceEpoch) const override;
- Data previousTransition(qint64 beforeMSecsSinceEpoch) const override;
-
- QByteArray systemTimeZoneId() const override;
-
- QList<QByteArray> availableTimeZoneIds() const override;
- QList<QByteArray> availableTimeZoneIds(QLocale::Country country) const override;
- QList<QByteArray> availableTimeZoneIds(int offsetFromUtc) const override;
-
-private:
- void init(const QByteArray &ianaId);
-
- UCalendar *m_ucal;
-};
-#endif
-
-#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_EMBEDDED))
-struct QTzTransitionTime
-{
- qint64 atMSecsSinceEpoch;
- quint8 ruleIndex;
-};
-Q_DECLARE_TYPEINFO(QTzTransitionTime, Q_PRIMITIVE_TYPE);
-struct QTzTransitionRule
-{
- int stdOffset;
- int dstOffset;
- quint8 abbreviationIndex;
-};
-Q_DECLARE_TYPEINFO(QTzTransitionRule, Q_PRIMITIVE_TYPE);
-Q_DECL_CONSTEXPR inline bool operator==(const QTzTransitionRule &lhs, const QTzTransitionRule &rhs) noexcept
-{ return lhs.stdOffset == rhs.stdOffset && lhs.dstOffset == rhs.dstOffset && lhs.abbreviationIndex == rhs.abbreviationIndex; }
-Q_DECL_CONSTEXPR inline bool operator!=(const QTzTransitionRule &lhs, const QTzTransitionRule &rhs) noexcept
-{ return !operator==(lhs, rhs); }
-
-class Q_AUTOTEST_EXPORT QTzTimeZonePrivate final : public QTimeZonePrivate
-{
- QTzTimeZonePrivate(const QTzTimeZonePrivate &) = default;
-public:
- // Create default time zone
- QTzTimeZonePrivate();
- // Create named time zone
- QTzTimeZonePrivate(const QByteArray &ianaId);
- ~QTzTimeZonePrivate();
-
- QTzTimeZonePrivate *clone() const override;
-
- QLocale::Country country() const override;
- QString comment() const override;
-
- QString displayName(qint64 atMSecsSinceEpoch,
- QTimeZone::NameType nameType,
- const QLocale &locale) const override;
- QString displayName(QTimeZone::TimeType timeType,
- QTimeZone::NameType nameType,
- const QLocale &locale) const override;
- QString abbreviation(qint64 atMSecsSinceEpoch) const override;
-
- int offsetFromUtc(qint64 atMSecsSinceEpoch) const override;
- int standardTimeOffset(qint64 atMSecsSinceEpoch) const override;
- int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override;
-
- bool hasDaylightTime() const override;
- bool isDaylightTime(qint64 atMSecsSinceEpoch) const override;
-
- Data data(qint64 forMSecsSinceEpoch) const override;
-
- bool hasTransitions() const override;
- Data nextTransition(qint64 afterMSecsSinceEpoch) const override;
- Data previousTransition(qint64 beforeMSecsSinceEpoch) const override;
-
- QByteArray systemTimeZoneId() const override;
-
- bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override;
- QList<QByteArray> availableTimeZoneIds() const override;
- QList<QByteArray> availableTimeZoneIds(QLocale::Country country) const override;
-
-private:
- void init(const QByteArray &ianaId);
- QVector<QTimeZonePrivate::Data> getPosixTransitions(qint64 msNear) const;
-
- Data dataForTzTransition(QTzTransitionTime tran) const;
- QVector<QTzTransitionTime> m_tranTimes;
- QVector<QTzTransitionRule> m_tranRules;
- QList<QByteArray> m_abbreviations;
-#if QT_CONFIG(icu)
- mutable QSharedDataPointer<QTimeZonePrivate> m_icu;
-#endif
- QByteArray m_posixRule;
-};
-#endif // Q_OS_UNIX
-
-#ifdef Q_OS_MAC
-class Q_AUTOTEST_EXPORT QMacTimeZonePrivate final : public QTimeZonePrivate
-{
-public:
- // Create default time zone
- QMacTimeZonePrivate();
- // Create named time zone
- QMacTimeZonePrivate(const QByteArray &ianaId);
- QMacTimeZonePrivate(const QMacTimeZonePrivate &other);
- ~QMacTimeZonePrivate();
-
- QMacTimeZonePrivate *clone() const override;
-
- QString comment() const override;
-
- QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType,
- const QLocale &locale) const override;
- QString abbreviation(qint64 atMSecsSinceEpoch) const override;
-
- int offsetFromUtc(qint64 atMSecsSinceEpoch) const override;
- int standardTimeOffset(qint64 atMSecsSinceEpoch) const override;
- int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override;
-
- bool hasDaylightTime() const override;
- bool isDaylightTime(qint64 atMSecsSinceEpoch) const override;
-
- Data data(qint64 forMSecsSinceEpoch) const override;
-
- bool hasTransitions() const override;
- Data nextTransition(qint64 afterMSecsSinceEpoch) const override;
- Data previousTransition(qint64 beforeMSecsSinceEpoch) const override;
-
- QByteArray systemTimeZoneId() const override;
-
- QList<QByteArray> availableTimeZoneIds() const override;
-
- NSTimeZone *nsTimeZone() const;
-
-private:
- void init(const QByteArray &zoneId);
-
- NSTimeZone *m_nstz;
-};
-#endif // Q_OS_MAC
-
-#ifdef Q_OS_WIN
-class Q_AUTOTEST_EXPORT QWinTimeZonePrivate final : public QTimeZonePrivate
-{
-public:
- struct QWinTransitionRule {
- int startYear;
- int standardTimeBias;
- int daylightTimeBias;
- SYSTEMTIME standardTimeRule;
- SYSTEMTIME daylightTimeRule;
- };
-
- // Create default time zone
- QWinTimeZonePrivate();
- // Create named time zone
- QWinTimeZonePrivate(const QByteArray &ianaId);
- QWinTimeZonePrivate(const QWinTimeZonePrivate &other);
- ~QWinTimeZonePrivate();
-
- QWinTimeZonePrivate *clone() const override;
-
- QString comment() const override;
-
- QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType,
- const QLocale &locale) const override;
- QString abbreviation(qint64 atMSecsSinceEpoch) const override;
-
- int offsetFromUtc(qint64 atMSecsSinceEpoch) const override;
- int standardTimeOffset(qint64 atMSecsSinceEpoch) const override;
- int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override;
-
- bool hasDaylightTime() const override;
- bool isDaylightTime(qint64 atMSecsSinceEpoch) const override;
-
- Data data(qint64 forMSecsSinceEpoch) const override;
-
- bool hasTransitions() const override;
- Data nextTransition(qint64 afterMSecsSinceEpoch) const override;
- Data previousTransition(qint64 beforeMSecsSinceEpoch) const override;
-
- QByteArray systemTimeZoneId() const override;
-
- QList<QByteArray> availableTimeZoneIds() const override;
-
-private:
- void init(const QByteArray &ianaId);
- QTimeZonePrivate::Data ruleToData(const QWinTransitionRule &rule, qint64 atMSecsSinceEpoch,
- QTimeZone::TimeType type, bool fakeDst = false) const;
-
- QByteArray m_windowsId;
- QString m_displayName;
- QString m_standardName;
- QString m_daylightName;
- QList<QWinTransitionRule> m_tranRules;
-};
-#endif // Q_OS_WIN
-
-#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
-class QAndroidTimeZonePrivate final : public QTimeZonePrivate
-{
-public:
- // Create default time zone
- QAndroidTimeZonePrivate();
- // Create named time zone
- QAndroidTimeZonePrivate(const QByteArray &ianaId);
- QAndroidTimeZonePrivate(const QAndroidTimeZonePrivate &other);
- ~QAndroidTimeZonePrivate();
-
- QAndroidTimeZonePrivate *clone() const override;
-
- QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType,
- const QLocale &locale) const override;
- QString abbreviation(qint64 atMSecsSinceEpoch) const override;
-
- int offsetFromUtc(qint64 atMSecsSinceEpoch) const override;
- int standardTimeOffset(qint64 atMSecsSinceEpoch) const override;
- int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override;
-
- bool hasDaylightTime() const override;
- bool isDaylightTime(qint64 atMSecsSinceEpoch) const override;
-
- Data data(qint64 forMSecsSinceEpoch) const override;
-
- bool hasTransitions() const override;
- Data nextTransition(qint64 afterMSecsSinceEpoch) const override;
- Data previousTransition(qint64 beforeMSecsSinceEpoch) const override;
-
- QByteArray systemTimeZoneId() const override;
-
- QList<QByteArray> availableTimeZoneIds() const override;
-
-private:
- void init(const QByteArray &zoneId);
-
- QJNIObjectPrivate androidTimeZone;
-
-};
-#endif // Q_OS_ANDROID
-
-QT_END_NAMESPACE
-
-#endif // QTIMEZONEPRIVATE_P_H
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
deleted file mode 100644
index f5440799ab..0000000000
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ /dev/null
@@ -1,1155 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 John Layt <jlayt@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtimezone.h"
-#include "qtimezoneprivate_p.h"
-#include "qdatetime_p.h" // ### Qt 5.14: remove once YearRange is on QDateTime
-
-#include <QtCore/QFile>
-#include <QtCore/QHash>
-#include <QtCore/QDataStream>
-#include <QtCore/QDateTime>
-
-#include <qdebug.h>
-
-#include "qlocale_tools_p.h"
-
-#include <algorithm>
-
-QT_BEGIN_NAMESPACE
-
-/*
- Private
-
- tz file implementation
-*/
-
-struct QTzTimeZone {
- QLocale::Country country;
- QByteArray comment;
-};
-
-// Define as a type as Q_GLOBAL_STATIC doesn't like it
-typedef QHash<QByteArray, QTzTimeZone> QTzTimeZoneHash;
-
-// Parse zone.tab table, assume lists all installed zones, if not will need to read directories
-static QTzTimeZoneHash loadTzTimeZones()
-{
- QString path = QStringLiteral("/usr/share/zoneinfo/zone.tab");
- if (!QFile::exists(path))
- path = QStringLiteral("/usr/lib/zoneinfo/zone.tab");
-
- QFile tzif(path);
- if (!tzif.open(QIODevice::ReadOnly))
- return QTzTimeZoneHash();
-
- QTzTimeZoneHash zonesHash;
- // TODO QTextStream inefficient, replace later
- QTextStream ts(&tzif);
- while (!ts.atEnd()) {
- const QString line = ts.readLine();
- // Comment lines are prefixed with a #
- if (!line.isEmpty() && line.at(0) != '#') {
- // Data rows are tab-separated columns Region, Coordinates, ID, Optional Comments
- const auto parts = line.splitRef(QLatin1Char('\t'));
- QTzTimeZone zone;
- zone.country = QLocalePrivate::codeToCountry(parts.at(0));
- if (parts.size() > 3)
- zone.comment = parts.at(3).toUtf8();
- zonesHash.insert(parts.at(2).toUtf8(), zone);
- }
- }
- return zonesHash;
-}
-
-// Hash of available system tz files as loaded by loadTzTimeZones()
-Q_GLOBAL_STATIC_WITH_ARGS(const QTzTimeZoneHash, tzZones, (loadTzTimeZones()));
-
-/*
- The following is copied and modified from tzfile.h which is in the public domain.
- Copied as no compatibility guarantee and is never system installed.
- See https://github.com/eggert/tz/blob/master/tzfile.h
-*/
-
-#define TZ_MAGIC "TZif"
-#define TZ_MAX_TIMES 1200
-#define TZ_MAX_TYPES 256 // Limited by what (unsigned char)'s can hold
-#define TZ_MAX_CHARS 50 // Maximum number of abbreviation characters
-#define TZ_MAX_LEAPS 50 // Maximum number of leap second corrections
-
-struct QTzHeader {
- char tzh_magic[4]; // TZ_MAGIC
- char tzh_version; // '\0' or '2' as of 2005
- char tzh_reserved[15]; // reserved--must be zero
- quint32 tzh_ttisgmtcnt; // number of trans. time flags
- quint32 tzh_ttisstdcnt; // number of trans. time flags
- quint32 tzh_leapcnt; // number of leap seconds
- quint32 tzh_timecnt; // number of transition times
- quint32 tzh_typecnt; // number of local time types
- quint32 tzh_charcnt; // number of abbr. chars
-};
-
-struct QTzTransition {
- qint64 tz_time; // Transition time
- quint8 tz_typeind; // Type Index
-};
-Q_DECLARE_TYPEINFO(QTzTransition, Q_PRIMITIVE_TYPE);
-
-struct QTzType {
- int tz_gmtoff; // UTC offset in seconds
- bool tz_isdst; // Is DST
- quint8 tz_abbrind; // abbreviation list index
-};
-Q_DECLARE_TYPEINFO(QTzType, Q_PRIMITIVE_TYPE);
-
-
-// TZ File parsing
-
-static QTzHeader parseTzHeader(QDataStream &ds, bool *ok)
-{
- QTzHeader hdr;
- quint8 ch;
- *ok = false;
-
- // Parse Magic, 4 bytes
- ds.readRawData(hdr.tzh_magic, 4);
-
- if (memcmp(hdr.tzh_magic, TZ_MAGIC, 4) != 0 || ds.status() != QDataStream::Ok)
- return hdr;
-
- // Parse Version, 1 byte, before 2005 was '\0', since 2005 a '2', since 2013 a '3'
- ds >> ch;
- hdr.tzh_version = ch;
- if (ds.status() != QDataStream::Ok
- || (hdr.tzh_version != '2' && hdr.tzh_version != '\0' && hdr.tzh_version != '3')) {
- return hdr;
- }
-
- // Parse reserved space, 15 bytes
- ds.readRawData(hdr.tzh_reserved, 15);
- if (ds.status() != QDataStream::Ok)
- return hdr;
-
- // Parse rest of header, 6 x 4-byte transition counts
- ds >> hdr.tzh_ttisgmtcnt >> hdr.tzh_ttisstdcnt >> hdr.tzh_leapcnt >> hdr.tzh_timecnt
- >> hdr.tzh_typecnt >> hdr.tzh_charcnt;
-
- // Check defined maximums
- if (ds.status() != QDataStream::Ok
- || hdr.tzh_timecnt > TZ_MAX_TIMES
- || hdr.tzh_typecnt > TZ_MAX_TYPES
- || hdr.tzh_charcnt > TZ_MAX_CHARS
- || hdr.tzh_leapcnt > TZ_MAX_LEAPS
- || hdr.tzh_ttisgmtcnt > hdr.tzh_typecnt
- || hdr.tzh_ttisstdcnt > hdr.tzh_typecnt) {
- return hdr;
- }
-
- *ok = true;
- return hdr;
-}
-
-static QVector<QTzTransition> parseTzTransitions(QDataStream &ds, int tzh_timecnt, bool longTran)
-{
- QVector<QTzTransition> transitions(tzh_timecnt);
-
- if (longTran) {
- // Parse tzh_timecnt x 8-byte transition times
- for (int i = 0; i < tzh_timecnt && ds.status() == QDataStream::Ok; ++i) {
- ds >> transitions[i].tz_time;
- if (ds.status() != QDataStream::Ok)
- transitions.resize(i);
- }
- } else {
- // Parse tzh_timecnt x 4-byte transition times
- qint32 val;
- for (int i = 0; i < tzh_timecnt && ds.status() == QDataStream::Ok; ++i) {
- ds >> val;
- transitions[i].tz_time = val;
- if (ds.status() != QDataStream::Ok)
- transitions.resize(i);
- }
- }
-
- // Parse tzh_timecnt x 1-byte transition type index
- for (int i = 0; i < tzh_timecnt && ds.status() == QDataStream::Ok; ++i) {
- quint8 typeind;
- ds >> typeind;
- if (ds.status() == QDataStream::Ok)
- transitions[i].tz_typeind = typeind;
- }
-
- return transitions;
-}
-
-static QVector<QTzType> parseTzTypes(QDataStream &ds, int tzh_typecnt)
-{
- QVector<QTzType> types(tzh_typecnt);
-
- // Parse tzh_typecnt x transition types
- for (int i = 0; i < tzh_typecnt && ds.status() == QDataStream::Ok; ++i) {
- QTzType &type = types[i];
- // Parse UTC Offset, 4 bytes
- ds >> type.tz_gmtoff;
- // Parse Is DST flag, 1 byte
- if (ds.status() == QDataStream::Ok)
- ds >> type.tz_isdst;
- // Parse Abbreviation Array Index, 1 byte
- if (ds.status() == QDataStream::Ok)
- ds >> type.tz_abbrind;
- if (ds.status() != QDataStream::Ok)
- types.resize(i);
- }
-
- return types;
-}
-
-static QMap<int, QByteArray> parseTzAbbreviations(QDataStream &ds, int tzh_charcnt, const QVector<QTzType> &types)
-{
- // Parse the abbreviation list which is tzh_charcnt long with '\0' separated strings. The
- // QTzType.tz_abbrind index points to the first char of the abbreviation in the array, not the
- // occurrence in the list. It can also point to a partial string so we need to use the actual typeList
- // index values when parsing. By using a map with tz_abbrind as ordered key we get both index
- // methods in one data structure and can convert the types afterwards.
- QMap<int, QByteArray> map;
- quint8 ch;
- QByteArray input;
- // First parse the full abbrev string
- for (int i = 0; i < tzh_charcnt && ds.status() == QDataStream::Ok; ++i) {
- ds >> ch;
- if (ds.status() == QDataStream::Ok)
- input.append(char(ch));
- else
- return map;
- }
- // Then extract all the substrings pointed to by types
- for (const QTzType &type : types) {
- QByteArray abbrev;
- for (int i = type.tz_abbrind; input.at(i) != '\0'; ++i)
- abbrev.append(input.at(i));
- // Have reached end of an abbreviation, so add to map
- map[type.tz_abbrind] = abbrev;
- }
- return map;
-}
-
-static void parseTzLeapSeconds(QDataStream &ds, int tzh_leapcnt, bool longTran)
-{
- // Parse tzh_leapcnt x pairs of leap seconds
- // We don't use leap seconds, so only read and don't store
- qint32 val;
- if (longTran) {
- // v2 file format, each entry is 12 bytes long
- qint64 time;
- for (int i = 0; i < tzh_leapcnt && ds.status() == QDataStream::Ok; ++i) {
- // Parse Leap Occurrence Time, 8 bytes
- ds >> time;
- // Parse Leap Seconds To Apply, 4 bytes
- if (ds.status() == QDataStream::Ok)
- ds >> val;
- }
- } else {
- // v0 file format, each entry is 8 bytes long
- for (int i = 0; i < tzh_leapcnt && ds.status() == QDataStream::Ok; ++i) {
- // Parse Leap Occurrence Time, 4 bytes
- ds >> val;
- // Parse Leap Seconds To Apply, 4 bytes
- if (ds.status() == QDataStream::Ok)
- ds >> val;
- }
- }
-}
-
-static QVector<QTzType> parseTzIndicators(QDataStream &ds, const QVector<QTzType> &types, int tzh_ttisstdcnt, int tzh_ttisgmtcnt)
-{
- QVector<QTzType> result = types;
- bool temp;
- /*
- Scan and discard indicators.
-
- These indicators are only of use (by the date program) when "handling
- POSIX-style time zone environment variables". The flags here say whether
- the *specification* of the zone gave the time in UTC, local standard time
- or local wall time; but whatever was specified has been digested for us,
- already, by the zone-info compiler (zic), so that the tz_time values read
- from the file (by parseTzTransitions) are all in UTC.
- */
-
- // Scan tzh_ttisstdcnt x 1-byte standard/wall indicators
- for (int i = 0; i < tzh_ttisstdcnt && ds.status() == QDataStream::Ok; ++i)
- ds >> temp;
-
- // Scan tzh_ttisgmtcnt x 1-byte UTC/local indicators
- for (int i = 0; i < tzh_ttisgmtcnt && ds.status() == QDataStream::Ok; ++i)
- ds >> temp;
-
- return result;
-}
-
-static QByteArray parseTzPosixRule(QDataStream &ds)
-{
- // Parse POSIX rule, variable length '\n' enclosed
- QByteArray rule;
-
- quint8 ch;
- ds >> ch;
- if (ch != '\n' || ds.status() != QDataStream::Ok)
- return rule;
- ds >> ch;
- while (ch != '\n' && ds.status() == QDataStream::Ok) {
- rule.append((char)ch);
- ds >> ch;
- }
-
- return rule;
-}
-
-static QDate calculateDowDate(int year, int month, int dayOfWeek, int week)
-{
- QDate date(year, month, 1);
- int startDow = date.dayOfWeek();
- if (startDow <= dayOfWeek)
- date = date.addDays(dayOfWeek - startDow - 7);
- else
- date = date.addDays(dayOfWeek - startDow);
- date = date.addDays(week * 7);
- while (date.month() != month)
- date = date.addDays(-7);
- return date;
-}
-
-static QDate calculatePosixDate(const QByteArray &dateRule, int year)
-{
- // Can start with M, J, or a digit
- if (dateRule.at(0) == 'M') {
- // nth week in month format "Mmonth.week.dow"
- QList<QByteArray> dateParts = dateRule.split('.');
- int month = dateParts.at(0).mid(1).toInt();
- int week = dateParts.at(1).toInt();
- int dow = dateParts.at(2).toInt();
- if (dow == 0)
- ++dow;
- return calculateDowDate(year, month, dow, week);
- } else if (dateRule.at(0) == 'J') {
- // Day of Year ignores Feb 29
- int doy = dateRule.mid(1).toInt();
- QDate date = QDate(year, 1, 1).addDays(doy - 1);
- if (QDate::isLeapYear(date.year()))
- date = date.addDays(-1);
- return date;
- } else {
- // Day of Year includes Feb 29
- int doy = dateRule.toInt();
- return QDate(year, 1, 1).addDays(doy - 1);
- }
-}
-
-// returns the time in seconds, INT_MIN if we failed to parse
-static int parsePosixTime(const char *begin, const char *end)
-{
- // Format "hh[:mm[:ss]]"
- int hour, min = 0, sec = 0;
-
- // Note that the calls to qstrtoll do *not* check the end pointer, which
- // means they proceed until they find a non-digit. We check that we're
- // still in range at the end, but we may have read from past end. It's the
- // caller's responsibility to ensure that begin is part of a
- // null-terminated string.
-
- bool ok = false;
- hour = qstrtoll(begin, &begin, 10, &ok);
- if (!ok || hour < 0)
- return INT_MIN;
- if (begin < end && *begin == ':') {
- // minutes
- ++begin;
- min = qstrtoll(begin, &begin, 10, &ok);
- if (!ok || min < 0)
- return INT_MIN;
-
- if (begin < end && *begin == ':') {
- // seconds
- ++begin;
- sec = qstrtoll(begin, &begin, 10, &ok);
- if (!ok || sec < 0)
- return INT_MIN;
- }
- }
-
- // we must have consumed everything
- if (begin != end)
- return INT_MIN;
-
- return (hour * 60 + min) * 60 + sec;
-}
-
-static QTime parsePosixTransitionTime(const QByteArray &timeRule)
-{
- // Format "hh[:mm[:ss]]"
- int value = parsePosixTime(timeRule.constBegin(), timeRule.constEnd());
- if (value == INT_MIN) {
- // if we failed to parse, return 02:00
- return QTime(2, 0, 0);
- }
- return QTime::fromMSecsSinceStartOfDay(value * 1000);
-}
-
-static int parsePosixOffset(const char *begin, const char *end)
-{
- // Format "[+|-]hh[:mm[:ss]]"
- // note that the sign is inverted because POSIX counts in hours West of GMT
- bool negate = true;
- if (*begin == '+') {
- ++begin;
- } else if (*begin == '-') {
- negate = false;
- ++begin;
- }
-
- int value = parsePosixTime(begin, end);
- if (value == INT_MIN)
- return value;
- return negate ? -value : value;
-}
-
-static inline bool asciiIsLetter(char ch)
-{
- ch |= 0x20; // lowercases if it is a letter, otherwise just corrupts ch
- return ch >= 'a' && ch <= 'z';
-}
-
-namespace {
-
-struct PosixZone
-{
- enum {
- InvalidOffset = INT_MIN,
- };
-
- QString name;
- int offset;
-
- static PosixZone invalid() { return {QString(), InvalidOffset}; }
- static PosixZone parse(const char *&pos, const char *end);
-
- bool hasValidOffset() const noexcept { return offset != InvalidOffset; }
-};
-
-} // unnamed namespace
-
-// Returns the zone name, the offset (in seconds) and advances \a begin to
-// where the parsing ended. Returns a zone of INT_MIN in case an offset
-// couldn't be read.
-PosixZone PosixZone::parse(const char *&pos, const char *end)
-{
- static const char offsetChars[] = "0123456789:";
-
- const char *nameBegin = pos;
- const char *nameEnd;
- Q_ASSERT(pos < end);
-
- if (*pos == '<') {
- nameBegin = pos + 1; // skip the '<'
- nameEnd = nameBegin;
- while (nameEnd < end && *nameEnd != '>') {
- // POSIX says only alphanumeric, but we allow anything
- ++nameEnd;
- }
- pos = nameEnd + 1; // skip the '>'
- } else {
- nameBegin = pos;
- nameEnd = nameBegin;
- while (nameEnd < end && asciiIsLetter(*nameEnd))
- ++nameEnd;
- pos = nameEnd;
- }
- if (nameEnd - nameBegin < 3)
- return invalid(); // name must be at least 3 characters long
-
- // zone offset, form [+-]hh:mm:ss
- const char *zoneBegin = pos;
- const char *zoneEnd = pos;
- if (zoneEnd < end && (zoneEnd[0] == '+' || zoneEnd[0] == '-'))
- ++zoneEnd;
- while (zoneEnd < end) {
- if (strchr(offsetChars, char(*zoneEnd)) == NULL)
- break;
- ++zoneEnd;
- }
-
- QString name = QString::fromUtf8(nameBegin, nameEnd - nameBegin);
- const int offset = zoneEnd > zoneBegin ? parsePosixOffset(zoneBegin, zoneEnd) : InvalidOffset;
- pos = zoneEnd;
- // UTC+hh:mm:ss or GMT+hh:mm:ss should be read as offsets from UTC, not as a
- // POSIX rule naming a zone as UTC or GMT and specifying a non-zero offset.
- if (offset != 0 && (name == QLatin1String("UTC") || name == QLatin1String("GMT")))
- return invalid();
- return {std::move(name), offset};
-}
-
-static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray &posixRule,
- int startYear, int endYear,
- qint64 lastTranMSecs)
-{
- QVector<QTimeZonePrivate::Data> result;
-
- // POSIX Format is like "TZ=CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00"
- // i.e. "std offset dst [offset],start[/time],end[/time]"
- // See the section about TZ at
- // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
- QList<QByteArray> parts = posixRule.split(',');
-
- PosixZone stdZone, dstZone = PosixZone::invalid();
- {
- const QByteArray &zoneinfo = parts.at(0);
- const char *begin = zoneinfo.constBegin();
-
- stdZone = PosixZone::parse(begin, zoneinfo.constEnd());
- if (!stdZone.hasValidOffset()) {
- stdZone.offset = 0; // reset to UTC if we failed to parse
- } else if (begin < zoneinfo.constEnd()) {
- dstZone = PosixZone::parse(begin, zoneinfo.constEnd());
- if (!dstZone.hasValidOffset()) {
- // if the dst offset isn't provided, it is 1 hour ahead of the standard offset
- dstZone.offset = stdZone.offset + (60 * 60);
- }
- }
- }
-
- // If only the name part then no transitions
- if (parts.count() == 1) {
- QTimeZonePrivate::Data data;
- data.atMSecsSinceEpoch = lastTranMSecs;
- data.offsetFromUtc = stdZone.offset;
- data.standardTimeOffset = stdZone.offset;
- data.daylightTimeOffset = 0;
- data.abbreviation = stdZone.name;
- result << data;
- return result;
- }
-
-
- // Get the std to dst transtion details
- QList<QByteArray> dstParts = parts.at(1).split('/');
- QByteArray dstDateRule = dstParts.at(0);
- QTime dstTime;
- if (dstParts.count() > 1)
- dstTime = parsePosixTransitionTime(dstParts.at(1));
- else
- dstTime = QTime(2, 0, 0);
-
- // Get the dst to std transtion details
- QList<QByteArray> stdParts = parts.at(2).split('/');
- QByteArray stdDateRule = stdParts.at(0);
- QTime stdTime;
- if (stdParts.count() > 1)
- stdTime = parsePosixTransitionTime(stdParts.at(1));
- else
- stdTime = QTime(2, 0, 0);
-
- // Limit year to the range QDateTime can represent:
- const int minYear = int(QDateTimePrivate::YearRange::First);
- const int maxYear = int(QDateTimePrivate::YearRange::Last);
- startYear = qBound(minYear, startYear, maxYear);
- endYear = qBound(minYear, endYear, maxYear);
- Q_ASSERT(startYear <= endYear);
-
- for (int year = startYear; year <= endYear; ++year) {
- QTimeZonePrivate::Data dstData;
- QDateTime dst(calculatePosixDate(dstDateRule, year), dstTime, Qt::UTC);
- dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (stdZone.offset * 1000);
- dstData.offsetFromUtc = dstZone.offset;
- dstData.standardTimeOffset = stdZone.offset;
- dstData.daylightTimeOffset = dstZone.offset - stdZone.offset;
- dstData.abbreviation = dstZone.name;
- QTimeZonePrivate::Data stdData;
- QDateTime std(calculatePosixDate(stdDateRule, year), stdTime, Qt::UTC);
- stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstZone.offset * 1000);
- stdData.offsetFromUtc = stdZone.offset;
- stdData.standardTimeOffset = stdZone.offset;
- stdData.daylightTimeOffset = 0;
- stdData.abbreviation = stdZone.name;
- // Part of maxYear will overflow (likewise for minYear, below):
- if (year == maxYear && (dstData.atMSecsSinceEpoch < 0 || stdData.atMSecsSinceEpoch < 0)) {
- if (dstData.atMSecsSinceEpoch > 0) {
- result << dstData;
- } else if (stdData.atMSecsSinceEpoch > 0) {
- result << stdData;
- }
- } else if (year < 1970) { // We ignore DST before the epoch.
- if (year > minYear || stdData.atMSecsSinceEpoch != QTimeZonePrivate::invalidMSecs())
- result << stdData;
- } else if (dst < std) {
- result << dstData << stdData;
- } else {
- result << stdData << dstData;
- }
- }
- return result;
-}
-
-// Create the system default time zone
-QTzTimeZonePrivate::QTzTimeZonePrivate()
-{
- init(systemTimeZoneId());
-}
-
-// Create a named time zone
-QTzTimeZonePrivate::QTzTimeZonePrivate(const QByteArray &ianaId)
-{
- init(ianaId);
-}
-
-QTzTimeZonePrivate::~QTzTimeZonePrivate()
-{
-}
-
-QTzTimeZonePrivate *QTzTimeZonePrivate::clone() const
-{
- return new QTzTimeZonePrivate(*this);
-}
-
-void QTzTimeZonePrivate::init(const QByteArray &ianaId)
-{
- QFile tzif;
- if (ianaId.isEmpty()) {
- // Open system tz
- tzif.setFileName(QStringLiteral("/etc/localtime"));
- if (!tzif.open(QIODevice::ReadOnly))
- return;
- } else {
- // Open named tz, try modern path first, if fails try legacy path
- tzif.setFileName(QLatin1String("/usr/share/zoneinfo/") + QString::fromLocal8Bit(ianaId));
- if (!tzif.open(QIODevice::ReadOnly)) {
- tzif.setFileName(QLatin1String("/usr/lib/zoneinfo/") + QString::fromLocal8Bit(ianaId));
- if (!tzif.open(QIODevice::ReadOnly)) {
- // ianaId may be a POSIX rule, taken from $TZ or /etc/TZ
- const QByteArray zoneInfo = ianaId.split(',').at(0);
- const char *begin = zoneInfo.constBegin();
- if (PosixZone::parse(begin, zoneInfo.constEnd()).hasValidOffset()
- && (begin == zoneInfo.constEnd()
- || PosixZone::parse(begin, zoneInfo.constEnd()).hasValidOffset())) {
- m_id = m_posixRule = ianaId;
- }
- return;
- }
- }
- }
-
- QDataStream ds(&tzif);
-
- // Parse the old version block of data
- bool ok = false;
- QTzHeader hdr = parseTzHeader(ds, &ok);
- if (!ok || ds.status() != QDataStream::Ok)
- return;
- QVector<QTzTransition> tranList = parseTzTransitions(ds, hdr.tzh_timecnt, false);
- if (ds.status() != QDataStream::Ok)
- return;
- QVector<QTzType> typeList = parseTzTypes(ds, hdr.tzh_typecnt);
- if (ds.status() != QDataStream::Ok)
- return;
- QMap<int, QByteArray> abbrevMap = parseTzAbbreviations(ds, hdr.tzh_charcnt, typeList);
- if (ds.status() != QDataStream::Ok)
- return;
- parseTzLeapSeconds(ds, hdr.tzh_leapcnt, false);
- if (ds.status() != QDataStream::Ok)
- return;
- typeList = parseTzIndicators(ds, typeList, hdr.tzh_ttisstdcnt, hdr.tzh_ttisgmtcnt);
- if (ds.status() != QDataStream::Ok)
- return;
-
- // If version 2 then parse the second block of data
- if (hdr.tzh_version == '2' || hdr.tzh_version == '3') {
- ok = false;
- QTzHeader hdr2 = parseTzHeader(ds, &ok);
- if (!ok || ds.status() != QDataStream::Ok)
- return;
- tranList = parseTzTransitions(ds, hdr2.tzh_timecnt, true);
- if (ds.status() != QDataStream::Ok)
- return;
- typeList = parseTzTypes(ds, hdr2.tzh_typecnt);
- if (ds.status() != QDataStream::Ok)
- return;
- abbrevMap = parseTzAbbreviations(ds, hdr2.tzh_charcnt, typeList);
- if (ds.status() != QDataStream::Ok)
- return;
- parseTzLeapSeconds(ds, hdr2.tzh_leapcnt, true);
- if (ds.status() != QDataStream::Ok)
- return;
- typeList = parseTzIndicators(ds, typeList, hdr2.tzh_ttisstdcnt, hdr2.tzh_ttisgmtcnt);
- if (ds.status() != QDataStream::Ok)
- return;
- m_posixRule = parseTzPosixRule(ds);
- if (ds.status() != QDataStream::Ok)
- return;
- }
-
- // Translate the TZ file into internal format
-
- // Translate the array index based tz_abbrind into list index
- const int size = abbrevMap.size();
- m_abbreviations.clear();
- m_abbreviations.reserve(size);
- QVector<int> abbrindList;
- abbrindList.reserve(size);
- for (auto it = abbrevMap.cbegin(), end = abbrevMap.cend(); it != end; ++it) {
- m_abbreviations.append(it.value());
- abbrindList.append(it.key());
- }
- for (int i = 0; i < typeList.size(); ++i)
- typeList[i].tz_abbrind = abbrindList.indexOf(typeList.at(i).tz_abbrind);
-
- // Offsets are stored as total offset, want to know separate UTC and DST offsets
- // so find the first non-dst transition to use as base UTC Offset
- int utcOffset = 0;
- for (const QTzTransition &tran : qAsConst(tranList)) {
- if (!typeList.at(tran.tz_typeind).tz_isdst) {
- utcOffset = typeList.at(tran.tz_typeind).tz_gmtoff;
- break;
- }
- }
-
- // Now for each transition time calculate and store our rule:
- const int tranCount = tranList.count();;
- m_tranTimes.reserve(tranCount);
- // The DST offset when in effect: usually stable, usually an hour:
- int lastDstOff = 3600;
- for (int i = 0; i < tranCount; i++) {
- const QTzTransition &tz_tran = tranList.at(i);
- QTzTransitionTime tran;
- QTzTransitionRule rule;
- const QTzType tz_type = typeList.at(tz_tran.tz_typeind);
-
- // Calculate the associated Rule
- if (!tz_type.tz_isdst) {
- utcOffset = tz_type.tz_gmtoff;
- } else if (Q_UNLIKELY(tz_type.tz_gmtoff != utcOffset + lastDstOff)) {
- /*
- This might be a genuine change in DST offset, but could also be
- DST starting at the same time as the standard offset changed. See
- if DST's end gives a more plausible utcOffset (i.e. one closer to
- the last we saw, or a simple whole hour):
- */
- // Standard offset inferred from net offset and expected DST offset:
- const int inferStd = tz_type.tz_gmtoff - lastDstOff; // != utcOffset
- for (int j = i + 1; j < tranCount; j++) {
- const QTzType new_type = typeList.at(tranList.at(j).tz_typeind);
- if (!new_type.tz_isdst) {
- const int newUtc = new_type.tz_gmtoff;
- if (newUtc == utcOffset) {
- // DST-end can't help us, avoid lots of messy checks.
- // else: See if the end matches the familiar DST offset:
- } else if (newUtc == inferStd) {
- utcOffset = newUtc;
- // else: let either end shift us to one hour as DST offset:
- } else if (tz_type.tz_gmtoff - 3600 == utcOffset) {
- // Start does it
- } else if (tz_type.tz_gmtoff - 3600 == newUtc) {
- utcOffset = newUtc; // End does it
- // else: prefer whichever end gives DST offset closer to
- // last, but consider any offset > 0 "closer" than any <= 0:
- } else if (newUtc < tz_type.tz_gmtoff
- ? (utcOffset >= tz_type.tz_gmtoff
- || qAbs(newUtc - inferStd) < qAbs(utcOffset - inferStd))
- : (utcOffset >= tz_type.tz_gmtoff
- && qAbs(newUtc - inferStd) < qAbs(utcOffset - inferStd))) {
- utcOffset = newUtc;
- }
- break;
- }
- }
- lastDstOff = tz_type.tz_gmtoff - utcOffset;
- }
- rule.stdOffset = utcOffset;
- rule.dstOffset = tz_type.tz_gmtoff - utcOffset;
- rule.abbreviationIndex = tz_type.tz_abbrind;
-
- // If the rule already exist then use that, otherwise add it
- int ruleIndex = m_tranRules.indexOf(rule);
- if (ruleIndex == -1) {
- m_tranRules.append(rule);
- tran.ruleIndex = m_tranRules.size() - 1;
- } else {
- tran.ruleIndex = ruleIndex;
- }
-
- tran.atMSecsSinceEpoch = tz_tran.tz_time * 1000;
- m_tranTimes.append(tran);
- }
- if (m_tranTimes.isEmpty() && m_posixRule.isEmpty())
- return; // Invalid after all !
-
- if (ianaId.isEmpty())
- m_id = systemTimeZoneId();
- else
- m_id = ianaId;
-}
-
-QLocale::Country QTzTimeZonePrivate::country() const
-{
- return tzZones->value(m_id).country;
-}
-
-QString QTzTimeZonePrivate::comment() const
-{
- return QString::fromUtf8(tzZones->value(m_id).comment);
-}
-
-QString QTzTimeZonePrivate::displayName(qint64 atMSecsSinceEpoch,
- QTimeZone::NameType nameType,
- const QLocale &locale) const
-{
-#if QT_CONFIG(icu)
- 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);
-#else
- Q_UNUSED(nameType)
- Q_UNUSED(locale)
-#endif
- return abbreviation(atMSecsSinceEpoch);
-}
-
-QString QTzTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
- QTimeZone::NameType nameType,
- const QLocale &locale) const
-{
-#if QT_CONFIG(icu)
- 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);
-#else
- Q_UNUSED(timeType)
- Q_UNUSED(nameType)
- Q_UNUSED(locale)
-#endif
- // If no ICU available then have to use abbreviations instead
- // Abbreviations don't have GenericTime
- if (timeType == QTimeZone::GenericTime)
- timeType = QTimeZone::StandardTime;
-
- // Get current tran, if valid and is what we want, then use it
- const qint64 currentMSecs = QDateTime::currentMSecsSinceEpoch();
- QTimeZonePrivate::Data tran = data(currentMSecs);
- if (tran.atMSecsSinceEpoch != invalidMSecs()
- && ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
- || (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0))) {
- return tran.abbreviation;
- }
-
- // Otherwise get next tran and if valid and is what we want, then use it
- tran = nextTransition(currentMSecs);
- if (tran.atMSecsSinceEpoch != invalidMSecs()
- && ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
- || (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0))) {
- return tran.abbreviation;
- }
-
- // Otherwise get prev tran and if valid and is what we want, then use it
- tran = previousTransition(currentMSecs);
- if (tran.atMSecsSinceEpoch != invalidMSecs())
- tran = previousTransition(tran.atMSecsSinceEpoch);
- if (tran.atMSecsSinceEpoch != invalidMSecs()
- && ((timeType == QTimeZone::DaylightTime && tran.daylightTimeOffset != 0)
- || (timeType == QTimeZone::StandardTime && tran.daylightTimeOffset == 0))) {
- return tran.abbreviation;
- }
-
- // Otherwise is strange sequence, so work backwards through trans looking for first match, if any
- auto it = std::partition_point(m_tranTimes.cbegin(), m_tranTimes.cend(),
- [currentMSecs](const QTzTransitionTime &at) {
- return at.atMSecsSinceEpoch <= currentMSecs;
- });
-
- while (it != m_tranTimes.cbegin()) {
- --it;
- tran = dataForTzTransition(*it);
- int offset = tran.daylightTimeOffset;
- if ((timeType == QTimeZone::DaylightTime) != (offset == 0))
- return tran.abbreviation;
- }
-
- // Otherwise if no match use current data
- return data(currentMSecs).abbreviation;
-}
-
-QString QTzTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch) const
-{
- return data(atMSecsSinceEpoch).abbreviation;
-}
-
-int QTzTimeZonePrivate::offsetFromUtc(qint64 atMSecsSinceEpoch) const
-{
- const QTimeZonePrivate::Data tran = data(atMSecsSinceEpoch);
- return tran.offsetFromUtc; // == tran.standardTimeOffset + tran.daylightTimeOffset
-}
-
-int QTzTimeZonePrivate::standardTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- return data(atMSecsSinceEpoch).standardTimeOffset;
-}
-
-int QTzTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- return data(atMSecsSinceEpoch).daylightTimeOffset;
-}
-
-bool QTzTimeZonePrivate::hasDaylightTime() const
-{
- // TODO Perhaps cache as frequently accessed?
- for (const QTzTransitionRule &rule : m_tranRules) {
- if (rule.dstOffset != 0)
- return true;
- }
- return false;
-}
-
-bool QTzTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
-{
- return (daylightTimeOffset(atMSecsSinceEpoch) != 0);
-}
-
-QTimeZonePrivate::Data QTzTimeZonePrivate::dataForTzTransition(QTzTransitionTime tran) const
-{
- QTimeZonePrivate::Data data;
- data.atMSecsSinceEpoch = tran.atMSecsSinceEpoch;
- QTzTransitionRule rule = m_tranRules.at(tran.ruleIndex);
- data.standardTimeOffset = rule.stdOffset;
- data.daylightTimeOffset = rule.dstOffset;
- data.offsetFromUtc = rule.stdOffset + rule.dstOffset;
- data.abbreviation = QString::fromUtf8(m_abbreviations.at(rule.abbreviationIndex));
- return data;
-}
-
-QVector<QTimeZonePrivate::Data> QTzTimeZonePrivate::getPosixTransitions(qint64 msNear) const
-{
- const int year = QDateTime::fromMSecsSinceEpoch(msNear, Qt::UTC).date().year();
- // The Data::atMSecsSinceEpoch of the single entry if zone is constant:
- qint64 atTime = m_tranTimes.isEmpty() ? msNear : m_tranTimes.last().atMSecsSinceEpoch;
- return calculatePosixTransitions(m_posixRule, year - 1, year + 1, atTime);
-}
-
-QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
-{
- // If the required time is after the last transition (or there were none)
- // and we have a POSIX rule, then use it:
- if (!m_posixRule.isEmpty()
- && (m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch)) {
- QVector<QTimeZonePrivate::Data> posixTrans = getPosixTransitions(forMSecsSinceEpoch);
- auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
- [forMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) {
- return at.atMSecsSinceEpoch <= forMSecsSinceEpoch;
- });
- // Use most recent, if any in the past; or the first if we have no other rules:
- if (it > posixTrans.cbegin() || (m_tranTimes.isEmpty() && it < posixTrans.cend())) {
- QTimeZonePrivate::Data data = *(it > posixTrans.cbegin() ? it - 1 : it);
- data.atMSecsSinceEpoch = forMSecsSinceEpoch;
- return data;
- }
- }
- if (m_tranTimes.isEmpty()) // Only possible if !isValid()
- return invalidData();
-
- // Otherwise, use the rule for the most recent or first transition:
- auto last = std::partition_point(m_tranTimes.cbegin(), m_tranTimes.cend(),
- [forMSecsSinceEpoch] (const QTzTransitionTime &at) {
- return at.atMSecsSinceEpoch <= forMSecsSinceEpoch;
- });
- if (last > m_tranTimes.cbegin())
- --last;
- Data data = dataForTzTransition(*last);
- data.atMSecsSinceEpoch = forMSecsSinceEpoch;
- return data;
-}
-
-bool QTzTimeZonePrivate::hasTransitions() const
-{
- return true;
-}
-
-QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const
-{
- // If the required time is after the last transition (or there were none)
- // and we have a POSIX rule, then use it:
- if (!m_posixRule.isEmpty()
- && (m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch)) {
- QVector<QTimeZonePrivate::Data> posixTrans = getPosixTransitions(afterMSecsSinceEpoch);
- auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
- [afterMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) {
- return at.atMSecsSinceEpoch <= afterMSecsSinceEpoch;
- });
-
- return it == posixTrans.cend() ? invalidData() : *it;
- }
-
- // Otherwise, if we can find a valid tran, use its rule:
- auto last = std::partition_point(m_tranTimes.cbegin(), m_tranTimes.cend(),
- [afterMSecsSinceEpoch] (const QTzTransitionTime &at) {
- return at.atMSecsSinceEpoch <= afterMSecsSinceEpoch;
- });
- return last != m_tranTimes.cend() ? dataForTzTransition(*last) : invalidData();
-}
-
-QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
-{
- // If the required time is after the last transition (or there were none)
- // and we have a POSIX rule, then use it:
- if (!m_posixRule.isEmpty()
- && (m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch)) {
- QVector<QTimeZonePrivate::Data> posixTrans = getPosixTransitions(beforeMSecsSinceEpoch);
- auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
- [beforeMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) {
- return at.atMSecsSinceEpoch < beforeMSecsSinceEpoch;
- });
- if (it > posixTrans.cbegin())
- return *--it;
- // It fell between the last transition (if any) and the first of the POSIX rule:
- return m_tranTimes.isEmpty() ? invalidData() : dataForTzTransition(m_tranTimes.last());
- }
-
- // Otherwise if we can find a valid tran then use its rule
- auto last = std::partition_point(m_tranTimes.cbegin(), m_tranTimes.cend(),
- [beforeMSecsSinceEpoch] (const QTzTransitionTime &at) {
- return at.atMSecsSinceEpoch < beforeMSecsSinceEpoch;
- });
- return last > m_tranTimes.cbegin() ? dataForTzTransition(*--last) : invalidData();
-}
-
-// TODO Could cache the value and monitor the required files for any changes
-QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
-{
- // Check TZ env var first, if not populated try find it
- QByteArray ianaId = qgetenv("TZ");
- if (!ianaId.isEmpty() && ianaId.at(0) == ':')
- ianaId = ianaId.mid(1);
-
- // The TZ value can be ":/etc/localtime" which libc considers
- // to be a "default timezone", in which case it will be read
- // by one of the blocks below, so unset it here so it is not
- // considered as a valid/found ianaId
- if (ianaId == "/etc/localtime")
- ianaId.clear();
-
- // On most distros /etc/localtime is a symlink to a real file so extract name from the path
- if (ianaId.isEmpty()) {
- const QString path = QFile::symLinkTarget(QStringLiteral("/etc/localtime"));
- if (!path.isEmpty()) {
- // /etc/localtime is a symlink to the current TZ file, so extract from path
- int index = path.indexOf(QLatin1String("/zoneinfo/"));
- if (index != -1)
- ianaId = path.mid(index + 10).toUtf8();
- }
- }
-
- // On Debian Etch up to Jessie, /etc/localtime is a regular file while the actual name is in /etc/timezone
- if (ianaId.isEmpty()) {
- QFile tzif(QStringLiteral("/etc/timezone"));
- if (tzif.open(QIODevice::ReadOnly)) {
- // TODO QTextStream inefficient, replace later
- QTextStream ts(&tzif);
- if (!ts.atEnd())
- ianaId = ts.readLine().toUtf8();
- }
- }
-
- // On some Red Hat distros /etc/localtime is real file with name held in /etc/sysconfig/clock
- // in a line like ZONE="Europe/Oslo" or TIMEZONE="Europe/Oslo"
- if (ianaId.isEmpty()) {
- QFile tzif(QStringLiteral("/etc/sysconfig/clock"));
- if (tzif.open(QIODevice::ReadOnly)) {
- // TODO QTextStream inefficient, replace later
- QTextStream ts(&tzif);
- QString line;
- while (ianaId.isEmpty() && !ts.atEnd() && ts.status() == QTextStream::Ok) {
- line = ts.readLine();
- if (line.startsWith(QLatin1String("ZONE="))) {
- ianaId = line.mid(6, line.size() - 7).toUtf8();
- } else if (line.startsWith(QLatin1String("TIMEZONE="))) {
- ianaId = line.mid(10, line.size() - 11).toUtf8();
- }
- }
- }
- }
-
- // Some systems (e.g. uClibc) have a default value for $TZ in /etc/TZ:
- if (ianaId.isEmpty()) {
- QFile zone(QStringLiteral("/etc/TZ"));
- if (zone.open(QIODevice::ReadOnly))
- ianaId = zone.readAll().trimmed();
- }
-
- // Give up for now and return UTC
- if (ianaId.isEmpty())
- ianaId = utcQByteArray();
-
- return ianaId;
-}
-
-bool QTzTimeZonePrivate::isTimeZoneIdAvailable(const QByteArray &ianaId) const
-{
- return tzZones->contains(ianaId);
-}
-
-QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds() const
-{
- QList<QByteArray> result = tzZones->keys();
- std::sort(result.begin(), result.end());
- return result;
-}
-
-QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds(QLocale::Country country) const
-{
- // TODO AnyCountry
- QList<QByteArray> result;
- for (auto it = tzZones->cbegin(), end = tzZones->cend(); it != end; ++it) {
- if (it.value().country == country)
- result << it.key();
- }
- std::sort(result.begin(), result.end());
- return result;
-}
-
-QT_END_NAMESPACE
diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp
deleted file mode 100644
index 1bf2366748..0000000000
--- a/src/corelib/tools/qtimezoneprivate_win.cpp
+++ /dev/null
@@ -1,927 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 John Layt <jlayt@kde.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtimezone.h"
-#include "qtimezoneprivate_p.h"
-
-#include "qdatetime.h"
-
-#include "qdebug.h"
-
-#include <algorithm>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef Q_OS_WINRT
-// The registry-based timezone backend is not available on WinRT, which falls back to equivalent APIs.
-#define QT_USE_REGISTRY_TIMEZONE 1
-#endif
-
-/*
- Private
-
- Windows system implementation
-*/
-
-#define MAX_KEY_LENGTH 255
-#define FILETIME_UNIX_EPOCH Q_UINT64_C(116444736000000000)
-
-// MSDN home page for Time support
-// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724962%28v=vs.85%29.aspx
-
-// For Windows XP and later refer to MSDN docs on TIME_ZONE_INFORMATION structure
-// http://msdn.microsoft.com/en-gb/library/windows/desktop/ms725481%28v=vs.85%29.aspx
-
-// Vista introduced support for historic data, see MSDN docs on DYNAMIC_TIME_ZONE_INFORMATION
-// http://msdn.microsoft.com/en-gb/library/windows/desktop/ms724253%28v=vs.85%29.aspx
-#ifdef QT_USE_REGISTRY_TIMEZONE
-static const char tzRegPath[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones";
-static const char currTzRegPath[] = "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation";
-#endif
-
-enum {
- MIN_YEAR = -292275056,
- MAX_YEAR = 292278994,
- MSECS_PER_DAY = 86400000,
- TIME_T_MAX = 2145916799, // int maximum 2037-12-31T23:59:59 UTC
- JULIAN_DAY_FOR_EPOCH = 2440588 // result of julianDayFromDate(1970, 1, 1)
-};
-
-// Copied from MSDN, see above for link
-typedef struct _REG_TZI_FORMAT
-{
- LONG Bias;
- LONG StandardBias;
- LONG DaylightBias;
- SYSTEMTIME StandardDate;
- SYSTEMTIME DaylightDate;
-} REG_TZI_FORMAT;
-
-namespace {
-
-// Fast and reliable conversion from msecs to date for all values
-// Adapted from QDateTime msecsToDate
-QDate msecsToDate(qint64 msecs)
-{
- qint64 jd = JULIAN_DAY_FOR_EPOCH;
-
- if (qAbs(msecs) >= MSECS_PER_DAY) {
- jd += (msecs / MSECS_PER_DAY);
- msecs %= MSECS_PER_DAY;
- }
-
- if (msecs < 0) {
- qint64 ds = MSECS_PER_DAY - msecs - 1;
- jd -= ds / MSECS_PER_DAY;
- }
-
- return QDate::fromJulianDay(jd);
-}
-
-bool equalSystemtime(const SYSTEMTIME &t1, const SYSTEMTIME &t2)
-{
- return (t1.wYear == t2.wYear
- && t1.wMonth == t2.wMonth
- && t1.wDay == t2.wDay
- && t1.wDayOfWeek == t2.wDayOfWeek
- && t1.wHour == t2.wHour
- && t1.wMinute == t2.wMinute
- && t1.wSecond == t2.wSecond
- && t1.wMilliseconds == t2.wMilliseconds);
-}
-
-bool equalTzi(const TIME_ZONE_INFORMATION &tzi1, const TIME_ZONE_INFORMATION &tzi2)
-{
- return(tzi1.Bias == tzi2.Bias
- && tzi1.StandardBias == tzi2.StandardBias
- && equalSystemtime(tzi1.StandardDate, tzi2.StandardDate)
- && wcscmp(tzi1.StandardName, tzi2.StandardName) == 0
- && tzi1.DaylightBias == tzi2.DaylightBias
- && equalSystemtime(tzi1.DaylightDate, tzi2.DaylightDate)
- && wcscmp(tzi1.DaylightName, tzi2.DaylightName) == 0);
-}
-
-#ifdef QT_USE_REGISTRY_TIMEZONE
-bool openRegistryKey(const QString &keyPath, HKEY *key)
-{
- return RegOpenKeyEx(HKEY_LOCAL_MACHINE, reinterpret_cast<const wchar_t*>(keyPath.utf16()),
- 0, KEY_READ, key) == ERROR_SUCCESS;
-}
-
-QString readRegistryString(const HKEY &key, const wchar_t *value)
-{
- wchar_t buffer[MAX_PATH] = {0};
- DWORD size = sizeof(wchar_t) * MAX_PATH;
- RegQueryValueEx(key, value, nullptr, nullptr, reinterpret_cast<LPBYTE>(buffer), &size);
- return QString::fromWCharArray(buffer);
-}
-
-int readRegistryValue(const HKEY &key, const wchar_t *value)
-{
- DWORD buffer;
- DWORD size = sizeof(buffer);
- RegQueryValueEx(key, value, nullptr, nullptr, reinterpret_cast<LPBYTE>(&buffer), &size);
- return buffer;
-}
-
-QWinTimeZonePrivate::QWinTransitionRule readRegistryRule(const HKEY &key,
- const wchar_t *value, bool *ok)
-{
- *ok = false;
- QWinTimeZonePrivate::QWinTransitionRule rule;
- REG_TZI_FORMAT tzi;
- DWORD tziSize = sizeof(tzi);
- if (RegQueryValueEx(key, value, nullptr, nullptr, reinterpret_cast<BYTE *>(&tzi), &tziSize)
- == ERROR_SUCCESS) {
- rule.startYear = 0;
- rule.standardTimeBias = tzi.Bias + tzi.StandardBias;
- rule.daylightTimeBias = tzi.Bias + tzi.DaylightBias - rule.standardTimeBias;
- rule.standardTimeRule = tzi.StandardDate;
- rule.daylightTimeRule = tzi.DaylightDate;
- *ok = true;
- }
- return rule;
-}
-
-TIME_ZONE_INFORMATION getRegistryTzi(const QByteArray &windowsId, bool *ok)
-{
- *ok = false;
- TIME_ZONE_INFORMATION tzi;
- REG_TZI_FORMAT regTzi;
- DWORD regTziSize = sizeof(regTzi);
- HKEY key = NULL;
- const QString tziKeyPath = QString::fromUtf8(tzRegPath) + QLatin1Char('\\')
- + QString::fromUtf8(windowsId);
-
- if (openRegistryKey(tziKeyPath, &key)) {
-
- DWORD size = sizeof(tzi.DaylightName);
- RegQueryValueEx(key, L"Dlt", nullptr, nullptr, reinterpret_cast<LPBYTE>(tzi.DaylightName), &size);
-
- size = sizeof(tzi.StandardName);
- RegQueryValueEx(key, L"Std", nullptr, nullptr, reinterpret_cast<LPBYTE>(tzi.StandardName), &size);
-
- if (RegQueryValueEx(key, L"TZI", nullptr, nullptr, reinterpret_cast<BYTE *>(&regTzi), &regTziSize)
- == ERROR_SUCCESS) {
- tzi.Bias = regTzi.Bias;
- tzi.StandardBias = regTzi.StandardBias;
- tzi.DaylightBias = regTzi.DaylightBias;
- tzi.StandardDate = regTzi.StandardDate;
- tzi.DaylightDate = regTzi.DaylightDate;
- *ok = true;
- }
-
- RegCloseKey(key);
- }
-
- return tzi;
-}
-#else // QT_USE_REGISTRY_TIMEZONE
-struct QWinDynamicTimeZone
-{
- QString standardName;
- QString daylightName;
- QString timezoneName;
- qint32 bias;
- bool daylightTime;
-};
-
-typedef QHash<QByteArray, QWinDynamicTimeZone> QWinRTTimeZoneHash;
-
-Q_GLOBAL_STATIC(QWinRTTimeZoneHash, gTimeZones)
-
-void enumerateTimeZones()
-{
- DYNAMIC_TIME_ZONE_INFORMATION dtzInfo;
- quint32 index = 0;
- QString prevTimeZoneKeyName;
- while (SUCCEEDED(EnumDynamicTimeZoneInformation(index++, &dtzInfo))) {
- QWinDynamicTimeZone item;
- item.timezoneName = QString::fromWCharArray(dtzInfo.TimeZoneKeyName);
- // As soon as key name repeats, break. Some systems continue to always
- // return the last item independent of index being out of range
- if (item.timezoneName == prevTimeZoneKeyName)
- break;
- item.standardName = QString::fromWCharArray(dtzInfo.StandardName);
- item.daylightName = QString::fromWCharArray(dtzInfo.DaylightName);
- item.daylightTime = !dtzInfo.DynamicDaylightTimeDisabled;
- item.bias = dtzInfo.Bias;
- gTimeZones->insert(item.timezoneName.toUtf8(), item);
- prevTimeZoneKeyName = item.timezoneName;
- }
-}
-
-DYNAMIC_TIME_ZONE_INFORMATION dynamicInfoForId(const QByteArray &windowsId)
-{
- DYNAMIC_TIME_ZONE_INFORMATION dtzInfo;
- quint32 index = 0;
- QString prevTimeZoneKeyName;
- while (SUCCEEDED(EnumDynamicTimeZoneInformation(index++, &dtzInfo))) {
- const QString timeZoneName = QString::fromWCharArray(dtzInfo.TimeZoneKeyName);
- if (timeZoneName == QLatin1String(windowsId))
- break;
- if (timeZoneName == prevTimeZoneKeyName)
- break;
- prevTimeZoneKeyName = timeZoneName;
- }
- return dtzInfo;
-}
-
-QWinTimeZonePrivate::QWinTransitionRule
-readDynamicRule(DYNAMIC_TIME_ZONE_INFORMATION &dtzi, int year, bool *ok)
-{
- TIME_ZONE_INFORMATION tzi;
- QWinTimeZonePrivate::QWinTransitionRule rule;
- *ok = GetTimeZoneInformationForYear(year, &dtzi, &tzi);
- if (*ok) {
- rule.startYear = 0;
- rule.standardTimeBias = tzi.Bias + tzi.StandardBias;
- rule.daylightTimeBias = tzi.Bias + tzi.DaylightBias - rule.standardTimeBias;
- rule.standardTimeRule = tzi.StandardDate;
- rule.daylightTimeRule = tzi.DaylightDate;
- }
- return rule;
-}
-#endif // QT_USE_REGISTRY_TIMEZONE
-
-bool isSameRule(const QWinTimeZonePrivate::QWinTransitionRule &last,
- const QWinTimeZonePrivate::QWinTransitionRule &rule)
-{
- // In particular, when this is true and either wYear is 0, so is the other;
- // so if one rule is recurrent and they're equal, so is the other. If
- // either rule *isn't* recurrent, it has non-0 wYear which shall be
- // different from the other's. Note that we don't compare .startYear, since
- // that will always be different.
- return equalSystemtime(last.standardTimeRule, rule.standardTimeRule)
- && equalSystemtime(last.daylightTimeRule, rule.daylightTimeRule)
- && last.standardTimeBias == rule.standardTimeBias
- && last.daylightTimeBias == rule.daylightTimeBias;
-}
-
-QList<QByteArray> availableWindowsIds()
-{
-#ifdef QT_USE_REGISTRY_TIMEZONE
- // TODO Consider caching results in a global static, very unlikely to change.
- QList<QByteArray> list;
- HKEY key = NULL;
- if (openRegistryKey(QString::fromUtf8(tzRegPath), &key)) {
- DWORD idCount = 0;
- if (RegQueryInfoKey(key, 0, 0, 0, &idCount, 0, 0, 0, 0, 0, 0, 0) == ERROR_SUCCESS
- && idCount > 0) {
- for (DWORD i = 0; i < idCount; ++i) {
- DWORD maxLen = MAX_KEY_LENGTH;
- TCHAR buffer[MAX_KEY_LENGTH];
- if (RegEnumKeyEx(key, i, buffer, &maxLen, 0, 0, 0, 0) == ERROR_SUCCESS)
- list.append(QString::fromWCharArray(buffer).toUtf8());
- }
- }
- RegCloseKey(key);
- }
- return list;
-#else // QT_USE_REGISTRY_TIMEZONE
- if (gTimeZones->isEmpty())
- enumerateTimeZones();
- return gTimeZones->keys();
-#endif // QT_USE_REGISTRY_TIMEZONE
-}
-
-QByteArray windowsSystemZoneId()
-{
-#ifdef QT_USE_REGISTRY_TIMEZONE
- // On Vista and later is held in the value TimeZoneKeyName in key currTzRegPath
- QString id;
- HKEY key = NULL;
- QString tziKeyPath = QString::fromUtf8(currTzRegPath);
- if (openRegistryKey(tziKeyPath, &key)) {
- id = readRegistryString(key, L"TimeZoneKeyName");
- RegCloseKey(key);
- if (!id.isEmpty())
- return std::move(id).toUtf8();
- }
-
- // On XP we have to iterate over the zones until we find a match on
- // names/offsets with the current data
- TIME_ZONE_INFORMATION sysTzi;
- GetTimeZoneInformation(&sysTzi);
- bool ok = false;
- const auto winIds = availableWindowsIds();
- for (const QByteArray &winId : winIds) {
- if (equalTzi(getRegistryTzi(winId, &ok), sysTzi))
- return winId;
- }
-#else // QT_USE_REGISTRY_TIMEZONE
- DYNAMIC_TIME_ZONE_INFORMATION dtzi;
- if (SUCCEEDED(GetDynamicTimeZoneInformation(&dtzi)))
- return QString::fromWCharArray(dtzi.TimeZoneKeyName).toLocal8Bit();
-#endif // QT_USE_REGISTRY_TIMEZONE
-
- // If we can't determine the current ID use UTC
- return QTimeZonePrivate::utcQByteArray();
-}
-
-QDate calculateTransitionLocalDate(const SYSTEMTIME &rule, int year)
-{
- // If month is 0 then there is no date
- if (rule.wMonth == 0)
- return QDate();
-
- // Interpret SYSTEMTIME according to the slightly quirky rules in:
- // https://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx
-
- // If the year is set, the rule gives an absolute date:
- if (rule.wYear)
- return QDate(rule.wYear, rule.wMonth, rule.wDay);
-
- // Otherwise, the rule date is annual and relative:
- const int dayOfWeek = rule.wDayOfWeek == 0 ? 7 : rule.wDayOfWeek;
- QDate date(year, rule.wMonth, 1);
- // How many days before was last dayOfWeek before target month ?
- int adjust = dayOfWeek - date.dayOfWeek(); // -6 <= adjust < 7
- if (adjust >= 0) // Ensure -7 <= adjust < 0:
- adjust -= 7;
- // Normally, wDay is day-within-month; but here it is 1 for the first
- // of the given dayOfWeek in the month, through 4 for the fourth or ...
- adjust += (rule.wDay < 1 ? 1 : rule.wDay > 4 ? 5 : rule.wDay) * 7;
- date = date.addDays(adjust);
- // ... 5 for the last; so back up by weeks to get within the month:
- if (date.month() != rule.wMonth) {
- Q_ASSERT(rule.wDay > 4);
- // (Note that, with adjust < 0, date <= 28th of our target month
- // is guaranteed when wDay <= 4, or after our first -7 here.)
- date = date.addDays(-7);
- Q_ASSERT(date.month() == rule.wMonth);
- }
- return date;
-}
-
-// Converts a date/time value into msecs
-inline qint64 timeToMSecs(const QDate &date, const QTime &time)
-{
- return ((date.toJulianDay() - JULIAN_DAY_FOR_EPOCH) * MSECS_PER_DAY)
- + time.msecsSinceStartOfDay();
-}
-
-qint64 calculateTransitionForYear(const SYSTEMTIME &rule, int year, int bias)
-{
- // TODO Consider caching the calculated values - i.e. replace SYSTEMTIME in
- // WinTransitionRule; do this in init() once and store the results.
- const QDate date = calculateTransitionLocalDate(rule, year);
- const QTime time = QTime(rule.wHour, rule.wMinute, rule.wSecond);
- if (date.isValid() && time.isValid())
- return timeToMSecs(date, time) + bias * 60000;
- return QTimeZonePrivate::invalidMSecs();
-}
-
-struct TransitionTimePair
-{
- // Transition times after the epoch, in ms:
- qint64 std, dst;
- // If either is invalidMSecs(), which shall then be < the other, there is no
- // DST and the other describes a change in actual standard offset.
-
- TransitionTimePair(const QWinTimeZonePrivate::QWinTransitionRule &rule,
- int year, int oldYearOffset)
- // The local time in Daylight Time of the switch to Standard Time
- : std(calculateTransitionForYear(rule.standardTimeRule, year,
- rule.standardTimeBias + rule.daylightTimeBias)),
- // The local time in Standard Time of the switch to Daylight Time
- dst(calculateTransitionForYear(rule.daylightTimeRule, year, rule.standardTimeBias))
- {
- /*
- Check for potential "fake DST", used by MS's APIs because the
- TIME_ZONE_INFORMATION spec either expresses no transitions in the
- year, or expresses a transition of each kind, even if standard time
- did change in a year with no DST. We've seen year-start fake-DST
- (whose offset matches prior standard offset, in which the previous
- year ended); and conjecture that similar might be used at a year-end.
- (This might be used for a southern-hemisphere zone, where the start of
- the year usually is in DST, when applicable.) Note that, here, wDay
- identifies an instance of a given day-of-week in the month, with 5
- meaning last.
-
- Either the alleged standardTimeRule or the alleged daylightTimeRule
- may be faked; either way, the transition is actually a change to the
- current standard offset; but the unfaked half of the rule contains the
- useful bias data, so we have to go along with its lies.
-
- Example: Russia/Moscow
- Format: -bias +( -stdBias, stdDate | -dstBias, dstDate ) notes
- Last year of DST, 2010: 180 +( 0, 0-10-5 3:0 | 60, 0-3-5 2:0 ) normal DST
- Zone change in 2011: 180 +( 0, 0-1-1 0:0 | 60 0-3-5 2:0 ) fake DST at transition
- Fixed standard in 2012: 240 +( 0, 0-0-0 0:0 | 60, 0-0-0 0:0 ) standard time years
- Zone change in 2014: 180 +( 0, 0-10-5 2:0 | 60, 0-1-1 0:0 ) fake DST at year-start
- The last of these is missing on Win7 VMs (too old to know about it).
- */
- if (rule.daylightTimeRule.wMonth == 1 && rule.daylightTimeRule.wDay == 1) {
- // Fake "DST transition" at start of year producing the same offset as
- // previous year ended in.
- if (rule.standardTimeBias + rule.daylightTimeBias == oldYearOffset)
- dst = QTimeZonePrivate::invalidMSecs();
- } else if (rule.daylightTimeRule.wMonth == 12 && rule.daylightTimeRule.wDay > 3) {
- // Similar, conjectured, for end of year, not changing offset.
- if (rule.daylightTimeBias == 0)
- dst = QTimeZonePrivate::invalidMSecs();
- }
- if (rule.standardTimeRule.wMonth == 1 && rule.standardTimeRule.wDay == 1) {
- // Fake "transition out of DST" at start of year producing the same
- // offset as previous year ended in.
- if (rule.standardTimeBias == oldYearOffset)
- std = QTimeZonePrivate::invalidMSecs();
- } else if (rule.standardTimeRule.wMonth == 12 && rule.standardTimeRule.wDay > 3) {
- // Similar, conjectured, for end of year, not changing offset.
- if (rule.daylightTimeBias == 0)
- std = QTimeZonePrivate::invalidMSecs();
- }
- }
-
- bool fakesDst() const
- {
- return std == QTimeZonePrivate::invalidMSecs()
- || dst == QTimeZonePrivate::invalidMSecs();
- }
-};
-
-int yearEndOffset(const QWinTimeZonePrivate::QWinTransitionRule &rule, int year)
-{
- int offset = rule.standardTimeBias;
- // Only needed to help another TransitionTimePair work out year + 1's start
- // offset; and the oldYearOffset we use only affects an alleged transition
- // at the *start* of this year, so it doesn't matter if we guess wrong here:
- TransitionTimePair pair(rule, year, offset);
- if (pair.dst > pair.std)
- offset += rule.daylightTimeBias;
- return offset;
-}
-
-QLocale::Country userCountry()
-{
- const GEOID id = GetUserGeoID(GEOCLASS_NATION);
- wchar_t code[3];
- const int size = GetGeoInfo(id, GEO_ISO2, code, 3, 0);
- return (size == 3) ? QLocalePrivate::codeToCountry(QStringView(code, size))
- : QLocale::AnyCountry;
-}
-
-// Index of last rule in rules with .startYear <= year:
-int ruleIndexForYear(const QList<QWinTimeZonePrivate::QWinTransitionRule> &rules, int year)
-{
- if (rules.last().startYear <= year)
- return rules.count() - 1;
- // We don't have a rule for before the first, but the first is the best we can offer:
- if (rules.first().startYear > year)
- return 0;
-
- // Otherwise, use binary chop:
- int lo = 0, hi = rules.count();
- // invariant: rules[i].startYear <= year < rules[hi].startYear
- // subject to treating rules[rules.count()] as "off the end of time"
- while (lo + 1 < hi) {
- const int mid = (lo + hi) / 2;
- // lo + 2 <= hi, so lo + 1 <= mid <= hi - 1, so lo < mid < hi
- // In particular, mid < rules.count()
- const int midYear = rules.at(mid).startYear;
- if (midYear > year)
- hi = mid;
- else if (midYear < year)
- lo = mid;
- else // No two rules have the same startYear:
- return mid;
- }
- return lo;
-}
-
-} // anonymous namespace
-
-// Create the system default time zone
-QWinTimeZonePrivate::QWinTimeZonePrivate()
- : QTimeZonePrivate()
-{
- init(QByteArray());
-}
-
-// Create a named time zone
-QWinTimeZonePrivate::QWinTimeZonePrivate(const QByteArray &ianaId)
- : QTimeZonePrivate()
-{
- init(ianaId);
-}
-
-QWinTimeZonePrivate::QWinTimeZonePrivate(const QWinTimeZonePrivate &other)
- : QTimeZonePrivate(other), m_windowsId(other.m_windowsId),
- m_displayName(other.m_displayName), m_standardName(other.m_standardName),
- m_daylightName(other.m_daylightName), m_tranRules(other.m_tranRules)
-{
-}
-
-QWinTimeZonePrivate::~QWinTimeZonePrivate()
-{
-}
-
-QWinTimeZonePrivate *QWinTimeZonePrivate::clone() const
-{
- return new QWinTimeZonePrivate(*this);
-}
-
-void QWinTimeZonePrivate::init(const QByteArray &ianaId)
-{
- if (ianaId.isEmpty()) {
- m_windowsId = windowsSystemZoneId();
- m_id = systemTimeZoneId();
- } else {
- m_windowsId = ianaIdToWindowsId(ianaId);
- m_id = ianaId;
- }
-
- bool badMonth = false; // Only warn once per zone, if at all.
- if (!m_windowsId.isEmpty()) {
-#ifdef QT_USE_REGISTRY_TIMEZONE
- // Open the base TZI for the time zone
- HKEY baseKey = NULL;
- const QString baseKeyPath = QString::fromUtf8(tzRegPath) + QLatin1Char('\\')
- + QString::fromUtf8(m_windowsId);
- if (openRegistryKey(baseKeyPath, &baseKey)) {
- // Load the localized names
- m_displayName = readRegistryString(baseKey, L"Display");
- m_standardName = readRegistryString(baseKey, L"Std");
- m_daylightName = readRegistryString(baseKey, L"Dlt");
- // On Vista and later the optional dynamic key holds historic data
- const QString dynamicKeyPath = baseKeyPath + QLatin1String("\\Dynamic DST");
- HKEY dynamicKey = NULL;
- if (openRegistryKey(dynamicKeyPath, &dynamicKey)) {
- // Find out the start and end years stored, then iterate over them
- int startYear = readRegistryValue(dynamicKey, L"FirstEntry");
- int endYear = readRegistryValue(dynamicKey, L"LastEntry");
- for (int year = startYear; year <= endYear; ++year) {
- bool ruleOk;
- QWinTransitionRule rule = readRegistryRule(dynamicKey,
- reinterpret_cast<LPCWSTR>(QString::number(year).utf16()),
- &ruleOk);
- if (ruleOk
- // Don't repeat a recurrent rule:
- && (m_tranRules.isEmpty()
- || !isSameRule(m_tranRules.last(), rule))) {
- if (!badMonth
- && (rule.standardTimeRule.wMonth == 0)
- != (rule.daylightTimeRule.wMonth == 0)) {
- badMonth = true;
- qWarning("MS registry TZ API violated its wMonth constraint;"
- "this may cause mistakes for %s from %d",
- ianaId.constData(), year);
- }
- rule.startYear = m_tranRules.isEmpty() ? MIN_YEAR : year;
- m_tranRules.append(rule);
- }
- }
- RegCloseKey(dynamicKey);
- } else {
- // No dynamic data so use the base data
- bool ruleOk;
- QWinTransitionRule rule = readRegistryRule(baseKey, L"TZI", &ruleOk);
- rule.startYear = MIN_YEAR;
- if (ruleOk)
- m_tranRules.append(rule);
- }
- RegCloseKey(baseKey);
- }
-#else // QT_USE_REGISTRY_TIMEZONE
- if (gTimeZones->isEmpty())
- enumerateTimeZones();
- QWinRTTimeZoneHash::const_iterator it = gTimeZones->find(m_windowsId);
- if (it != gTimeZones->constEnd()) {
- m_displayName = it->timezoneName;
- m_standardName = it->standardName;
- m_daylightName = it->daylightName;
- DWORD firstYear = 0;
- DWORD lastYear = 0;
- DYNAMIC_TIME_ZONE_INFORMATION dtzi = dynamicInfoForId(m_windowsId);
- if (GetDynamicTimeZoneInformationEffectiveYears(&dtzi, &firstYear, &lastYear)
- == ERROR_SUCCESS && firstYear < lastYear) {
- for (DWORD year = firstYear; year <= lastYear; ++year) {
- bool ok = false;
- QWinTransitionRule rule = readDynamicRule(dtzi, year, &ok);
- if (ok
- // Don't repeat a recurrent rule
- && (m_tranRules.isEmpty()
- || !isSameRule(m_tranRules.last(), rule))) {
- if (!badMonth
- && (rule.standardTimeRule.wMonth == 0)
- != (rule.daylightTimeRule.wMonth == 0)) {
- badMonth = true;
- qWarning("MS dynamic TZ API violated its wMonth constraint;"
- "this may cause mistakes for %s from %d",
- ianaId.constData(), year);
- }
- rule.startYear = m_tranRules.isEmpty() ? MIN_YEAR : year;
- m_tranRules.append(rule);
- }
- }
- } else {
- // At least try to get the non-dynamic data:
- dtzi.DynamicDaylightTimeDisabled = false;
- bool ok = false;
- QWinTransitionRule rule = readDynamicRule(dtzi, 1970, &ok);
- if (ok) {
- rule.startYear = MIN_YEAR;
- m_tranRules.append(rule);
- }
- }
- }
-#endif // QT_USE_REGISTRY_TIMEZONE
- }
-
- // If there are no rules then we failed to find a windowsId or any tzi info
- if (m_tranRules.size() == 0) {
- m_id.clear();
- m_windowsId.clear();
- m_displayName.clear();
- }
-}
-
-QString QWinTimeZonePrivate::comment() const
-{
- return m_displayName;
-}
-
-QString QWinTimeZonePrivate::displayName(QTimeZone::TimeType timeType,
- QTimeZone::NameType nameType,
- const QLocale &locale) const
-{
- // TODO Registry holds MUI keys, should be able to look up translations?
- Q_UNUSED(locale);
-
- if (nameType == QTimeZone::OffsetName) {
- const QWinTransitionRule &rule =
- m_tranRules.at(ruleIndexForYear(m_tranRules, QDate::currentDate().year()));
- int offset = rule.standardTimeBias;
- if (timeType == QTimeZone::DaylightTime)
- offset += rule.daylightTimeBias;
- return isoOffsetFormat(offset * -60);
- }
-
- switch (timeType) {
- case QTimeZone::DaylightTime :
- return m_daylightName;
- case QTimeZone::GenericTime :
- return m_displayName;
- case QTimeZone::StandardTime :
- return m_standardName;
- }
- return m_standardName;
-}
-
-QString QWinTimeZonePrivate::abbreviation(qint64 atMSecsSinceEpoch) const
-{
- return data(atMSecsSinceEpoch).abbreviation;
-}
-
-int QWinTimeZonePrivate::offsetFromUtc(qint64 atMSecsSinceEpoch) const
-{
- return data(atMSecsSinceEpoch).offsetFromUtc;
-}
-
-int QWinTimeZonePrivate::standardTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- return data(atMSecsSinceEpoch).standardTimeOffset;
-}
-
-int QWinTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch) const
-{
- return data(atMSecsSinceEpoch).daylightTimeOffset;
-}
-
-bool QWinTimeZonePrivate::hasDaylightTime() const
-{
- return hasTransitions();
-}
-
-bool QWinTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
-{
- return (data(atMSecsSinceEpoch).daylightTimeOffset != 0);
-}
-
-QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
-{
- int year = msecsToDate(forMSecsSinceEpoch).year();
- for (int ruleIndex = ruleIndexForYear(m_tranRules, year);
- ruleIndex >= 0; --ruleIndex) {
- const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
- // Does this rule's period include any transition at all ?
- if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
- const int endYear = qMax(rule.startYear, year - 1);
- while (year >= endYear) {
- const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
- ? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
- : yearEndOffset(rule, year - 1);
- const TransitionTimePair pair(rule, year, newYearOffset);
- bool isDst = false;
- if (pair.std != invalidMSecs() && pair.std <= forMSecsSinceEpoch) {
- isDst = pair.std < pair.dst && pair.dst <= forMSecsSinceEpoch;
- } else if (pair.dst != invalidMSecs() && pair.dst <= forMSecsSinceEpoch) {
- isDst = true;
- } else {
- --year; // Try an earlier year for this rule (once).
- continue;
- }
- return ruleToData(rule, forMSecsSinceEpoch,
- isDst ? QTimeZone::DaylightTime : QTimeZone::StandardTime,
- pair.fakesDst());
- }
- // Fell off start of rule, try previous rule.
- } else {
- // No transition, no DST, use the year's standard time.
- return ruleToData(rule, forMSecsSinceEpoch, QTimeZone::StandardTime);
- }
- if (year >= rule.startYear)
- year = rule.startYear - 1; // Seek last transition in new rule.
- }
- // We don't have relevant data :-(
- return invalidData();
-}
-
-bool QWinTimeZonePrivate::hasTransitions() const
-{
- for (const QWinTransitionRule &rule : m_tranRules) {
- if (rule.standardTimeRule.wMonth > 0 && rule.daylightTimeRule.wMonth > 0)
- return true;
- }
- return false;
-}
-
-QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const
-{
- int year = msecsToDate(afterMSecsSinceEpoch).year();
- for (int ruleIndex = ruleIndexForYear(m_tranRules, year);
- ruleIndex < m_tranRules.count(); ++ruleIndex) {
- const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
- // Does this rule's period include any transition at all ?
- if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
- if (year < rule.startYear)
- year = rule.startYear; // Seek first transition in this rule.
- const int endYear = ruleIndex + 1 < m_tranRules.count()
- ? qMin(m_tranRules.at(ruleIndex + 1).startYear, year + 2) : (year + 2);
- int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
- ? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
- : yearEndOffset(rule, year - 1);
- while (year < endYear) {
- const TransitionTimePair pair(rule, year, newYearOffset);
- bool isDst = false;
- Q_ASSERT(invalidMSecs() <= afterMSecsSinceEpoch); // invalid is min qint64
- if (pair.std > afterMSecsSinceEpoch) {
- isDst = pair.std > pair.dst && pair.dst > afterMSecsSinceEpoch;
- } else if (pair.dst > afterMSecsSinceEpoch) {
- isDst = true;
- } else {
- newYearOffset = rule.standardTimeBias;
- if (pair.dst > pair.std)
- newYearOffset += rule.daylightTimeBias;
- ++year; // Try a later year for this rule (once).
- continue;
- }
-
- if (isDst)
- return ruleToData(rule, pair.dst, QTimeZone::DaylightTime, pair.fakesDst());
- return ruleToData(rule, pair.std, QTimeZone::StandardTime, pair.fakesDst());
- }
- // Fell off end of rule, try next rule.
- } // else: no transition during rule's period
- }
- // Apparently no transition after the given time:
- return invalidData();
-}
-
-QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
-{
- const qint64 startOfTime = invalidMSecs() + 1;
- if (beforeMSecsSinceEpoch <= startOfTime)
- return invalidData();
-
- int year = msecsToDate(beforeMSecsSinceEpoch).year();
- for (int ruleIndex = ruleIndexForYear(m_tranRules, year);
- ruleIndex >= 0; --ruleIndex) {
- const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
- // Does this rule's period include any transition at all ?
- if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
- const int endYear = qMax(rule.startYear, year - 1);
- while (year >= endYear) {
- const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
- ? yearEndOffset(m_tranRules.at(ruleIndex - 1), year - 1)
- : yearEndOffset(rule, year - 1);
- const TransitionTimePair pair(rule, year, newYearOffset);
- bool isDst = false;
- if (pair.std != invalidMSecs() && pair.std < beforeMSecsSinceEpoch) {
- isDst = pair.std < pair.dst && pair.dst < beforeMSecsSinceEpoch;
- } else if (pair.dst != invalidMSecs() && pair.dst < beforeMSecsSinceEpoch) {
- isDst = true;
- } else {
- --year; // Try an earlier year for this rule (once).
- continue;
- }
- if (isDst)
- return ruleToData(rule, pair.dst, QTimeZone::DaylightTime, pair.fakesDst());
- return ruleToData(rule, pair.std, QTimeZone::StandardTime, pair.fakesDst());
- }
- // Fell off start of rule, try previous rule.
- } else if (ruleIndex == 0) {
- // Treat a no-transition first rule as a transition at the start of
- // time, so that a scan through all rules *does* see it as the first
- // rule:
- return ruleToData(rule, startOfTime, QTimeZone::StandardTime, false);
- } // else: no transition during rule's period
- if (year >= rule.startYear)
- year = rule.startYear - 1; // Seek last transition in new rule
- }
- // Apparently no transition before the given time:
- return invalidData();
-}
-
-QByteArray QWinTimeZonePrivate::systemTimeZoneId() const
-{
- const QLocale::Country country = userCountry();
- const QByteArray windowsId = windowsSystemZoneId();
- QByteArray ianaId;
- // If we have a real country, then try get a specific match for that country
- if (country != QLocale::AnyCountry)
- ianaId = windowsIdToDefaultIanaId(windowsId, country);
- // If we don't have a real country, or there wasn't a specific match, try the global default
- if (ianaId.isEmpty()) {
- ianaId = windowsIdToDefaultIanaId(windowsId);
- // If no global default then probably an unknown Windows ID so return UTC
- if (ianaId.isEmpty())
- return utcQByteArray();
- }
- return ianaId;
-}
-
-QList<QByteArray> QWinTimeZonePrivate::availableTimeZoneIds() const
-{
- QList<QByteArray> result;
- const auto winIds = availableWindowsIds();
- for (const QByteArray &winId : winIds)
- result += windowsIdToIanaIds(winId);
- std::sort(result.begin(), result.end());
- result.erase(std::unique(result.begin(), result.end()), result.end());
- return result;
-}
-
-QTimeZonePrivate::Data QWinTimeZonePrivate::ruleToData(const QWinTransitionRule &rule,
- qint64 atMSecsSinceEpoch,
- QTimeZone::TimeType type,
- bool fakeDst) const
-{
- Data tran = invalidData();
- tran.atMSecsSinceEpoch = atMSecsSinceEpoch;
- tran.standardTimeOffset = rule.standardTimeBias * -60;
- if (fakeDst) {
- tran.daylightTimeOffset = 0;
- tran.abbreviation = m_standardName;
- // Rule may claim we're in DST when it's actually a standard time change:
- if (type == QTimeZone::DaylightTime)
- tran.standardTimeOffset += rule.daylightTimeBias * -60;
- } else if (type == QTimeZone::DaylightTime) {
- tran.daylightTimeOffset = rule.daylightTimeBias * -60;
- tran.abbreviation = m_daylightName;
- } else {
- tran.daylightTimeOffset = 0;
- tran.abbreviation = m_standardName;
- }
- tran.offsetFromUtc = tran.standardTimeOffset + tran.daylightTimeOffset;
- return tran;
-}
-
-QT_END_NAMESPACE
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 5dcb6c9ee0..52eddd5d6b 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -20,8 +20,6 @@ HEADERS += \
tools/qcontainerfwd.h \
tools/qcontainertools_impl.h \
tools/qcryptographichash.h \
- tools/qdatetime.h \
- tools/qdatetime_p.h \
tools/qdoublescanprint_p.h \
tools/qeasingcurve.h \
tools/qfreelist_p.h \
@@ -86,7 +84,6 @@ SOURCES += \
tools/qbytearraymatcher.cpp \
tools/qcollator.cpp \
tools/qcryptographichash.cpp \
- tools/qdatetime.cpp \
tools/qeasingcurve.cpp \
tools/qfreelist.cpp \
tools/qhash.cpp \
@@ -154,33 +151,6 @@ qtConfig(icu) {
SOURCES += tools/qcollator_posix.cpp
}
-qtConfig(timezone) {
- HEADERS += \
- tools/qtimezone.h \
- tools/qtimezoneprivate_p.h \
- tools/qtimezoneprivate_data_p.h
- SOURCES += \
- tools/qtimezone.cpp \
- tools/qtimezoneprivate.cpp
- !nacl:darwin: {
- SOURCES += tools/qtimezoneprivate_mac.mm
- } else: android:!android-embedded: {
- SOURCES += tools/qtimezoneprivate_android.cpp
- } else: unix: {
- SOURCES += tools/qtimezoneprivate_tz.cpp
- qtConfig(icu): SOURCES += tools/qtimezoneprivate_icu.cpp
- } else: qtConfig(icu): {
- SOURCES += tools/qtimezoneprivate_icu.cpp
- } else: win32: {
- SOURCES += tools/qtimezoneprivate_win.cpp
- }
-}
-
-qtConfig(datetimeparser) {
- HEADERS += tools/qdatetimeparser_p.h
- SOURCES += tools/qdatetimeparser.cpp
-}
-
qtConfig(regularexpression) {
QMAKE_USE_PRIVATE += pcre2