Add support for calendars beside Gregorian
Add QCalendarBackend as a base class for calendar implementations and QCalendar as a facade via which to access it. QDate's implicit implementation of the Gregorian calendar becomes QGregorianCalendar and QDate methods now support choice of calendar. Convert QLocale's CLDR data for month names to a locale-data component of each supported calendar and relevant QLocale methods now support choice of calendar. Adapt Python scripts for locale data generation to extract month name data from CLDR (keeping on version v35.1) into the new calendar-locale files. The locale data for the Gregorian calendar is held in a Roman calendar base, for sharing with other calendars. Add tests for basic uses of the new API. [ChangeLog][QtCore][QCalendar] Added QCalendar to support diverse calendars, supported by implementing QCalendarBackend. [ChangeLog][QtCore][QDate] Allow choice of calendar in various operations, with Gregorian remaining the default. Done-with: Lars Knoll <lars.knoll@qt.io> Done-with: Edward Welbourne <edward.welbourne@qt.io> Fixes: QTBUG-17110 Fixes: QTBUG-950 Change-Id: I9d6278f394269a183aee8156e990cec4d5198ab8 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
8f083bade0
commit
aa8393c94f
@ -28,6 +28,7 @@ QOBJS = \
|
||||
qmetatype.o qsystemerror.o qvariant.o \
|
||||
quuid.o \
|
||||
qarraydata.o qbitarray.o qbytearray.o qbytearraymatcher.o \
|
||||
qcalendar.o qgregoriancalendar.o qromancalendar.o \
|
||||
qcryptographichash.o qdatetime.o qhash.o qlist.o \
|
||||
qlocale.o qlocale_tools.o qmap.o qregexp.o qringbuffer.o \
|
||||
qstringbuilder.o qstring.o qstringlist.o qversionnumber.o \
|
||||
@ -114,7 +115,10 @@ DEPEND_SRC = \
|
||||
$(SOURCE_PATH)/src/corelib/text/qstring.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/text/qstringlist.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/text/qvsnprintf.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/time/qcalendar.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/time/qdatetime.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/time/qgregoriancalendar.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/time/qromancalendar.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qarraydata.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp \
|
||||
$(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp \
|
||||
@ -428,6 +432,15 @@ qfileinfo.o: $(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp
|
||||
qdatetime.o: $(SOURCE_PATH)/src/corelib/time/qdatetime.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $<
|
||||
|
||||
qcalendar.o: $(SOURCE_PATH)/src/corelib/time/qcalendar.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $<
|
||||
|
||||
qgregoriancalendar.o: $(SOURCE_PATH)/src/corelib/time/qgregoriancalendar.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $<
|
||||
|
||||
qromancalendar.o: $(SOURCE_PATH)/src/corelib/time/qromancalendar.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $<
|
||||
|
||||
qstringlist.o: $(SOURCE_PATH)/src/corelib/text/qstringlist.cpp
|
||||
$(CXX) -c -o $@ $(CXXFLAGS) $<
|
||||
|
||||
|
@ -71,6 +71,7 @@ QTOBJS= \
|
||||
qbytearray.obj \
|
||||
qvsnprintf.obj \
|
||||
qbytearraymatcher.obj \
|
||||
qcalendar.obj \
|
||||
qdatetime.obj \
|
||||
qdir.obj \
|
||||
qdiriterator.obj \
|
||||
@ -83,6 +84,7 @@ QTOBJS= \
|
||||
qfileinfo.obj \
|
||||
qendian.obj \
|
||||
qglobal.obj \
|
||||
qgregoriancalendar.obj \
|
||||
qhash.obj \
|
||||
qiodevice.obj \
|
||||
qringbuffer.obj \
|
||||
@ -97,6 +99,7 @@ QTOBJS= \
|
||||
qoperatingsystemversion.obj \
|
||||
qoperatingsystemversion_win.obj \
|
||||
qregexp.obj \
|
||||
qromancalendar.obj \
|
||||
qutfcodec.obj \
|
||||
qstring.obj \
|
||||
qstringlist.obj \
|
||||
|
@ -115,6 +115,7 @@ SOURCES += \
|
||||
qbuffer.cpp \
|
||||
qbytearray.cpp \
|
||||
qbytearraymatcher.cpp \
|
||||
qcalendar.cpp \
|
||||
qcryptographichash.cpp \
|
||||
qdatetime.cpp \
|
||||
qdir.cpp \
|
||||
@ -127,6 +128,7 @@ SOURCES += \
|
||||
qfsfileengine.cpp \
|
||||
qfsfileengine_iterator.cpp \
|
||||
qglobal.cpp \
|
||||
qgregoriancalendar.cpp \
|
||||
qhash.cpp \
|
||||
qiodevice.cpp \
|
||||
qjson.cpp \
|
||||
@ -145,6 +147,7 @@ SOURCES += \
|
||||
qmetatype.cpp \
|
||||
qnumeric.cpp \
|
||||
qregexp.cpp \
|
||||
qromancalendar.cpp \
|
||||
qsettings.cpp \
|
||||
qstring.cpp \
|
||||
qstringlist.cpp \
|
||||
@ -168,6 +171,9 @@ HEADERS += \
|
||||
qbuffer.h \
|
||||
qbytearray.h \
|
||||
qbytearraymatcher.h \
|
||||
qcalendar.h \
|
||||
qcalendarbackend_p.h \
|
||||
qcalendarmath_p.h \
|
||||
qchar.h \
|
||||
qcryptographichash.h \
|
||||
qdatetime.h \
|
||||
@ -178,6 +184,7 @@ HEADERS += \
|
||||
qfile.h \
|
||||
qfileinfo.h \
|
||||
qglobal.h \
|
||||
qgregoriancalendar_p.h \
|
||||
qhash.h \
|
||||
qiodevice.h \
|
||||
qjson_p.h \
|
||||
@ -194,6 +201,7 @@ HEADERS += \
|
||||
qmetatype.h \
|
||||
qnumeric.h \
|
||||
qregexp.h \
|
||||
qromancalendar_p.h \
|
||||
qstring.h \
|
||||
qstringlist.h \
|
||||
qstringmatcher.h \
|
||||
|
@ -72,6 +72,10 @@
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
#include "private/qcalendarbackend_p.h"
|
||||
#include "private/qgregoriancalendar_p.h"
|
||||
#include "qcalendar.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
@ -341,8 +345,10 @@ QByteArray QLocalePrivate::bcp47Name(char separator) const
|
||||
return localeId.withLikelySubtagsRemoved().name(separator);
|
||||
}
|
||||
|
||||
static const QLocaleData *findLocaleDataById(const QLocaleId &localeId)
|
||||
static const QLocaleData *findLocaleDataById(const QLocaleId &lid)
|
||||
{
|
||||
QLocaleId localeId = lid.withLikelySubtagsAdded();
|
||||
|
||||
const uint idx = locale_index[localeId.language_id];
|
||||
|
||||
const QLocaleData *data = locale_data + idx;
|
||||
@ -443,6 +449,12 @@ const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLoca
|
||||
return locale_data + idx;
|
||||
}
|
||||
|
||||
uint QLocaleData::findLocaleOffset(QLocale::Language language, QLocale::Script script,
|
||||
QLocale::Country country)
|
||||
{
|
||||
return findLocaleData(language, script, country) - locale_data;
|
||||
}
|
||||
|
||||
static bool parse_locale_tag(const QString &input, int &i, QString *result,
|
||||
const QString &separators)
|
||||
{
|
||||
@ -550,6 +562,16 @@ static const QLocaleData *findLocaleData(const QString &name)
|
||||
return QLocaleData::findLocaleData(lang, script, cntry);
|
||||
}
|
||||
|
||||
static uint findLocaleOffset(const QString &name)
|
||||
{
|
||||
QLocale::Language lang;
|
||||
QLocale::Script script;
|
||||
QLocale::Country cntry;
|
||||
QLocalePrivate::getLangAndCountry(name, lang, script, cntry);
|
||||
|
||||
return QLocaleData::findLocaleOffset(lang, script, cntry);
|
||||
}
|
||||
|
||||
QString qt_readEscapedFormatString(QStringView format, int *idx)
|
||||
{
|
||||
int &i = *idx;
|
||||
@ -617,8 +639,8 @@ static QLocale::NumberOptions default_number_options = QLocale::DefaultNumberOpt
|
||||
static const QLocaleData *const c_data = locale_data;
|
||||
static QLocalePrivate *c_private()
|
||||
{
|
||||
static QLocalePrivate c_locale =
|
||||
{ c_data, Q_BASIC_ATOMIC_INITIALIZER(1), QLocale::OmitGroupSeparator };
|
||||
static QLocalePrivate c_locale{
|
||||
c_data, Q_BASIC_ATOMIC_INITIALIZER(1), 0, QLocale::OmitGroupSeparator };
|
||||
return &c_locale;
|
||||
}
|
||||
|
||||
@ -803,9 +825,11 @@ static QLocalePrivate *localePrivateByName(const QString &name)
|
||||
{
|
||||
if (name == QLatin1String("C"))
|
||||
return c_private();
|
||||
// TODO: Remove this version, and use offset everywhere
|
||||
const QLocaleData *data = findLocaleData(name);
|
||||
return QLocalePrivate::create(data, data->m_language_id == QLocale::C ?
|
||||
QLocale::OmitGroupSeparator : QLocale::DefaultNumberOptions);
|
||||
return QLocalePrivate::create(data, findLocaleOffset(name),
|
||||
data->m_language_id == QLocale::C
|
||||
? QLocale::OmitGroupSeparator : QLocale::DefaultNumberOptions);
|
||||
}
|
||||
|
||||
static QLocalePrivate *findLocalePrivate(QLocale::Language language, QLocale::Script script,
|
||||
@ -814,7 +838,9 @@ static QLocalePrivate *findLocalePrivate(QLocale::Language language, QLocale::Sc
|
||||
if (language == QLocale::C)
|
||||
return c_private();
|
||||
|
||||
// TODO: Remove pointer, use index instead
|
||||
const QLocaleData *data = QLocaleData::findLocaleData(language, script, country);
|
||||
const uint offset = QLocaleData::findLocaleOffset(language, script, country);
|
||||
|
||||
QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions;
|
||||
|
||||
@ -823,7 +849,7 @@ static QLocalePrivate *findLocalePrivate(QLocale::Language language, QLocale::Sc
|
||||
numberOptions = default_number_options;
|
||||
data = defaultData();
|
||||
}
|
||||
return QLocalePrivate::create(data, numberOptions);
|
||||
return QLocalePrivate::create(data, offset, numberOptions);
|
||||
}
|
||||
|
||||
|
||||
@ -1957,7 +1983,7 @@ QString QLocale::toString(qulonglong i) const
|
||||
|
||||
QString QLocale::toString(const QDate &date, const QString &format) const
|
||||
{
|
||||
return d->dateTimeToString(format, QDateTime(), date, QTime(), this);
|
||||
return QCalendar().dateTimeToString(format, QDateTime(), date, QTime(), *this);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1972,7 +1998,7 @@ QString QLocale::toString(const QDate &date, const QString &format) const
|
||||
*/
|
||||
QString QLocale::toString(const QDate &date, QStringView format) const
|
||||
{
|
||||
return d->dateTimeToString(format, QDateTime(), date, QTime(), this);
|
||||
return QCalendar().dateTimeToString(format, QDateTime(), date, QTime(), *this);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2027,7 +2053,7 @@ static bool timeFormatContainsAP(QStringView format)
|
||||
*/
|
||||
QString QLocale::toString(const QTime &time, const QString &format) const
|
||||
{
|
||||
return d->dateTimeToString(format, QDateTime(), QDate(), time, this);
|
||||
return QCalendar().dateTimeToString(format, QDateTime(), QDate(), time, *this);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2042,7 +2068,7 @@ QString QLocale::toString(const QTime &time, const QString &format) const
|
||||
*/
|
||||
QString QLocale::toString(const QTime &time, QStringView format) const
|
||||
{
|
||||
return d->dateTimeToString(format, QDateTime(), QDate(), time, this);
|
||||
return QCalendar().dateTimeToString(format, QDateTime(), QDate(), time, *this);
|
||||
}
|
||||
|
||||
#if QT_STRINGVIEW_LEVEL < 2
|
||||
@ -2058,7 +2084,7 @@ QString QLocale::toString(const QTime &time, QStringView format) const
|
||||
|
||||
QString QLocale::toString(const QDateTime &dateTime, const QString &format) const
|
||||
{
|
||||
return d->dateTimeToString(format, dateTime, QDate(), QTime(), this);
|
||||
return QCalendar().dateTimeToString(format, dateTime, QDate(), QTime(), *this);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2073,7 +2099,58 @@ QString QLocale::toString(const QDateTime &dateTime, const QString &format) cons
|
||||
*/
|
||||
QString QLocale::toString(const QDateTime &dateTime, QStringView format) const
|
||||
{
|
||||
return d->dateTimeToString(format, dateTime, QDate(), QTime(), this);
|
||||
return QCalendar().dateTimeToString(format, dateTime, QDate(), QTime(), *this);
|
||||
}
|
||||
|
||||
QString QLocale::toString(const QDate &date, QStringView format, QCalendar cal) const
|
||||
{
|
||||
return cal.dateTimeToString(format, QDateTime(), date, QTime(), *this);
|
||||
}
|
||||
|
||||
QString QLocale::toString(const QDate &date, QLocale::FormatType format, QCalendar cal) const
|
||||
{
|
||||
if (!date.isValid())
|
||||
return QString();
|
||||
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
if (cal.isGregorian() && d->m_data == systemData()) {
|
||||
QVariant res = systemLocale()->query(format == LongFormat
|
||||
? QSystemLocale::DateToStringLong
|
||||
: QSystemLocale::DateToStringShort,
|
||||
date);
|
||||
if (!res.isNull())
|
||||
return res.toString();
|
||||
}
|
||||
#endif
|
||||
|
||||
QString format_str = dateFormat(format);
|
||||
return toString(date, format_str, cal);
|
||||
}
|
||||
|
||||
QString QLocale::toString(const QDateTime &dateTime, QLocale::FormatType format,
|
||||
QCalendar cal) const
|
||||
{
|
||||
if (!dateTime.isValid())
|
||||
return QString();
|
||||
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
if (cal.isGregorian() && d->m_data == systemData()) {
|
||||
QVariant res = systemLocale()->query(format == LongFormat
|
||||
? QSystemLocale::DateTimeToStringLong
|
||||
: QSystemLocale::DateTimeToStringShort,
|
||||
dateTime);
|
||||
if (!res.isNull())
|
||||
return res.toString();
|
||||
}
|
||||
#endif
|
||||
|
||||
const QString format_str = dateTimeFormat(format);
|
||||
return toString(dateTime, format_str, cal);
|
||||
}
|
||||
|
||||
QString QLocale::toString(const QDateTime &dateTime, QStringView format, QCalendar cal) const
|
||||
{
|
||||
return cal.dateTimeToString(format, dateTime, QDate(), QTime(), *this);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2232,6 +2309,7 @@ QString QLocale::dateTimeFormat(FormatType format) const
|
||||
return dateFormat(format) + QLatin1Char(' ') + timeFormat(format);
|
||||
}
|
||||
|
||||
#if QT_CONFIG(datestring)
|
||||
/*!
|
||||
\since 4.4
|
||||
|
||||
@ -2243,12 +2321,19 @@ QString QLocale::dateTimeFormat(FormatType format) const
|
||||
|
||||
\sa timeFormat(), toDate(), toDateTime(), QTime::fromString()
|
||||
*/
|
||||
#if QT_CONFIG(datestring)
|
||||
QTime QLocale::toTime(const QString &string, FormatType format) const
|
||||
{
|
||||
return toTime(string, timeFormat(format));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
\overload
|
||||
*/
|
||||
QTime QLocale::toTime(const QString &string, FormatType format, QCalendar cal) const
|
||||
{
|
||||
return toTime(string, timeFormat(format), cal);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 4.4
|
||||
@ -2261,12 +2346,19 @@ QTime QLocale::toTime(const QString &string, FormatType format) const
|
||||
|
||||
\sa dateFormat(), toTime(), toDateTime(), QDate::fromString()
|
||||
*/
|
||||
#if QT_CONFIG(datestring)
|
||||
QDate QLocale::toDate(const QString &string, FormatType format) const
|
||||
{
|
||||
return toDate(string, dateFormat(format));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
\overload
|
||||
*/
|
||||
QDate QLocale::toDate(const QString &string, FormatType format, QCalendar cal) const
|
||||
{
|
||||
return toDate(string, dateFormat(format), cal);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 4.4
|
||||
@ -2279,13 +2371,19 @@ QDate QLocale::toDate(const QString &string, FormatType format) const
|
||||
|
||||
\sa dateTimeFormat(), toTime(), toDate(), QDateTime::fromString()
|
||||
*/
|
||||
|
||||
#if QT_CONFIG(datestring)
|
||||
QDateTime QLocale::toDateTime(const QString &string, FormatType format) const
|
||||
{
|
||||
return toDateTime(string, dateTimeFormat(format));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
\overload
|
||||
*/
|
||||
QDateTime QLocale::toDateTime(const QString &string, FormatType format, QCalendar cal) const
|
||||
{
|
||||
return toDateTime(string, dateTimeFormat(format), cal);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 4.4
|
||||
@ -2298,22 +2396,30 @@ QDateTime QLocale::toDateTime(const QString &string, FormatType format) const
|
||||
|
||||
\sa timeFormat(), toDate(), toDateTime(), QTime::fromString()
|
||||
*/
|
||||
#if QT_CONFIG(datestring)
|
||||
QTime QLocale::toTime(const QString &string, const QString &format) const
|
||||
{
|
||||
return toTime(string, format, QCalendar());
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
\overload
|
||||
*/
|
||||
QTime QLocale::toTime(const QString &string, const QString &format, QCalendar cal) const
|
||||
{
|
||||
QTime time;
|
||||
#if QT_CONFIG(datetimeparser)
|
||||
QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
|
||||
QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString, cal);
|
||||
dt.setDefaultLocale(*this);
|
||||
if (dt.parseFormat(format))
|
||||
dt.fromString(string, 0, &time);
|
||||
#else
|
||||
Q_UNUSED(cal);
|
||||
Q_UNUSED(string);
|
||||
Q_UNUSED(format);
|
||||
#endif
|
||||
return time;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\since 4.4
|
||||
@ -2329,22 +2435,30 @@ QTime QLocale::toTime(const QString &string, const QString &format) const
|
||||
|
||||
\sa dateFormat(), toTime(), toDateTime(), QDate::fromString()
|
||||
*/
|
||||
#if QT_CONFIG(datestring)
|
||||
QDate QLocale::toDate(const QString &string, const QString &format) const
|
||||
{
|
||||
return toDate(string, format, QCalendar());
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
\overload
|
||||
*/
|
||||
QDate QLocale::toDate(const QString &string, const QString &format, QCalendar cal) const
|
||||
{
|
||||
QDate date;
|
||||
#if QT_CONFIG(datetimeparser)
|
||||
QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
|
||||
QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString, cal);
|
||||
dt.setDefaultLocale(*this);
|
||||
if (dt.parseFormat(format))
|
||||
dt.fromString(string, &date, 0);
|
||||
#else
|
||||
Q_UNUSED(string);
|
||||
Q_UNUSED(format);
|
||||
Q_UNUSED(cal);
|
||||
#endif
|
||||
return date;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\since 4.4
|
||||
@ -2360,25 +2474,33 @@ QDate QLocale::toDate(const QString &string, const QString &format) const
|
||||
|
||||
\sa dateTimeFormat(), toTime(), toDate(), QDateTime::fromString()
|
||||
*/
|
||||
#if QT_CONFIG(datestring)
|
||||
QDateTime QLocale::toDateTime(const QString &string, const QString &format) const
|
||||
{
|
||||
return toDateTime(string, format, QCalendar());
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
\overload
|
||||
*/
|
||||
QDateTime QLocale::toDateTime(const QString &string, const QString &format, QCalendar cal) const
|
||||
{
|
||||
#if QT_CONFIG(datetimeparser)
|
||||
QTime time;
|
||||
QDate date;
|
||||
|
||||
QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString);
|
||||
QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString, cal);
|
||||
dt.setDefaultLocale(*this);
|
||||
if (dt.parseFormat(format) && dt.fromString(string, &date, &time))
|
||||
return QDateTime(date, time);
|
||||
#else
|
||||
Q_UNUSED(string);
|
||||
Q_UNUSED(format);
|
||||
Q_UNUSED(cal);
|
||||
#endif
|
||||
return QDateTime(QDate(), QTime(-1, -1, -1));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // datestring
|
||||
|
||||
/*!
|
||||
\since 4.1
|
||||
@ -2623,38 +2745,7 @@ QList<QLocale::Country> QLocale::countriesForLanguage(Language language)
|
||||
*/
|
||||
QString QLocale::monthName(int month, FormatType type) const
|
||||
{
|
||||
if (month < 1 || month > 12)
|
||||
return QString();
|
||||
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
if (d->m_data == systemData()) {
|
||||
QVariant res = systemLocale()->query(type == LongFormat
|
||||
? QSystemLocale::MonthNameLong
|
||||
: QSystemLocale::MonthNameShort,
|
||||
month);
|
||||
if (!res.isNull())
|
||||
return res.toString();
|
||||
}
|
||||
#endif
|
||||
|
||||
quint32 idx, size;
|
||||
switch (type) {
|
||||
case QLocale::LongFormat:
|
||||
idx = d->m_data->m_long_month_names_idx;
|
||||
size = d->m_data->m_long_month_names_size;
|
||||
break;
|
||||
case QLocale::ShortFormat:
|
||||
idx = d->m_data->m_short_month_names_idx;
|
||||
size = d->m_data->m_short_month_names_size;
|
||||
break;
|
||||
case QLocale::NarrowFormat:
|
||||
idx = d->m_data->m_narrow_month_names_idx;
|
||||
size = d->m_data->m_narrow_month_names_size;
|
||||
break;
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
return getLocaleListData(months_data + idx, size, month - 1);
|
||||
return QCalendar().monthName(*this, month, QCalendar::Unspecified, type);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2670,41 +2761,7 @@ QString QLocale::monthName(int month, FormatType type) const
|
||||
*/
|
||||
QString QLocale::standaloneMonthName(int month, FormatType type) const
|
||||
{
|
||||
if (month < 1 || month > 12)
|
||||
return QString();
|
||||
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
if (d->m_data == systemData()) {
|
||||
QVariant res = systemLocale()->query(type == LongFormat
|
||||
? QSystemLocale::StandaloneMonthNameLong
|
||||
: QSystemLocale::StandaloneMonthNameShort,
|
||||
month);
|
||||
if (!res.isNull())
|
||||
return res.toString();
|
||||
}
|
||||
#endif
|
||||
|
||||
quint32 idx, size;
|
||||
switch (type) {
|
||||
case QLocale::LongFormat:
|
||||
idx = d->m_data->m_standalone_long_month_names_idx;
|
||||
size = d->m_data->m_standalone_long_month_names_size;
|
||||
break;
|
||||
case QLocale::ShortFormat:
|
||||
idx = d->m_data->m_standalone_short_month_names_idx;
|
||||
size = d->m_data->m_standalone_short_month_names_size;
|
||||
break;
|
||||
case QLocale::NarrowFormat:
|
||||
idx = d->m_data->m_standalone_narrow_month_names_idx;
|
||||
size = d->m_data->m_standalone_narrow_month_names_size;
|
||||
break;
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
QString name = getLocaleListData(months_data + idx, size, month - 1);
|
||||
if (name.isEmpty())
|
||||
return monthName(month, type);
|
||||
return name;
|
||||
return QCalendar().standaloneMonthName(*this, month, QCalendar::Unspecified, type);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2718,40 +2775,7 @@ QString QLocale::standaloneMonthName(int month, FormatType type) const
|
||||
*/
|
||||
QString QLocale::dayName(int day, FormatType type) const
|
||||
{
|
||||
if (day < 1 || day > 7)
|
||||
return QString();
|
||||
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
if (d->m_data == systemData()) {
|
||||
QVariant res = systemLocale()->query(type == LongFormat
|
||||
? QSystemLocale::DayNameLong
|
||||
: QSystemLocale::DayNameShort,
|
||||
day);
|
||||
if (!res.isNull())
|
||||
return res.toString();
|
||||
}
|
||||
#endif
|
||||
if (day == 7)
|
||||
day = 0;
|
||||
|
||||
quint32 idx, size;
|
||||
switch (type) {
|
||||
case QLocale::LongFormat:
|
||||
idx = d->m_data->m_long_day_names_idx;
|
||||
size = d->m_data->m_long_day_names_size;
|
||||
break;
|
||||
case QLocale::ShortFormat:
|
||||
idx = d->m_data->m_short_day_names_idx;
|
||||
size = d->m_data->m_short_day_names_size;
|
||||
break;
|
||||
case QLocale::NarrowFormat:
|
||||
idx = d->m_data->m_narrow_day_names_idx;
|
||||
size = d->m_data->m_narrow_day_names_size;
|
||||
break;
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
return getLocaleListData(days_data + idx, size, day);
|
||||
return QCalendar().weekDayName(*this, day, type);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2767,13 +2791,191 @@ QString QLocale::dayName(int day, FormatType type) const
|
||||
\sa dayName(), standaloneMonthName()
|
||||
*/
|
||||
QString QLocale::standaloneDayName(int day, FormatType type) const
|
||||
{
|
||||
return QCalendar().standaloneWeekDayName(*this, day, type);
|
||||
}
|
||||
|
||||
// Calendar look-up of month and day names:
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
|
||||
static QString rawMonthName(const QCalendarLocale &localeData,
|
||||
const ushort *monthsData, int month,
|
||||
QLocale::FormatType type)
|
||||
{
|
||||
quint32 idx, size;
|
||||
switch (type) {
|
||||
case QLocale::LongFormat:
|
||||
idx = localeData.m_long.index;
|
||||
size = localeData.m_long.size;
|
||||
break;
|
||||
case QLocale::ShortFormat:
|
||||
idx = localeData.m_short.index;
|
||||
size = localeData.m_short.size;
|
||||
break;
|
||||
case QLocale::NarrowFormat:
|
||||
idx = localeData.m_narrow.index;
|
||||
size = localeData.m_narrow.size;
|
||||
break;
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
return getLocaleListData(monthsData + idx, size, month - 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
|
||||
static QString rawStandaloneMonthName(const QCalendarLocale &localeData,
|
||||
const ushort *monthsData, int month,
|
||||
QLocale::FormatType type)
|
||||
{
|
||||
quint32 idx, size;
|
||||
switch (type) {
|
||||
case QLocale::LongFormat:
|
||||
idx = localeData.m_standalone_long.index;
|
||||
size = localeData.m_standalone_long.size;
|
||||
break;
|
||||
case QLocale::ShortFormat:
|
||||
idx = localeData.m_standalone_short.index;
|
||||
size = localeData.m_standalone_short.size;
|
||||
break;
|
||||
case QLocale::NarrowFormat:
|
||||
idx = localeData.m_standalone_narrow.index;
|
||||
size = localeData.m_standalone_narrow.size;
|
||||
break;
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
QString name = getLocaleListData(monthsData + idx, size, month - 1);
|
||||
return name.isEmpty() ? rawMonthName(localeData, monthsData, month, type) : name;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
|
||||
static QString rawWeekDayName(const QLocaleData *data, const int day,
|
||||
QLocale::FormatType type)
|
||||
{
|
||||
quint32 idx, size;
|
||||
switch (type) {
|
||||
case QLocale::LongFormat:
|
||||
idx = data->m_long_day_names_idx;
|
||||
size = data->m_long_day_names_size;
|
||||
break;
|
||||
case QLocale::ShortFormat:
|
||||
idx = data->m_short_day_names_idx;
|
||||
size = data->m_short_day_names_size;
|
||||
break;
|
||||
case QLocale::NarrowFormat:
|
||||
idx = data->m_narrow_day_names_idx;
|
||||
size = data->m_narrow_day_names_size;
|
||||
break;
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
return getLocaleListData(days_data + idx, size, day == 7 ? 0 : day);
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
|
||||
static QString rawStandaloneWeekDayName(const QLocaleData *data, const int day,
|
||||
QLocale::FormatType type)
|
||||
{
|
||||
quint32 idx, size;
|
||||
switch (type) {
|
||||
case QLocale::LongFormat:
|
||||
idx = data->m_standalone_long_day_names_idx;
|
||||
size = data->m_standalone_long_day_names_size;
|
||||
break;
|
||||
case QLocale::ShortFormat:
|
||||
idx = data->m_standalone_short_day_names_idx;
|
||||
size = data->m_standalone_short_day_names_size;
|
||||
break;
|
||||
case QLocale::NarrowFormat:
|
||||
idx = data->m_standalone_narrow_day_names_idx;
|
||||
size = data->m_standalone_narrow_day_names_size;
|
||||
break;
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
QString name = getLocaleListData(days_data + idx, size, day == 7 ? 0 : day);
|
||||
if (name.isEmpty())
|
||||
return rawWeekDayName(data, day, type);
|
||||
return name;
|
||||
}
|
||||
|
||||
// Refugees from qcalendar.cpp that need functions above:
|
||||
|
||||
QString QCalendarBackend::monthName(const QLocale &locale, int month, int,
|
||||
QLocale::FormatType format) const
|
||||
{
|
||||
Q_ASSERT(month >= 1 && month <= maxMonthsInYear());
|
||||
return rawMonthName(localeMonthIndexData()[locale.d->m_data_offset],
|
||||
localeMonthData(), month, format);
|
||||
}
|
||||
|
||||
QString QGregorianCalendar::monthName(const QLocale &locale, int month, int year,
|
||||
QLocale::FormatType format) const
|
||||
{
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
if (locale.d->m_data == systemData()) {
|
||||
Q_ASSERT(month >= 1 && month <= 12);
|
||||
QVariant res = systemLocale()->query(format == QLocale::LongFormat
|
||||
? QSystemLocale::MonthNameLong
|
||||
: QSystemLocale::MonthNameShort,
|
||||
month);
|
||||
if (!res.isNull())
|
||||
return res.toString();
|
||||
}
|
||||
#endif
|
||||
|
||||
return QCalendarBackend::monthName(locale, month, year, format);
|
||||
}
|
||||
|
||||
QString QCalendarBackend::standaloneMonthName(const QLocale &locale, int month, int,
|
||||
QLocale::FormatType format) const
|
||||
{
|
||||
Q_ASSERT(month >= 1 && month <= maxMonthsInYear());
|
||||
return rawStandaloneMonthName(localeMonthIndexData()[locale.d->m_data_offset],
|
||||
localeMonthData(), month, format);
|
||||
}
|
||||
|
||||
QString QGregorianCalendar::standaloneMonthName(const QLocale &locale, int month, int year,
|
||||
QLocale::FormatType format) const
|
||||
{
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
if (locale.d->m_data == systemData()) {
|
||||
Q_ASSERT(month >= 1 && month <= 12);
|
||||
QVariant res = systemLocale()->query(format == QLocale::LongFormat
|
||||
? QSystemLocale::StandaloneMonthNameLong
|
||||
: QSystemLocale::StandaloneMonthNameShort,
|
||||
month);
|
||||
if (!res.isNull())
|
||||
return res.toString();
|
||||
}
|
||||
#endif
|
||||
|
||||
return QCalendarBackend::standaloneMonthName(locale, month, year, format);
|
||||
}
|
||||
|
||||
// Most calendars share the common week-day naming, modulo locale.
|
||||
// Calendars that don't must override these methods.
|
||||
QString QCalendarBackend::weekDayName(const QLocale &locale, int day,
|
||||
QLocale::FormatType format) const
|
||||
{
|
||||
if (day < 1 || day > 7)
|
||||
return QString();
|
||||
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
if (d->m_data == systemData()) {
|
||||
QVariant res = systemLocale()->query(type == LongFormat
|
||||
if (locale.d->m_data == systemData()) {
|
||||
QVariant res = systemLocale()->query(format == QLocale::LongFormat
|
||||
? QSystemLocale::DayNameLong
|
||||
: QSystemLocale::DayNameShort,
|
||||
day);
|
||||
@ -2781,32 +2983,32 @@ QString QLocale::standaloneDayName(int day, FormatType type) const
|
||||
return res.toString();
|
||||
}
|
||||
#endif
|
||||
if (day == 7)
|
||||
day = 0;
|
||||
|
||||
quint32 idx, size;
|
||||
switch (type) {
|
||||
case QLocale::LongFormat:
|
||||
idx = d->m_data->m_standalone_long_day_names_idx;
|
||||
size = d->m_data->m_standalone_long_day_names_size;
|
||||
break;
|
||||
case QLocale::ShortFormat:
|
||||
idx = d->m_data->m_standalone_short_day_names_idx;
|
||||
size = d->m_data->m_standalone_short_day_names_size;
|
||||
break;
|
||||
case QLocale::NarrowFormat:
|
||||
idx = d->m_data->m_standalone_narrow_day_names_idx;
|
||||
size = d->m_data->m_standalone_narrow_day_names_size;
|
||||
break;
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
QString name = getLocaleListData(days_data + idx, size, day);
|
||||
if (name.isEmpty())
|
||||
return dayName(day == 0 ? 7 : day, type);
|
||||
return name;
|
||||
return rawWeekDayName(locale.d->m_data, day, format);
|
||||
}
|
||||
|
||||
QString QCalendarBackend::standaloneWeekDayName(const QLocale &locale, int day,
|
||||
QLocale::FormatType format) const
|
||||
{
|
||||
if (day < 1 || day > 7)
|
||||
return QString();
|
||||
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
if (locale.d->m_data == systemData()) {
|
||||
QVariant res = systemLocale()->query(format == QLocale::LongFormat
|
||||
? QSystemLocale::DayNameLong
|
||||
: QSystemLocale::DayNameShort,
|
||||
day);
|
||||
if (!res.isNull())
|
||||
return res.toString();
|
||||
}
|
||||
#endif
|
||||
|
||||
return rawStandaloneWeekDayName(locale.d->m_data, day, format);
|
||||
}
|
||||
|
||||
// End of this block of qcalendar.cpp refugees. (One more follows.)
|
||||
|
||||
/*!
|
||||
\since 4.8
|
||||
|
||||
@ -3010,10 +3212,11 @@ QString QLocale::pmText() const
|
||||
return getLocaleData(pm_data + d->m_data->m_pm_idx, d->m_data->m_pm_size);
|
||||
}
|
||||
|
||||
// Another intrusion from QCalendar, using some of the tools above:
|
||||
|
||||
QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &datetime,
|
||||
const QDate &dateOnly, const QTime &timeOnly,
|
||||
const QLocale *q) const
|
||||
QString QCalendarBackend::dateTimeToString(QStringView format, const QDateTime &datetime,
|
||||
const QDate &dateOnly, const QTime &timeOnly,
|
||||
const QLocale &locale) const
|
||||
{
|
||||
QDate date;
|
||||
QTime time;
|
||||
@ -3035,6 +3238,15 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da
|
||||
}
|
||||
|
||||
QString result;
|
||||
int year = 0, month = 0, day = 0;
|
||||
if (formatDate) {
|
||||
const auto parts = julianDayToDate(date.toJulianDay());
|
||||
if (!parts.isValid())
|
||||
return QString();
|
||||
year = parts.year;
|
||||
month = parts.month;
|
||||
day = parts.day;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while (i < format.size()) {
|
||||
@ -3057,15 +3269,14 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da
|
||||
|
||||
switch (repeat) {
|
||||
case 4: {
|
||||
const int yr = date.year();
|
||||
const int len = (yr < 0) ? 5 : 4;
|
||||
result.append(m_data->longLongToString(yr, -1, 10, len,
|
||||
QLocaleData::ZeroPadded));
|
||||
const int len = (year < 0) ? 5 : 4;
|
||||
result.append(locale.d->m_data->longLongToString(year, -1, 10, len,
|
||||
QLocaleData::ZeroPadded));
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
result.append(m_data->longLongToString(date.year() % 100, -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
result.append(locale.d->m_data->longLongToString(year % 100, -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
break;
|
||||
default:
|
||||
repeat = 1;
|
||||
@ -3079,17 +3290,17 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da
|
||||
repeat = qMin(repeat, 4);
|
||||
switch (repeat) {
|
||||
case 1:
|
||||
result.append(m_data->longLongToString(date.month()));
|
||||
result.append(locale.d->m_data->longLongToString(month));
|
||||
break;
|
||||
case 2:
|
||||
result.append(m_data->longLongToString(date.month(), -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
result.append(locale.d->m_data->longLongToString(month, -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
break;
|
||||
case 3:
|
||||
result.append(q->monthName(date.month(), QLocale::ShortFormat));
|
||||
result.append(monthName(locale, month, year, QLocale::ShortFormat));
|
||||
break;
|
||||
case 4:
|
||||
result.append(q->monthName(date.month(), QLocale::LongFormat));
|
||||
result.append(monthName(locale, month, year, QLocale::LongFormat));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -3099,17 +3310,19 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da
|
||||
repeat = qMin(repeat, 4);
|
||||
switch (repeat) {
|
||||
case 1:
|
||||
result.append(m_data->longLongToString(date.day()));
|
||||
result.append(locale.d->m_data->longLongToString(day));
|
||||
break;
|
||||
case 2:
|
||||
result.append(m_data->longLongToString(date.day(), -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
result.append(locale.d->m_data->longLongToString(day, -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
break;
|
||||
case 3:
|
||||
result.append(q->dayName(date.dayOfWeek(), QLocale::ShortFormat));
|
||||
result.append(locale.dayName(
|
||||
dayOfWeek(date.toJulianDay()), QLocale::ShortFormat));
|
||||
break;
|
||||
case 4:
|
||||
result.append(q->dayName(date.dayOfWeek(), QLocale::LongFormat));
|
||||
result.append(locale.dayName(
|
||||
dayOfWeek(date.toJulianDay()), QLocale::LongFormat));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -3133,11 +3346,11 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da
|
||||
|
||||
switch (repeat) {
|
||||
case 1:
|
||||
result.append(m_data->longLongToString(hour));
|
||||
result.append(locale.d->m_data->longLongToString(hour));
|
||||
break;
|
||||
case 2:
|
||||
result.append(m_data->longLongToString(hour, -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
result.append(locale.d->m_data->longLongToString(hour, -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -3147,11 +3360,11 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da
|
||||
repeat = qMin(repeat, 2);
|
||||
switch (repeat) {
|
||||
case 1:
|
||||
result.append(m_data->longLongToString(time.hour()));
|
||||
result.append(locale.d->m_data->longLongToString(time.hour()));
|
||||
break;
|
||||
case 2:
|
||||
result.append(m_data->longLongToString(time.hour(), -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
result.append(locale.d->m_data->longLongToString(time.hour(), -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -3161,11 +3374,11 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da
|
||||
repeat = qMin(repeat, 2);
|
||||
switch (repeat) {
|
||||
case 1:
|
||||
result.append(m_data->longLongToString(time.minute()));
|
||||
result.append(locale.d->m_data->longLongToString(time.minute()));
|
||||
break;
|
||||
case 2:
|
||||
result.append(m_data->longLongToString(time.minute(), -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
result.append(locale.d->m_data->longLongToString(time.minute(), -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -3175,11 +3388,11 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da
|
||||
repeat = qMin(repeat, 2);
|
||||
switch (repeat) {
|
||||
case 1:
|
||||
result.append(m_data->longLongToString(time.second()));
|
||||
result.append(locale.d->m_data->longLongToString(time.second()));
|
||||
break;
|
||||
case 2:
|
||||
result.append(m_data->longLongToString(time.second(), -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
result.append(locale.d->m_data->longLongToString(time.second(), -1, 10, 2,
|
||||
QLocaleData::ZeroPadded));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -3187,13 +3400,15 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da
|
||||
case 'a':
|
||||
used = true;
|
||||
repeat = format.mid(i + 1).startsWith(QLatin1Char('p')) ? 2 : 1;
|
||||
result.append(time.hour() < 12 ? q->amText().toLower() : q->pmText().toLower());
|
||||
result.append(time.hour() < 12 ? locale.amText().toLower()
|
||||
: locale.pmText().toLower());
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
used = true;
|
||||
repeat = format.mid(i + 1).startsWith(QLatin1Char('P')) ? 2 : 1;
|
||||
result.append(time.hour() < 12 ? q->amText().toUpper() : q->pmText().toUpper());
|
||||
result.append(time.hour() < 12 ? locale.amText().toUpper()
|
||||
: locale.pmText().toUpper());
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
@ -3202,15 +3417,14 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da
|
||||
|
||||
// note: the millisecond component is treated like the decimal part of the seconds
|
||||
// so ms == 2 is always printed as "002", but ms == 200 can be either "2" or "200"
|
||||
result.append(m_data->longLongToString(time.msec(), -1, 10, 3,
|
||||
QLocaleData::ZeroPadded));
|
||||
result.append(locale.d->m_data->longLongToString(time.msec(), -1, 10, 3,
|
||||
QLocaleData::ZeroPadded));
|
||||
if (repeat == 1) {
|
||||
if (result.endsWith(zero()))
|
||||
if (result.endsWith(locale.d->zero()))
|
||||
result.chop(1);
|
||||
if (result.endsWith(zero()))
|
||||
if (result.endsWith(locale.d->zero()))
|
||||
result.chop(1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 't':
|
||||
@ -3233,6 +3447,8 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da
|
||||
return result;
|
||||
}
|
||||
|
||||
// End of QCalendar intrustions
|
||||
|
||||
QString QLocaleData::doubleToString(double d, int precision, DoubleForm form,
|
||||
int width, unsigned flags) const
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -47,7 +47,7 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class QCalendar;
|
||||
class QDataStream;
|
||||
class QDate;
|
||||
class QDateTime;
|
||||
@ -1013,6 +1013,14 @@ public:
|
||||
QString toString(const QDate &date, FormatType format = LongFormat) const;
|
||||
QString toString(const QTime &time, FormatType format = LongFormat) const;
|
||||
QString toString(const QDateTime &dateTime, FormatType format = LongFormat) const;
|
||||
/* Removing default value for `format' is done intentionally,
|
||||
* after all tests we will remove non-calendar-aware version of these functions,
|
||||
* and add a default value for both calendar instance, and format
|
||||
*/
|
||||
QString toString(const QDate &date, QStringView formatStr, QCalendar cal) const;
|
||||
QString toString(const QDate &date, FormatType format, QCalendar cal) const;
|
||||
QString toString(const QDateTime &dateTime, FormatType format, QCalendar cal) const;
|
||||
QString toString(const QDateTime &dateTime, QStringView formatStr, QCalendar cal) const;
|
||||
|
||||
QString dateFormat(FormatType format = LongFormat) const;
|
||||
QString timeFormat(FormatType format = LongFormat) const;
|
||||
@ -1024,6 +1032,13 @@ public:
|
||||
QDate toDate(const QString &string, const QString &format) const;
|
||||
QTime toTime(const QString &string, const QString &format) const;
|
||||
QDateTime toDateTime(const QString &string, const QString &format) const;
|
||||
// Calendar-aware API
|
||||
QDate toDate(const QString &string, FormatType format, QCalendar cal) const;
|
||||
QTime toTime(const QString &string, FormatType format, QCalendar cal) const;
|
||||
QDateTime toDateTime(const QString &string, FormatType format, QCalendar cal) const;
|
||||
QDate toDate(const QString &string, const QString &format, QCalendar cal) const;
|
||||
QTime toTime(const QString &string, const QString &format, QCalendar cal) const;
|
||||
QDateTime toDateTime(const QString &string, const QString &format, QCalendar cal) const;
|
||||
#endif
|
||||
|
||||
// ### Qt 5: We need to return QString from these function since
|
||||
@ -1108,6 +1123,8 @@ private:
|
||||
QLocale(QLocalePrivate &dd);
|
||||
friend class QLocalePrivate;
|
||||
friend class QSystemLocale;
|
||||
friend class QCalendarBackend;
|
||||
friend class QGregorianCalendar;
|
||||
friend Q_CORE_EXPORT uint qHash(const QLocale &key, uint seed) noexcept;
|
||||
|
||||
QSharedDataPointer<QLocalePrivate> d;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Copyright (C) 2016 Intel Corporation.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
@ -57,6 +57,7 @@
|
||||
#include "QtCore/qvarlengtharray.h"
|
||||
#include "QtCore/qvariant.h"
|
||||
#include "QtCore/qnumeric.h"
|
||||
#include <QtCore/qcalendar.h>
|
||||
|
||||
#include "qlocale.h"
|
||||
|
||||
@ -171,9 +172,14 @@ Q_DECLARE_TYPEINFO(QLocaleId, Q_PRIMITIVE_TYPE);
|
||||
struct QLocaleData
|
||||
{
|
||||
public:
|
||||
// TODO: Remove this?
|
||||
static const QLocaleData *findLocaleData(QLocale::Language language,
|
||||
QLocale::Script script,
|
||||
QLocale::Country country);
|
||||
// Having an offset of current locale, enables us to have multiple sources of data, i.e. user-provided calendar locales
|
||||
static uint findLocaleOffset(QLocale::Language language,
|
||||
QLocale::Script script,
|
||||
QLocale::Country country);
|
||||
static const QLocaleData *c();
|
||||
|
||||
// Maximum number of significant digits needed to represent a double.
|
||||
@ -297,12 +303,6 @@ public:
|
||||
quint16 m_long_date_format_idx, m_long_date_format_size;
|
||||
quint16 m_short_time_format_idx, m_short_time_format_size;
|
||||
quint16 m_long_time_format_idx, m_long_time_format_size;
|
||||
quint16 m_standalone_short_month_names_idx, m_standalone_short_month_names_size;
|
||||
quint16 m_standalone_long_month_names_idx, m_standalone_long_month_names_size;
|
||||
quint16 m_standalone_narrow_month_names_idx, m_standalone_narrow_month_names_size;
|
||||
quint16 m_short_month_names_idx, m_short_month_names_size;
|
||||
quint16 m_long_month_names_idx, m_long_month_names_size;
|
||||
quint16 m_narrow_month_names_idx, m_narrow_month_names_size;
|
||||
quint16 m_standalone_short_day_names_idx, m_standalone_short_day_names_size;
|
||||
quint16 m_standalone_long_day_names_idx, m_standalone_long_day_names_size;
|
||||
quint16 m_standalone_narrow_day_names_idx, m_standalone_narrow_day_names_size;
|
||||
@ -328,22 +328,23 @@ public:
|
||||
quint16 m_weekend_end : 3;
|
||||
};
|
||||
|
||||
class Q_CORE_EXPORT QLocalePrivate
|
||||
class Q_CORE_EXPORT QLocalePrivate // A POD type
|
||||
{
|
||||
public:
|
||||
static QLocalePrivate *create(
|
||||
const QLocaleData *data,
|
||||
const QLocaleData *data, const uint data_offset = 0,
|
||||
QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions)
|
||||
{
|
||||
QLocalePrivate *retval = new QLocalePrivate;
|
||||
auto *retval = new QLocalePrivate;
|
||||
retval->m_data = data;
|
||||
retval->ref.storeRelaxed(0);
|
||||
retval->m_data_offset = data_offset;
|
||||
retval->m_numberOptions = numberOptions;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static QLocalePrivate *get(QLocale &l) { return l.d; }
|
||||
static const QLocalePrivate *get(const QLocale &l) { return l.d; }
|
||||
static const QLocalePrivate *get(const QLocale &l) { return l.d; }
|
||||
|
||||
QChar decimal() const { return QChar(m_data->m_decimal); }
|
||||
QChar group() const { return QChar(m_data->m_group); }
|
||||
@ -374,12 +375,9 @@ public:
|
||||
|
||||
QLocale::MeasurementSystem measurementSystem() const;
|
||||
|
||||
QString dateTimeToString(QStringView format, const QDateTime &datetime,
|
||||
const QDate &dateOnly, const QTime &timeOnly,
|
||||
const QLocale *q) const;
|
||||
|
||||
const QLocaleData *m_data;
|
||||
QBasicAtomicInt ref;
|
||||
uint m_data_offset;
|
||||
QLocale::NumberOptions m_numberOptions;
|
||||
};
|
||||
|
||||
@ -392,7 +390,7 @@ inline QLocalePrivate *QSharedDataPointer<QLocalePrivate>::clone()
|
||||
{
|
||||
// cannot use QLocalePrivate's copy constructor
|
||||
// since it is deleted in C++11
|
||||
return QLocalePrivate::create(d->m_data, d->m_numberOptions);
|
||||
return QLocalePrivate::create(d->m_data, d->m_data_offset, d->m_numberOptions);
|
||||
}
|
||||
|
||||
inline char QLocaleData::digitToCLocale(QChar in) const
|
||||
|
1060
src/corelib/time/qcalendar.cpp
Normal file
1060
src/corelib/time/qcalendar.cpp
Normal file
File diff suppressed because it is too large
Load Diff
174
src/corelib/time/qcalendar.h
Normal file
174
src/corelib/time/qcalendar.h
Normal file
@ -0,0 +1,174 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 QCALENDAR_H
|
||||
#define QCALENDAR_H
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qlocale.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qstringview.h>
|
||||
|
||||
/* Suggested enum names for other calendars known to CLDR (v33.1)
|
||||
|
||||
Not yet implemented - see QCalendar::System - contributions welcome:
|
||||
|
||||
* Buddhist -- Thai Buddhist, to be specific
|
||||
* Chinese
|
||||
* Coptic
|
||||
* Dangi -- Korean
|
||||
* Ethiopic (Amete Mihret - epoch approx. 8 C.E.)
|
||||
* EthiopicAmeteAlem (Amete Alem - epoch approx. 5493 B.C.E; data from
|
||||
type="ethiopic-amete-alem", an alias for type="ethioaa")
|
||||
* Hebrew
|
||||
* Indian -- National
|
||||
* Islamic -- Based on astronomical observations, not predictions, so hard to
|
||||
implement. CLDR's data for type="islamic" apply, unless overridden, to the
|
||||
other Islamic calendar variants.
|
||||
* IslamicTabular -- tabular, astronomical epoch, CLDR type="islamic-tbla"
|
||||
* Saudi -- Saudi Arabia, sighting; CLDR type="islamic-rgsa"
|
||||
* UmmAlQura -- Umm al-Qura, Saudi Arabia, calculated; CLDR type="islamic-umalqura"
|
||||
* Iso8601 -- as Gregorian, but treating ISO 8601 weeks as "months"
|
||||
* Japanese -- Imperial calendar
|
||||
* Minguo -- Republic of China, Taiwan; CLDR type="roc"
|
||||
|
||||
See:
|
||||
http://www.unicode.org/repos/cldr/tags/latest/common/bcp47/calendar.xml
|
||||
|
||||
These can potentially be supported, as features, using CLDR's data; any
|
||||
others shall need hand-crafted localization data; it would probably be best
|
||||
to do that by contributing data for them to CLDR.
|
||||
*/
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QCalendarBackend;
|
||||
class QDate;
|
||||
|
||||
class Q_CORE_EXPORT QCalendar
|
||||
{
|
||||
Q_GADGET
|
||||
public:
|
||||
// (Extra parentheses to suppress bogus reading of min() as a macro.)
|
||||
enum : int { Unspecified = (std::numeric_limits<int>::min)() };
|
||||
struct YearMonthDay
|
||||
{
|
||||
YearMonthDay() = default;
|
||||
YearMonthDay(int y, int m = 1, int d = 1) : year(y), month(m), day(d) {}
|
||||
|
||||
bool isValid() const
|
||||
{ return month != Unspecified && day != Unspecified; }
|
||||
// (The first year supported by QDate has year == Unspecified.)
|
||||
|
||||
int year = Unspecified;
|
||||
int month = Unspecified;
|
||||
int day = Unspecified;
|
||||
};
|
||||
// Feature (\w+)calendar uses CLDR type="\1" data, except as noted in type="..." comments below
|
||||
enum class System {
|
||||
Gregorian, // CLDR: type = "gregory", alias = "gregorian"
|
||||
Last = Gregorian,
|
||||
User = -1
|
||||
};
|
||||
// New entries must be added to the \enum doc in qcalendar.cpp and
|
||||
// handled in QCalendar::fromEnum()
|
||||
Q_ENUM(System)
|
||||
|
||||
explicit QCalendar(); // Gregorian, optimised
|
||||
explicit QCalendar(System system);
|
||||
explicit QCalendar(QLatin1String name);
|
||||
explicit QCalendar(QStringView name);
|
||||
|
||||
// QCalendar is a trivially copyable value type.
|
||||
bool isValid() { return d != nullptr; }
|
||||
|
||||
// Date queries:
|
||||
int daysInMonth(int month, int year = Unspecified) const;
|
||||
int daysInYear(int year) const;
|
||||
int monthsInYear(int year) const;
|
||||
bool isDateValid(int year, int month, int day) const;
|
||||
|
||||
// Leap years:
|
||||
bool isLeapYear(int year) const;
|
||||
|
||||
// Properties of the calendar:
|
||||
bool isGregorian() const;
|
||||
bool isLunar() const;
|
||||
bool isLuniSolar() const;
|
||||
bool isSolar() const;
|
||||
bool isProleptic() const;
|
||||
bool hasYearZero() const;
|
||||
int maxDaysInMonth() const;
|
||||
int minDaysInMonth() const;
|
||||
int maxMonthsInYear() const;
|
||||
QString name() const;
|
||||
|
||||
// QDate conversions:
|
||||
QDate dateFromParts(int year, int month, int day) const;
|
||||
QDate dateFromParts(const YearMonthDay &parts) const;
|
||||
YearMonthDay partsFromDate(QDate date) const;
|
||||
int dayOfWeek(QDate date) const;
|
||||
|
||||
// Month and week-day names (as in QLocale):
|
||||
QString monthName(const QLocale &locale, int month, int year = Unspecified,
|
||||
QLocale::FormatType format=QLocale::LongFormat) const;
|
||||
QString standaloneMonthName(const QLocale &locale, int month, int year = Unspecified,
|
||||
QLocale::FormatType format = QLocale::LongFormat) const;
|
||||
QString weekDayName(const QLocale &locale, int day,
|
||||
QLocale::FormatType format = QLocale::LongFormat) const;
|
||||
QString standaloneWeekDayName(const QLocale &locale, int day,
|
||||
QLocale::FormatType format=QLocale::LongFormat) const;
|
||||
|
||||
// Formatting of date-times:
|
||||
QString dateTimeToString(QStringView format, const QDateTime &datetime,
|
||||
const QDate &dateOnly, const QTime &timeOnly,
|
||||
const QLocale &locale) const;
|
||||
|
||||
// What's available ?
|
||||
static QStringList availableCalendars();
|
||||
private:
|
||||
// Always supplied by QCalendarBackend and expected to be a singleton
|
||||
const QCalendarBackend *d;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QCALENDAR_H
|
144
src/corelib/time/qcalendarbackend_p.h
Normal file
144
src/corelib/time/qcalendarbackend_p.h
Normal file
@ -0,0 +1,144 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 QCALENDAR_BACKEND_P_H
|
||||
#define QCALENDAR_BACKEND_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of calendar implementations. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/qobjectdefs.h>
|
||||
#include <QtCore/qcalendar.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qmap.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// Locale-related parts, mostly handled in ../text/qlocale.cpp
|
||||
struct QLocaleDataEntry {
|
||||
quint16 index, size;
|
||||
};
|
||||
|
||||
struct QCalendarLocale {
|
||||
quint16 m_language_id, m_script_id, m_country_id;
|
||||
// Month name indexes:
|
||||
QLocaleDataEntry m_standalone_short;
|
||||
QLocaleDataEntry m_standalone_long;
|
||||
QLocaleDataEntry m_standalone_narrow;
|
||||
QLocaleDataEntry m_short;
|
||||
QLocaleDataEntry m_long;
|
||||
QLocaleDataEntry m_narrow;
|
||||
};
|
||||
|
||||
// Partial implementation, of methods with common forms, in qcalendar.cpp
|
||||
class Q_CORE_EXPORT QCalendarBackend
|
||||
{
|
||||
friend class QCalendar;
|
||||
public:
|
||||
virtual ~QCalendarBackend();
|
||||
virtual QString name() const = 0;
|
||||
virtual QCalendar::System calendarSystem() const;
|
||||
// Date queries:
|
||||
virtual int daysInMonth(int month, int year = QCalendar::Unspecified) const = 0;
|
||||
virtual int daysInYear(int year) const;
|
||||
virtual int monthsInYear(int year) const;
|
||||
virtual bool isDateValid(int year, int month, int day) const;
|
||||
// Properties of the calendar:
|
||||
virtual bool isLeapYear(int year) const = 0;
|
||||
virtual bool isLunar() const = 0;
|
||||
virtual bool isLuniSolar() const = 0;
|
||||
virtual bool isSolar() const = 0;
|
||||
virtual bool isProleptic() const;
|
||||
virtual bool hasYearZero() const;
|
||||
virtual int maxDaysInMonth() const;
|
||||
virtual int minDaysInMonth() const;
|
||||
virtual int maxMonthsInYear() const;
|
||||
// Julian Day conversions:
|
||||
virtual bool dateToJulianDay(int year, int month, int day, qint64 *jd) const = 0;
|
||||
virtual QCalendar::YearMonthDay julianDayToDate(qint64 jd) const = 0;
|
||||
// Day of week and week numbering:
|
||||
virtual int dayOfWeek(qint64 jd) const;
|
||||
|
||||
// Names of months and week-days (implemented in qlocale.cpp):
|
||||
virtual QString monthName(const QLocale &locale, int month, int year,
|
||||
QLocale::FormatType format) const;
|
||||
virtual QString standaloneMonthName(const QLocale &locale, int month, int year,
|
||||
QLocale::FormatType format) const;
|
||||
virtual QString weekDayName(const QLocale &locale, int day,
|
||||
QLocale::FormatType format) const;
|
||||
virtual QString standaloneWeekDayName(const QLocale &locale, int day,
|
||||
QLocale::FormatType format) const;
|
||||
|
||||
// Formatting of date-times (implemented in qlocale.cpp):
|
||||
virtual QString dateTimeToString(QStringView format, const QDateTime &datetime,
|
||||
const QDate &dateOnly, const QTime &timeOnly,
|
||||
const QLocale &locale) const;
|
||||
|
||||
// Calendar enumeration by name:
|
||||
static QStringList availableCalendars();
|
||||
|
||||
protected:
|
||||
QCalendarBackend(const QString &name, QCalendar::System id = QCalendar::System::User);
|
||||
|
||||
// Locale support:
|
||||
virtual const QCalendarLocale *localeMonthIndexData() const = 0;
|
||||
virtual const ushort *localeMonthData() const = 0;
|
||||
|
||||
bool registerAlias(const QString &name);
|
||||
|
||||
private:
|
||||
// QCalendar's access to its registry:
|
||||
static const QCalendarBackend *fromName(QStringView name);
|
||||
static const QCalendarBackend *fromName(QLatin1String name);
|
||||
// QCalendar's access to singletons:
|
||||
static const QCalendarBackend *fromEnum(QCalendar::System system);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QCALENDAR_BACKEND_P_H
|
77
src/corelib/time/qcalendarmath_p.h
Normal file
77
src/corelib/time/qcalendarmath_p.h
Normal file
@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 QCALENDARMATH_P_H
|
||||
#define QCALENDARMATH_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of q*calendar.cpp. 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
|
||||
|
||||
namespace QRoundingDown {
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
template<typename Int> constexpr Int qDiv(Int a, unsigned b)
|
||||
{ return (a - (a < 0 ? int(b - 1) : 0)) / int(b); }
|
||||
|
||||
template<typename Int> constexpr Int qMod(Int a, unsigned b)
|
||||
{ return a - qDiv(a, b) * b; }
|
||||
|
||||
} // QRoundingDown
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QCALENDARMATH_P_H
|
File diff suppressed because it is too large
Load Diff
@ -54,6 +54,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(NSDate);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QCalendar;
|
||||
class QTimeZone;
|
||||
class QDateTime;
|
||||
|
||||
@ -69,6 +70,7 @@ private:
|
||||
public:
|
||||
Q_DECL_CONSTEXPR QDate() : jd(nullJd()) {}
|
||||
QDate(int y, int m, int d);
|
||||
QDate(int y, int m, int d, QCalendar cal);
|
||||
|
||||
Q_DECL_CONSTEXPR bool isNull() const { return !isValid(); }
|
||||
Q_DECL_CONSTEXPR bool isValid() const { return jd >= minJd() && jd <= maxJd(); }
|
||||
@ -82,6 +84,14 @@ public:
|
||||
int daysInYear() const;
|
||||
int weekNumber(int *yearNum = nullptr) const;
|
||||
|
||||
int year(QCalendar cal) const;
|
||||
int month(QCalendar cal) const;
|
||||
int day(QCalendar cal) const;
|
||||
int dayOfWeek(QCalendar cal) const;
|
||||
int dayOfYear(QCalendar cal) const;
|
||||
int daysInMonth(QCalendar cal) const;
|
||||
int daysInYear(QCalendar cal) 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)
|
||||
@ -103,8 +113,12 @@ public:
|
||||
QString toString(Qt::DateFormat f = Qt::TextDate) const;
|
||||
#if QT_STRINGVIEW_LEVEL < 2
|
||||
QString toString(const QString &format) const;
|
||||
QString toString(const QString &format, QCalendar cal) const;
|
||||
#endif
|
||||
|
||||
QString toString(QStringView format) const;
|
||||
QString toString(Qt::DateFormat f, QCalendar cal) const;
|
||||
QString toString(QStringView format, QCalendar cal) const;
|
||||
#endif
|
||||
#if QT_DEPRECATED_SINCE(5,0)
|
||||
QT_DEPRECATED_X("Use setDate() instead") inline bool setYMD(int y, int m, int d)
|
||||
@ -112,6 +126,7 @@ public:
|
||||
#endif
|
||||
|
||||
bool setDate(int year, int month, int day);
|
||||
bool setDate(int year, int month, int day, QCalendar cal);
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
void getDate(int *year, int *month, int *day); // ### Qt 6: remove
|
||||
@ -121,6 +136,8 @@ public:
|
||||
Q_REQUIRED_RESULT QDate addDays(qint64 days) const;
|
||||
Q_REQUIRED_RESULT QDate addMonths(int months) const;
|
||||
Q_REQUIRED_RESULT QDate addYears(int years) const;
|
||||
Q_REQUIRED_RESULT QDate addMonths(int months, QCalendar cal) const;
|
||||
Q_REQUIRED_RESULT QDate addYears(int years, QCalendar cal) const;
|
||||
qint64 daysTo(const QDate &) const;
|
||||
|
||||
Q_DECL_CONSTEXPR bool operator==(const QDate &other) const { return jd == other.jd; }
|
||||
@ -134,6 +151,7 @@ public:
|
||||
#if QT_CONFIG(datestring)
|
||||
static QDate fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
|
||||
static QDate fromString(const QString &s, const QString &format);
|
||||
static QDate fromString(const QString &s, const QString &format, QCalendar cal);
|
||||
#endif
|
||||
static bool isValid(int y, int m, int d);
|
||||
static bool isLeapYear(int year);
|
||||
@ -353,6 +371,7 @@ public:
|
||||
#if QT_CONFIG(datestring)
|
||||
static QDateTime fromString(const QString &s, Qt::DateFormat f = Qt::TextDate);
|
||||
static QDateTime fromString(const QString &s, const QString &format);
|
||||
static QDateTime fromString(const QString &s, const QString &format, QCalendar cal);
|
||||
#endif
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 8)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -92,11 +92,11 @@ int QDateTimeParser::getDigit(const QDateTime &t, int index) const
|
||||
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 YearSection: return t.date().year(calendar);
|
||||
case MonthSection: return t.date().month(calendar);
|
||||
case DaySection: return t.date().day(calendar);
|
||||
case DayOfWeekSectionShort:
|
||||
case DayOfWeekSectionLong: return t.date().day();
|
||||
case DayOfWeekSectionLong: return t.date().day(calendar);
|
||||
case AmPmSection: return t.time().hour() > 11 ? 1 : 0;
|
||||
|
||||
default: break;
|
||||
@ -138,9 +138,9 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
|
||||
|
||||
const QDate date = v.date();
|
||||
const QTime time = v.time();
|
||||
int year = date.year();
|
||||
int month = date.month();
|
||||
int day = date.day();
|
||||
int year = date.year(calendar);
|
||||
int month = date.month(calendar);
|
||||
int day = date.day(calendar);
|
||||
int hour = time.hour();
|
||||
int minute = time.minute();
|
||||
int second = time.second();
|
||||
@ -184,13 +184,13 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
|
||||
if (!(node.type & DaySectionMask)) {
|
||||
if (day < cachedDay)
|
||||
day = cachedDay;
|
||||
const int max = QDate(year, month, 1).daysInMonth();
|
||||
const int max = calendar.daysInMonth(month, year);
|
||||
if (day > max) {
|
||||
day = max;
|
||||
}
|
||||
}
|
||||
|
||||
const QDate newDate(year, month, day);
|
||||
const QDate newDate(year, month, day, calendar);
|
||||
const QTime newTime(hour, minute, second, msec);
|
||||
if (!newDate.isValid() || !newTime.isValid())
|
||||
return false;
|
||||
@ -231,10 +231,10 @@ int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
|
||||
// people from typing in a larger
|
||||
// number in count == 2 sections.
|
||||
// stepBy() will work on real years anyway
|
||||
case MonthSection: return 12;
|
||||
case MonthSection: return calendar.maxMonthsInYear();
|
||||
case DaySection:
|
||||
case DayOfWeekSectionShort:
|
||||
case DayOfWeekSectionLong: return cur.isValid() ? cur.date().daysInMonth() : 31;
|
||||
case DayOfWeekSectionLong: return cur.isValid() ? cur.date().daysInMonth(calendar) : calendar.maxDaysInMonth() ;
|
||||
case AmPmSection: return 1;
|
||||
default: break;
|
||||
}
|
||||
@ -612,7 +612,7 @@ int QDateTimeParser::sectionSize(int sectionIndex) const
|
||||
int QDateTimeParser::sectionMaxSize(Section s, int count) const
|
||||
{
|
||||
#if QT_CONFIG(textdate)
|
||||
int mcount = 12;
|
||||
int mcount = calendar.maxMonthsInYear();
|
||||
#endif
|
||||
|
||||
switch (s) {
|
||||
@ -654,7 +654,7 @@ int QDateTimeParser::sectionMaxSize(Section s, int count) const
|
||||
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)
|
||||
? calendar.monthName(l, i, QCalendar::Unspecified, format)
|
||||
: l.dayName(i, format));
|
||||
ret = qMax(str.size(), ret);
|
||||
}
|
||||
@ -787,9 +787,9 @@ QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex,
|
||||
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, §iontext, &used);
|
||||
const int year = currentValue.date().year(calendar);
|
||||
const int min = (year == minDate.year(calendar)) ? minDate.month(calendar) : 1;
|
||||
num = findMonth(sectiontext.toLower(), min, sectionIndex, year, §iontext, &used);
|
||||
} else {
|
||||
num = findDay(sectiontext.toLower(), 1, sectionIndex, §iontext, &used);
|
||||
}
|
||||
@ -893,6 +893,26 @@ QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex,
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
Returns a day-number, in the same month as \a rough and as close to \a rough's
|
||||
day number as is valid, that \a calendar puts on the day of the week indicated
|
||||
by \a weekDay.
|
||||
*/
|
||||
|
||||
static int weekDayWithinMonth(const QCalendar &calendar, const QDate &rough, int weekDay)
|
||||
{
|
||||
// TODO: can we adapt this to cope gracefully with intercallary days (day of
|
||||
// week > 7) without making it slower for more widely-used calendars ?
|
||||
int day = rough.day(calendar) + weekDay - calendar.dayOfWeek(rough);
|
||||
if (day <= 0)
|
||||
return day + 7;
|
||||
if (day > rough.daysInMonth(calendar))
|
||||
return day - 7;
|
||||
return day;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
@ -901,11 +921,11 @@ QDateTimeParser::parseSection(const QDateTime ¤tValue, int sectionIndex,
|
||||
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)
|
||||
static QDate actualDate(QDateTimeParser::Sections known, const QCalendar &calendar,
|
||||
int year, int year2digits, int month, int day, int dayofweek)
|
||||
{
|
||||
QDate actual(year, month, day);
|
||||
if (actual.isValid() && year % 100 == year2digits && actual.dayOfWeek() == dayofweek)
|
||||
QDate actual(year, month, day, calendar);
|
||||
if (actual.isValid() && year % 100 == year2digits && calendar.dayOfWeek(actual) == dayofweek)
|
||||
return actual; // The obvious candidate is fine :-)
|
||||
|
||||
if (dayofweek < 1 || dayofweek > 7) // Invalid: ignore
|
||||
@ -931,18 +951,18 @@ static QDate actualDate(QDateTimeParser::Sections known, int year, int year2digi
|
||||
known &= ~QDateTimeParser::MonthSection;
|
||||
}
|
||||
|
||||
QDate first(year, month, 1);
|
||||
QDate first(year, month, 1, calendar);
|
||||
int last = known & QDateTimeParser::YearSection && known & QDateTimeParser::MonthSection
|
||||
? first.daysInMonth() : 0;
|
||||
? first.daysInMonth(calendar) : 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;
|
||||
int diff = (dayofweek - calendar.dayOfWeek(first) - 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();
|
||||
day = 1 + dayofweek - calendar.dayOfWeek(first);
|
||||
if (day < 1)
|
||||
day += 7;
|
||||
} else {
|
||||
@ -956,12 +976,12 @@ static QDate actualDate(QDateTimeParser::Sections known, int year, int year2digi
|
||||
day = last;
|
||||
}
|
||||
|
||||
actual = QDate(year, month, day);
|
||||
actual = QDate(year, month, day, calendar);
|
||||
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.
|
||||
|| calendar.dayOfWeek(actual) == dayofweek // Good enough, use it.
|
||||
|| (known & QDateTimeParser::DayOfWeekSectionMask) == 0) { // No contradiction, use it.
|
||||
return actual;
|
||||
}
|
||||
@ -976,12 +996,8 @@ static QDate actualDate(QDateTimeParser::Sections known, int year, int year2digi
|
||||
|
||||
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);
|
||||
day = weekDayWithinMonth(calendar, actual, dayofweek);
|
||||
actual = QDate(year, month, day, calendar);
|
||||
return actual;
|
||||
}
|
||||
|
||||
@ -993,18 +1009,18 @@ static QDate actualDate(QDateTimeParser::Sections known, int year, int year2digi
|
||||
*/
|
||||
for (int m = 1; m < 12; m++) {
|
||||
if (m < month) {
|
||||
actual = QDate(year, month - m, day);
|
||||
if (actual.dayOfWeek() == dayofweek)
|
||||
actual = QDate(year, month - m, day, calendar);
|
||||
if (calendar.dayOfWeek(actual) == dayofweek)
|
||||
return actual;
|
||||
}
|
||||
if (m + month <= 12) {
|
||||
actual = QDate(year, month + m, day);
|
||||
if (actual.dayOfWeek() == dayofweek)
|
||||
actual = QDate(year, month + m, day, calendar);
|
||||
if (calendar.dayOfWeek(actual) == dayofweek)
|
||||
return actual;
|
||||
}
|
||||
}
|
||||
// Should only get here in corner cases; e.g. day == 31
|
||||
actual = QDate(year, month, day); // Restore from trial values.
|
||||
actual = QDate(year, month, day, calendar); // Restore from trial values.
|
||||
}
|
||||
|
||||
if ((known & QDateTimeParser::YearSection) == 0) {
|
||||
@ -1017,24 +1033,24 @@ static QDate actualDate(QDateTimeParser::Sections known, int year, int year2digi
|
||||
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)
|
||||
actual = QDate(year + 100, month, day, calendar);
|
||||
if (calendar.dayOfWeek(actual) == dayofweek)
|
||||
return actual;
|
||||
actual = QDate(year - 100, month, day);
|
||||
if (actual.dayOfWeek() == dayofweek)
|
||||
actual = QDate(year - 100, month, day, calendar);
|
||||
if (calendar.dayOfWeek(actual) == 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)
|
||||
actual = QDate(year - y, month, day, calendar);
|
||||
if (calendar.dayOfWeek(actual) == dayofweek)
|
||||
return actual;
|
||||
actual = QDate(year + y, month, day);
|
||||
if (actual.dayOfWeek() == dayofweek)
|
||||
actual = QDate(year + y, month, day, calendar);
|
||||
if (calendar.dayOfWeek(actual) == dayofweek)
|
||||
return actual;
|
||||
}
|
||||
}
|
||||
actual = QDate(year, month, day); // Restore from trial values.
|
||||
actual = QDate(year, month, day, calendar); // Restore from trial values.
|
||||
}
|
||||
|
||||
return actual; // It'll just have to do :-(
|
||||
@ -1097,7 +1113,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
|
||||
int minute = defaultTime.minute();
|
||||
int second = defaultTime.second();
|
||||
int msec = defaultTime.msec();
|
||||
int dayofweek = defaultDate.dayOfWeek();
|
||||
int dayofweek = calendar.dayOfWeek(defaultDate);
|
||||
Qt::TimeSpec tspec = defaultValue.timeSpec();
|
||||
int zoneOffset = 0; // In seconds; local - UTC
|
||||
#if QT_CONFIG(timezone)
|
||||
@ -1138,7 +1154,8 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
|
||||
ParsedSection sect;
|
||||
|
||||
{
|
||||
const QDate date = actualDate(isSet, year, year2digits, month, day, dayofweek);
|
||||
const QDate date = actualDate(isSet, calendar, year, year2digits,
|
||||
month, day, dayofweek);
|
||||
const QTime time = actualTime(isSet, hour, hour12, ampm, minute, second, msec);
|
||||
sect = parseSection(
|
||||
#if QT_CONFIG(timezone)
|
||||
@ -1248,22 +1265,17 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
|
||||
}
|
||||
}
|
||||
|
||||
const QDate date(year, month, day);
|
||||
const int diff = dayofweek - date.dayOfWeek();
|
||||
if (diff != 0 && state == Acceptable && isSet & DayOfWeekSectionMask) {
|
||||
const QDate date(year, month, day, calendar);
|
||||
if (dayofweek != calendar.dayOfWeek(date)
|
||||
&& 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;
|
||||
}
|
||||
day = weekDayWithinMonth(calendar, date, dayofweek);
|
||||
QDTPDEBUG << year << month << day << dayofweek
|
||||
<< diff << QDate(year, month, day).dayOfWeek();
|
||||
<< calendar.dayOfWeek(QDate(year, month, day, calendar));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1275,20 +1287,18 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
|
||||
needfixday = true;
|
||||
}
|
||||
|
||||
if (!QDate::isValid(year, month, day)) {
|
||||
if (day < 32) {
|
||||
if (!calendar.isDateValid(year, month, day)) {
|
||||
if (day <= calendar.maxDaysInMonth())
|
||||
cachedDay = day;
|
||||
}
|
||||
if (day > 28 && QDate::isValid(year, month, 1)) {
|
||||
if (day > calendar.minDaysInMonth() && calendar.isDateValid(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());
|
||||
day = qMin<int>(day, calendar.daysInMonth(month, year));
|
||||
|
||||
const QLocale loc = locale();
|
||||
for (int i=0; i<sectionNodesCount; ++i) {
|
||||
@ -1296,7 +1306,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
|
||||
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 int dayOfWeek = calendar.dayOfWeek(QDate(year, month, day, calendar));
|
||||
const QLocale::FormatType dayFormat =
|
||||
(sn.type == DayOfWeekSectionShort
|
||||
? QLocale::ShortFormat : QLocale::LongFormat);
|
||||
@ -1333,13 +1343,12 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
|
||||
conflicts = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QDTPDEBUG << year << month << day << hour << minute << second << msec;
|
||||
Q_ASSERT(state != Invalid);
|
||||
|
||||
const QDate date(year, month, day);
|
||||
const QDate date(year, month, day, calendar);
|
||||
const QTime time(hour, minute, second, msec);
|
||||
const QDateTime when =
|
||||
#if QT_CONFIG(timezone)
|
||||
@ -1427,10 +1436,11 @@ QDateTimeParser::parse(QString input, int position, const QDateTime &defaultValu
|
||||
Q_FALLTHROUGH();
|
||||
case MonthSection:
|
||||
if (sn.count >= 3) {
|
||||
const int finalMonth = scan.value.date().month();
|
||||
const QDate when = scan.value.date();
|
||||
const int finalMonth = when.month(calendar);
|
||||
int tmp = finalMonth;
|
||||
// I know the first possible month makes the date too early
|
||||
while ((tmp = findMonth(t, tmp + 1, i)) != -1) {
|
||||
while ((tmp = findMonth(t, tmp + 1, i, when.year(calendar))) != -1) {
|
||||
const QDateTime copy(scan.value.addMonths(tmp - finalMonth));
|
||||
if (copy >= minimum && copy <= maximum)
|
||||
break; // break out of while
|
||||
@ -1566,7 +1576,7 @@ static int findTextEntry(const QString &text, const QVector<QString> &entries, Q
|
||||
*/
|
||||
|
||||
int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionIndex,
|
||||
QString *usedMonth, int *used) const
|
||||
int year, QString *usedMonth, int *used) const
|
||||
{
|
||||
const SectionNode &sn = sectionNode(sectionIndex);
|
||||
if (sn.type != MonthSection) {
|
||||
@ -1579,7 +1589,7 @@ int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionI
|
||||
QVector<QString> monthNames;
|
||||
monthNames.reserve(13 - startMonth);
|
||||
for (int month = startMonth; month <= 12; ++month)
|
||||
monthNames.append(l.monthName(month, type));
|
||||
monthNames.append(calendar.monthName(l, month, year, type));
|
||||
|
||||
const int index = findTextEntry(str1, monthNames, usedMonth, used);
|
||||
return index < 0 ? index : index + startMonth;
|
||||
@ -1877,7 +1887,7 @@ bool QDateTimeParser::potentialValue(const QStringRef &str, int min, int max, in
|
||||
int val = (int)locale().toUInt(str);
|
||||
const SectionNode &sn = sectionNode(index);
|
||||
if (sn.type == YearSection2Digits) {
|
||||
const int year = currentValue.date().year();
|
||||
const int year = currentValue.date().year(calendar);
|
||||
val += year - (year % 100);
|
||||
}
|
||||
if (val >= min && val <= max && str.size() == size) {
|
||||
@ -2047,4 +2057,13 @@ bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::S
|
||||
return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count);
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets \a cal as the calendar to use. The default is Gregorian.
|
||||
*/
|
||||
|
||||
void QDateTimeParser::setCalendar(const QCalendar &cal)
|
||||
{
|
||||
calendar = cal;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -57,6 +57,7 @@
|
||||
#include "QtCore/qdatetime.h"
|
||||
#include "QtCore/qstringlist.h"
|
||||
#include "QtCore/qlocale.h"
|
||||
#include "QtCore/qcalendar.h"
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
# include "QtCore/qvariant.h"
|
||||
#endif
|
||||
@ -82,9 +83,9 @@ public:
|
||||
FromString,
|
||||
DateTimeEdit
|
||||
};
|
||||
QDateTimeParser(QVariant::Type t, Context ctx)
|
||||
QDateTimeParser(QVariant::Type t, Context ctx, const QCalendar &cal = QCalendar())
|
||||
: currentSectionIndex(-1), display(nullptr), cachedDay(-1), parserType(t),
|
||||
fixday(false), spec(Qt::LocalTime), context(ctx)
|
||||
fixday(false), spec(Qt::LocalTime), context(ctx), calendar(cal)
|
||||
{
|
||||
defaultLocale = QLocale::system();
|
||||
first.type = FirstSection;
|
||||
@ -195,6 +196,7 @@ public:
|
||||
|
||||
void setDefaultLocale(const QLocale &loc) { defaultLocale = loc; }
|
||||
virtual QString displayText() const { return text; }
|
||||
void setCalendar(const QCalendar &calendar);
|
||||
|
||||
private:
|
||||
int sectionMaxSize(Section s, int count) const;
|
||||
@ -215,7 +217,7 @@ private:
|
||||
ParsedSection parseSection(const QDateTime ¤tValue, int sectionIndex,
|
||||
int offset, QString *text) const;
|
||||
int findMonth(const QString &str1, int monthstart, int sectionIndex,
|
||||
QString *monthName = nullptr, int *used = nullptr) const;
|
||||
int year, 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,
|
||||
@ -297,6 +299,7 @@ protected: // for the benefit of QDateTimeEditPrivate
|
||||
bool fixday;
|
||||
Qt::TimeSpec spec; // spec if used by QDateTimeEdit
|
||||
Context context;
|
||||
QCalendar calendar;
|
||||
};
|
||||
Q_DECLARE_TYPEINFO(QDateTimeParser::SectionNode, Q_PRIMITIVE_TYPE);
|
||||
|
||||
|
138
src/corelib/time/qgregoriancalendar.cpp
Normal file
138
src/corelib/time/qgregoriancalendar.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 "qgregoriancalendar_p.h"
|
||||
#include "qcalendarmath_p.h"
|
||||
#include <QtCore/qdatetime.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QRoundingDown;
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
|
||||
\class QGregorianCalendar
|
||||
\inmodule QtCore
|
||||
\brief The QGregorianCalendar class implements the Gregorian calendar.
|
||||
|
||||
\section1 The Gregorian Calendar
|
||||
|
||||
The Gregorian calendar is a refinement of the earlier Julian calendar,
|
||||
itself a late form of the Roman calendar. It is widely used.
|
||||
|
||||
\sa QRomanCalendar, QCalendarBackend, QCalendar
|
||||
*/
|
||||
|
||||
QGregorianCalendar::QGregorianCalendar()
|
||||
: QRomanCalendar(QStringLiteral("Gregorian"), QCalendar::System::Gregorian)
|
||||
{
|
||||
registerAlias(QStringLiteral("gregory"));
|
||||
}
|
||||
|
||||
QString QGregorianCalendar::name() const
|
||||
{
|
||||
return QStringLiteral("Gregorian");
|
||||
}
|
||||
|
||||
QCalendar::System QGregorianCalendar::calendarSystem() const
|
||||
{
|
||||
return QCalendar::System::Gregorian;
|
||||
}
|
||||
|
||||
bool QGregorianCalendar::isLeapYear(int year) const
|
||||
{
|
||||
if (year == QCalendar::Unspecified)
|
||||
return false;
|
||||
|
||||
// No year 0 in Gregorian calendar, so -1, -5, -9 etc are leap years
|
||||
if (year < 1)
|
||||
++year;
|
||||
|
||||
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||
}
|
||||
|
||||
bool QGregorianCalendar::dateToJulianDay(int year, int month, int day, qint64 *jd) const
|
||||
{
|
||||
Q_ASSERT(jd);
|
||||
if (!isDateValid(year, month, day))
|
||||
return false;
|
||||
|
||||
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 = month < 3 ? 1 : 0;
|
||||
qint64 y = qint64(year) + 4800 - a;
|
||||
int m = month + 12 * a - 3;
|
||||
*jd = day + qDiv(153 * m + 2, 5) - 32045
|
||||
+ 365 * y + qDiv(y, 4) - qDiv(y, 100) + qDiv(y, 400);
|
||||
return true;
|
||||
}
|
||||
|
||||
QCalendar::YearMonthDay QGregorianCalendar::julianDayToDate(qint64 jd) const
|
||||
{
|
||||
/*
|
||||
* 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 = jd + 32044;
|
||||
qint64 b = qDiv(4 * a + 3, 146097);
|
||||
int c = a - qDiv(146097 * b, 4);
|
||||
|
||||
int d = qDiv(4 * c + 3, 1461);
|
||||
int e = c - qDiv(1461 * d, 4);
|
||||
int m = qDiv(5 * e + 2, 153);
|
||||
|
||||
int y = 100 * b + d - 4800 + qDiv(m, 10);
|
||||
|
||||
// Adjust for no year 0
|
||||
int year = y > 0 ? y : y - 1;
|
||||
int month = m + 3 - 12 * qDiv(m, 10);
|
||||
int day = e - qDiv(153 * m + 2, 5) + 1;
|
||||
|
||||
return QCalendar::YearMonthDay(year, month, day);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
82
src/corelib/time/qgregoriancalendar_p.h
Normal file
82
src/corelib/time/qgregoriancalendar_p.h
Normal file
@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 QGREGORIAN_CALENDAR_P_H
|
||||
#define QGREGORIAN_CALENDAR_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of calendar implementations. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qromancalendar_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_CORE_EXPORT QGregorianCalendar : public QRomanCalendar
|
||||
{
|
||||
// TODO: provide static methods, called by the overrides, that can be called
|
||||
// directly by QDate to optimize various parts.
|
||||
public:
|
||||
QGregorianCalendar();
|
||||
// CAlendar properties:
|
||||
QString name() const override;
|
||||
QCalendar::System calendarSystem() const override;
|
||||
// Date queries:
|
||||
bool isLeapYear(int year) const override;
|
||||
// Julian Day conversions:
|
||||
bool dateToJulianDay(int year, int month, int day, qint64 *jd) const override;
|
||||
QCalendar::YearMonthDay julianDayToDate(qint64 jd) const override;
|
||||
|
||||
// Names of months (implemented in qlocale.cpp):
|
||||
QString monthName(const QLocale &locale, int month, int year,
|
||||
QLocale::FormatType format) const override;
|
||||
QString standaloneMonthName(const QLocale &locale, int month, int year,
|
||||
QLocale::FormatType format) const override;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QGREGORIAN_CALENDAR_P_H
|
105
src/corelib/time/qromancalendar.cpp
Normal file
105
src/corelib/time/qromancalendar.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 "qglobal.h"
|
||||
#include "qromancalendar_p.h"
|
||||
#include "qromancalendar_data_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
|
||||
\class QRomanCalendar
|
||||
\inmodule QtCore
|
||||
\brief The QRomanCalendar class is a shared base for calendars based on the
|
||||
ancient Roman calendar.
|
||||
|
||||
\section1
|
||||
|
||||
Calendars based on the ancient Roman calendar share the names of months, whose
|
||||
lengths depend in a common way on whether the year is a leap year. They differ
|
||||
in how they determine which years are leap years.
|
||||
|
||||
\sa QGregorianCalendar
|
||||
*/
|
||||
|
||||
int QRomanCalendar::daysInMonth(int month, int year) const
|
||||
{
|
||||
if (!year || month < 1 || month > 12)
|
||||
return 0;
|
||||
|
||||
if (month == 2)
|
||||
return isLeapYear(year) ? 29 : 28;
|
||||
|
||||
// Long if odd up to July = 7, or if even from 8 = August onwards:
|
||||
return 30 | ((month & 1) ^ (month >> 3));
|
||||
}
|
||||
|
||||
int QRomanCalendar::minDaysInMonth() const
|
||||
{
|
||||
return 28;
|
||||
}
|
||||
|
||||
bool QRomanCalendar::isLunar() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QRomanCalendar::isLuniSolar() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QRomanCalendar::isSolar() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const QCalendarLocale *QRomanCalendar::localeMonthIndexData() const
|
||||
{
|
||||
return locale_data;
|
||||
}
|
||||
|
||||
const ushort *QRomanCalendar::localeMonthData() const
|
||||
{
|
||||
return months_data;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
2646
src/corelib/time/qromancalendar_data_p.h
Normal file
2646
src/corelib/time/qromancalendar_data_p.h
Normal file
File diff suppressed because it is too large
Load Diff
79
src/corelib/time/qromancalendar_p.h
Normal file
79
src/corelib/time/qromancalendar_p.h
Normal file
@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 QROMAN_CALENDAR_P_H
|
||||
#define QROMAN_CALENDAR_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of calendar implementations. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qcalendarbackend_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_CORE_EXPORT QRomanCalendar : public QCalendarBackend
|
||||
{
|
||||
public:
|
||||
// date queries:
|
||||
int daysInMonth(int month, int year = QCalendar::Unspecified) const override;
|
||||
int minDaysInMonth() const override;
|
||||
// properties of the calendar
|
||||
bool isLunar() const override;
|
||||
bool isLuniSolar() const override;
|
||||
bool isSolar() const override;
|
||||
protected:
|
||||
// locale support:
|
||||
const QCalendarLocale *localeMonthIndexData() const override;
|
||||
const ushort *localeMonthData() const override;
|
||||
// (The INTEGRITY compiler got upset at: using QCalendarBackend:QCalendarBackend;)
|
||||
QRomanCalendar(const QString &name, QCalendar::System id = QCalendar::System::User)
|
||||
: QCalendarBackend(name, id) {}
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QROMAN_CALENDAR_P_H
|
@ -1,10 +1,20 @@
|
||||
# Qt time / date / zone / calendar module
|
||||
|
||||
HEADERS += \
|
||||
time/qcalendar.h \
|
||||
time/qcalendarbackend_p.h \
|
||||
time/qcalendarmath_p.h \
|
||||
time/qdatetime.h \
|
||||
time/qdatetime_p.h
|
||||
time/qdatetime_p.h \
|
||||
time/qgregoriancalendar_p.h \
|
||||
time/qromancalendar_p.h \
|
||||
time/qromancalendar_data_p.h
|
||||
|
||||
SOURCES += time/qdatetime.cpp
|
||||
SOURCES += \
|
||||
time/qdatetime.cpp \
|
||||
time/qcalendar.cpp \
|
||||
time/qgregoriancalendar.cpp \
|
||||
time/qromancalendar.cpp
|
||||
|
||||
qtConfig(timezone) {
|
||||
HEADERS += \
|
||||
|
@ -85,7 +85,10 @@ SOURCES += \
|
||||
../../corelib/text/qstringlist.cpp \
|
||||
../../corelib/text/qstringview.cpp \
|
||||
../../corelib/text/qvsnprintf.cpp \
|
||||
../../corelib/time/qcalendar.cpp \
|
||||
../../corelib/time/qdatetime.cpp \
|
||||
../../corelib/time/qgregoriancalendar.cpp \
|
||||
../../corelib/time/qromancalendar.cpp \
|
||||
../../corelib/tools/qarraydata.cpp \
|
||||
../../corelib/tools/qbitarray.cpp \
|
||||
../../corelib/tools/qcommandlineparser.cpp \
|
||||
|
5
tests/auto/corelib/time/qcalendar/qcalendar.pro
Normal file
5
tests/auto/corelib/time/qcalendar/qcalendar.pro
Normal file
@ -0,0 +1,5 @@
|
||||
CONFIG += testcase
|
||||
TARGET = tst_qcalendar
|
||||
QT = core testlib
|
||||
SOURCES = \
|
||||
tst_qcalendar.cpp
|
219
tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp
Normal file
219
tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp
Normal file
@ -0,0 +1,219 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** 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 General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** 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-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <QCalendar>
|
||||
Q_DECLARE_METATYPE(QCalendar::System)
|
||||
|
||||
class tst_QCalendar : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
void checkYear(const QCalendar &cal, int year, bool normal=false);
|
||||
|
||||
private slots:
|
||||
void basic_data();
|
||||
void basic();
|
||||
void nameCase();
|
||||
void specific_data();
|
||||
void specific();
|
||||
void daily_data() { basic_data(); }
|
||||
void daily();
|
||||
};
|
||||
|
||||
// Support for basic():
|
||||
void tst_QCalendar::checkYear(const QCalendar &cal, int year, bool normal)
|
||||
{
|
||||
const int moons = cal.monthsInYear(year);
|
||||
// Months are numbered from 1 to moons:
|
||||
QVERIFY(moons > 0);
|
||||
QVERIFY(!cal.isDateValid(year, moons + 1, 1));
|
||||
QVERIFY(!cal.isDateValid(year, 0, 1));
|
||||
QVERIFY(moons <= cal.maxMonthsInYear());
|
||||
|
||||
const int days = cal.daysInYear(year);
|
||||
QVERIFY(days > 0);
|
||||
|
||||
int sum = 0;
|
||||
const int longest = cal.maxDaysInMonth();
|
||||
for (int i = moons; i > 0; i--) {
|
||||
const int last = cal.daysInMonth(i, year);
|
||||
sum += last;
|
||||
// Valid month has some days and no more than max:
|
||||
QVERIFY(last > 0);
|
||||
QVERIFY(last <= longest);
|
||||
// Days are numbered from 1 to last:
|
||||
QVERIFY(cal.isDateValid(year, i, 1));
|
||||
QVERIFY(cal.isDateValid(year, i, last));
|
||||
QVERIFY(!cal.isDateValid(year, i, 0));
|
||||
QVERIFY(!cal.isDateValid(year, i, last + 1));
|
||||
if (normal) // Unspecified year gets same daysInMonth():
|
||||
QCOMPARE(cal.daysInMonth(i), last);
|
||||
}
|
||||
// Months add up to the whole year:
|
||||
QCOMPARE(sum, days);
|
||||
}
|
||||
|
||||
#define CHECKYEAR(cal, year) checkYear(cal, year); \
|
||||
if (QTest::currentTestFailed()) \
|
||||
return
|
||||
|
||||
#define NORMALYEAR(cal, year) checkYear(cal, year, true); \
|
||||
if (QTest::currentTestFailed()) \
|
||||
return
|
||||
|
||||
void tst_QCalendar::basic_data()
|
||||
{
|
||||
QTest::addColumn<QCalendar::System>("system");
|
||||
|
||||
QMetaEnum e = QCalendar::staticMetaObject.enumerator(0);
|
||||
Q_ASSERT(qstrcmp(e.name(), "System") == 0);
|
||||
|
||||
for (int i = 0; i <= int(QCalendar::System::Last); ++i) {
|
||||
// There may be gaps in the enum's numbering; and Last is a duplicate:
|
||||
if (e.value(i) != -1 && qstrcmp(e.key(i), "Last"))
|
||||
QTest::newRow(e.key(i)) << QCalendar::System(e.value(i));
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QCalendar::basic()
|
||||
{
|
||||
QFETCH(QCalendar::System, system);
|
||||
QCalendar cal(system);
|
||||
QVERIFY(cal.isValid());
|
||||
QCOMPARE(QCalendar(cal.name()).isGregorian(), cal.isGregorian());
|
||||
QCOMPARE(QCalendar(cal.name()).name(), cal.name());
|
||||
|
||||
if (cal.hasYearZero()) {
|
||||
CHECKYEAR(cal, 0);
|
||||
} else {
|
||||
QCOMPARE(cal.monthsInYear(0), 0);
|
||||
QCOMPARE(cal.daysInYear(0), 0);
|
||||
QVERIFY(!cal.isDateValid(0, 1, 1));
|
||||
}
|
||||
|
||||
if (cal.isProleptic()) {
|
||||
CHECKYEAR(cal, -1);
|
||||
} else {
|
||||
QCOMPARE(cal.monthsInYear(-1), 0);
|
||||
QCOMPARE(cal.daysInYear(-1), 0);
|
||||
QVERIFY(!cal.isDateValid(-1, 1, 1));
|
||||
}
|
||||
|
||||
// Look for a leap year in the last decade.
|
||||
int year = QDate::currentDate().year(cal);
|
||||
for (int i = 10; i > 0 && !cal.isLeapYear(year); --i)
|
||||
--year;
|
||||
if (cal.isLeapYear(year)) {
|
||||
// ... and a non-leap year within a decade before it.
|
||||
int leap = year--;
|
||||
for (int i = 10; i > 0 && cal.isLeapYear(year); --i)
|
||||
year--;
|
||||
if (!cal.isLeapYear(year))
|
||||
QVERIFY(cal.daysInYear(year) < cal.daysInYear(leap));
|
||||
|
||||
CHECKYEAR(cal, leap);
|
||||
}
|
||||
// Either year is non-leap or we have a decade of leap years together;
|
||||
// expect daysInMonth() to treat year the same as unspecified.
|
||||
NORMALYEAR(cal, year);
|
||||
}
|
||||
|
||||
void tst_QCalendar::nameCase()
|
||||
{
|
||||
QVERIFY(QCalendar::availableCalendars().contains(QStringLiteral("Gregorian")));
|
||||
}
|
||||
|
||||
void tst_QCalendar::specific_data()
|
||||
{
|
||||
QTest::addColumn<QCalendar::System>("system");
|
||||
// Date in that system:
|
||||
QTest::addColumn<int>("sysyear");
|
||||
QTest::addColumn<int>("sysmonth");
|
||||
QTest::addColumn<int>("sysday");
|
||||
// Gregorian equivalent:
|
||||
QTest::addColumn<int>("gregyear");
|
||||
QTest::addColumn<int>("gregmonth");
|
||||
QTest::addColumn<int>("gregday");
|
||||
|
||||
#define ADDROW(cal, year, month, day, gy, gm, gd) \
|
||||
QTest::newRow(#cal) << QCalendar::System::cal << year << month << day << gy << gm << gd
|
||||
|
||||
ADDROW(Gregorian, 1970, 1, 1, 1970, 1, 1);
|
||||
|
||||
#undef ADDROW
|
||||
}
|
||||
|
||||
void tst_QCalendar::specific()
|
||||
{
|
||||
QFETCH(QCalendar::System, system);
|
||||
QFETCH(int, sysyear);
|
||||
QFETCH(int, sysmonth);
|
||||
QFETCH(int, sysday);
|
||||
QFETCH(int, gregyear);
|
||||
QFETCH(int, gregmonth);
|
||||
QFETCH(int, gregday);
|
||||
|
||||
const QCalendar cal(system);
|
||||
const QDate date(sysyear, sysmonth, sysday, cal), gregory(gregyear, gregmonth, gregday);
|
||||
QCOMPARE(date, gregory);
|
||||
QCOMPARE(gregory.year(cal), sysyear);
|
||||
QCOMPARE(gregory.month(cal), sysmonth);
|
||||
QCOMPARE(gregory.day(cal), sysday);
|
||||
QCOMPARE(date.year(), gregyear);
|
||||
QCOMPARE(date.month(), gregmonth);
|
||||
QCOMPARE(date.day(), gregday);
|
||||
}
|
||||
|
||||
void tst_QCalendar::daily()
|
||||
{
|
||||
QFETCH(QCalendar::System, system);
|
||||
QCalendar calendar(system);
|
||||
const quint64 startJDN = 0, endJDN = 2488070;
|
||||
// Iterate from -4713-01-01 (Julian calendar) to 2100-01-01
|
||||
for (quint64 expect = startJDN; expect <= endJDN; ++expect)
|
||||
{
|
||||
QDate date = QDate::fromJulianDay(expect);
|
||||
auto parts = calendar.partsFromDate(date);
|
||||
if (!parts.isValid())
|
||||
continue;
|
||||
|
||||
const int year = date.year(calendar);
|
||||
QCOMPARE(year, parts.year);
|
||||
const int month = date.month(calendar);
|
||||
QCOMPARE(month, parts.month);
|
||||
const int day = date.day(calendar);
|
||||
QCOMPARE(day, parts.day);
|
||||
const quint64 actual = QDate(year, month, day, calendar).toJulianDay();
|
||||
QCOMPARE(actual, expect);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_QCalendar)
|
||||
#include "tst_qcalendar.moc"
|
@ -1,5 +1,6 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS = \
|
||||
qcalendar \
|
||||
qdate \
|
||||
qdatetime \
|
||||
qtime \
|
||||
|
@ -1,7 +1,8 @@
|
||||
#!/usr/bin/env python2
|
||||
# coding=utf8
|
||||
#############################################################################
|
||||
##
|
||||
## Copyright (C) 2017 The Qt Company Ltd.
|
||||
## Copyright (C) 2018 The Qt Company Ltd.
|
||||
## Contact: https://www.qt.io/licensing/
|
||||
##
|
||||
## This file is part of the test suite of the Qt Toolkit.
|
||||
@ -62,6 +63,8 @@ from xpathlite import DraftResolution, findAlias, findEntry, findTagsInFile
|
||||
from dateconverter import convert_date
|
||||
from localexml import Locale
|
||||
|
||||
# TODO: make calendars a command-line option
|
||||
calendars = ['gregorian'] # 'persian', 'islamic', 'hebrew'
|
||||
findEntryInFile = xpathlite._findEntryInFile
|
||||
def wrappedwarn(prefix, tokens):
|
||||
return sys.stderr.write(
|
||||
@ -395,12 +398,12 @@ def _generateLocaleInfo(path, language_code, script_code, country_code, variant_
|
||||
('narrow', 'format', 'narrow'),
|
||||
)
|
||||
|
||||
# Month data:
|
||||
for cal in ('gregorian',): # We shall want to add to this
|
||||
# Month names for 12-month calendars:
|
||||
for cal in calendars:
|
||||
stem = 'dates/calendars/calendar[' + cal + ']/months/'
|
||||
for (key, mode, size) in namings:
|
||||
prop = 'monthContext[' + mode + ']/monthWidth[' + size + ']/'
|
||||
result[key + 'Months'] = ';'.join(
|
||||
result[key + 'Months_' + cal] = ';'.join(
|
||||
findEntry(path, stem + prop + "month[%d]" % i)
|
||||
for i in range(1, 13)) + ';'
|
||||
|
||||
@ -686,9 +689,9 @@ if skips:
|
||||
wrappedwarn('skipping likelySubtags (for unknown language codes): ', skips)
|
||||
print " <localeList>"
|
||||
|
||||
Locale.C().toXml()
|
||||
Locale.C(calendars).toXml(calendars)
|
||||
for key in locale_keys:
|
||||
locale_database[key].toXml()
|
||||
locale_database[key].toXml(calendars)
|
||||
|
||||
print " </localeList>"
|
||||
print "</localeDatabase>"
|
||||
|
@ -1,6 +1,7 @@
|
||||
# coding=utf8
|
||||
#############################################################################
|
||||
##
|
||||
## Copyright (C) 2017 The Qt Company Ltd.
|
||||
## Copyright (C) 2018 The Qt Company Ltd.
|
||||
## Contact: https://www.qt.io/licensing/
|
||||
##
|
||||
## This file is part of the test suite of the Qt Toolkit.
|
||||
@ -113,12 +114,11 @@ def convertFormat(format):
|
||||
return result
|
||||
|
||||
class Locale:
|
||||
# Tool used during class body (see del below), not method:
|
||||
def propsMonthDay(lengths=('long', 'short', 'narrow'), scale=('months', 'days')):
|
||||
@staticmethod
|
||||
def propsMonthDay(scale, lengths=('long', 'short', 'narrow')):
|
||||
for L in lengths:
|
||||
for S in scale:
|
||||
yield camelCase((L, S))
|
||||
yield camelCase(('standalone', L, S))
|
||||
yield camelCase((L, scale))
|
||||
yield camelCase(('standalone', L, scale))
|
||||
|
||||
# Expected to be numbers, read with int():
|
||||
__asint = ("decimal", "group", "zero",
|
||||
@ -137,15 +137,13 @@ class Locale:
|
||||
"listPatternPartEnd", "listPatternPartTwo", "am", "pm",
|
||||
'byte_unit', 'byte_si_quantified', 'byte_iec_quantified',
|
||||
"currencyIsoCode", "currencySymbol", "currencyDisplayName",
|
||||
"currencyFormat", "currencyNegativeFormat"
|
||||
) + tuple(propsMonthDay())
|
||||
del propsMonthDay
|
||||
"currencyFormat", "currencyNegativeFormat")
|
||||
|
||||
# Day-of-Week numbering used by Qt:
|
||||
__qDoW = {"mon": 1, "tue": 2, "wed": 3, "thu": 4, "fri": 5, "sat": 6, "sun": 7}
|
||||
|
||||
@classmethod
|
||||
def fromXmlData(cls, lookup):
|
||||
def fromXmlData(cls, lookup, calendars=('gregorian',)):
|
||||
"""Constructor from the contents of XML elements.
|
||||
|
||||
Single parameter, lookup, is called with the names of XML
|
||||
@ -170,12 +168,15 @@ class Locale:
|
||||
for k in cls.__asfmt:
|
||||
data[k] = convertFormat(lookup(k))
|
||||
|
||||
for k in cls.__astxt:
|
||||
for k in cls.__astxt + tuple(cls.propsMonthDay('days')):
|
||||
data[k] = lookup(k)
|
||||
|
||||
for k in cls.propsMonthDay('months'):
|
||||
data[k] = dict((cal, lookup('_'.join((k, cal)))) for cal in calendars)
|
||||
|
||||
return cls(data)
|
||||
|
||||
def toXml(self, indent=' ', tab=' '):
|
||||
def toXml(self, calendars=('gregorian',), indent=' ', tab=' '):
|
||||
print indent + '<locale>'
|
||||
inner = indent + tab
|
||||
get = lambda k: getattr(self, k)
|
||||
@ -199,13 +200,14 @@ class Locale:
|
||||
'weekendStart', 'weekendEnd',
|
||||
'longDateFormat', 'shortDateFormat',
|
||||
'longTimeFormat', 'shortTimeFormat',
|
||||
'standaloneLongMonths', 'standaloneShortMonths',
|
||||
'standaloneNarrowMonths',
|
||||
'longMonths', 'shortMonths', 'narrowMonths',
|
||||
'longDays', 'shortDays', 'narrowDays',
|
||||
'standaloneLongDays', 'standaloneShortDays', 'standaloneNarrowDays',
|
||||
'currencyIsoCode', 'currencySymbol', 'currencyDisplayName',
|
||||
'currencyFormat', 'currencyNegativeFormat'):
|
||||
'currencyFormat', 'currencyNegativeFormat'
|
||||
) + tuple(self.propsMonthDay('days')) + tuple(
|
||||
'_'.join((k, cal))
|
||||
for k in self.propsMonthDay('months')
|
||||
for cal in calendars):
|
||||
ent = camelCase(key.split('_')) if key.endswith('_endonym') else key
|
||||
print inner + "<%s>%s</%s>" % (ent, escape(get(key)).encode('utf-8'), ent)
|
||||
|
||||
@ -218,16 +220,50 @@ class Locale:
|
||||
if data: self.__dict__.update(data)
|
||||
if kw: self.__dict__.update(kw)
|
||||
|
||||
# Tools used by __monthNames:
|
||||
def fullName(i, name): return name
|
||||
def firstThree(i, name): return name[:3]
|
||||
def initial(i, name): return name[:1]
|
||||
def number(i, name): return str(i + 1)
|
||||
@staticmethod
|
||||
def __monthNames(calendars,
|
||||
known={ # Map calendar to (names, extractors...):
|
||||
'gregorian': (('January', 'February', 'March', 'April', 'May', 'June', 'July',
|
||||
'August', 'September', 'October', 'November', 'December'),
|
||||
# Extractor pairs, (plain, standalone)
|
||||
(fullName, fullName), # long
|
||||
(firstThree, firstThree), # short
|
||||
(number, initial)), # narrow
|
||||
'hebrew': (('Tishri', 'Heshvan', 'Kislev', 'Tevet', 'Shevat', 'Adar I',
|
||||
'Adar', 'Nisan', 'Iyar', 'Sivan', 'Tamuz', 'Av'),
|
||||
(fullName, fullName),
|
||||
(fullName, fullName),
|
||||
(number, number)),
|
||||
},
|
||||
sizes=('long', 'short', 'narrow')):
|
||||
for cal in calendars:
|
||||
try:
|
||||
data = known[cal]
|
||||
except KeyError: # Need to add an entry to known, above.
|
||||
print 'Unsupported calendar:', cal
|
||||
raise
|
||||
names, get = data[0] + ('',), data[1:]
|
||||
for n, size in enumerate(sizes):
|
||||
yield ('_'.join((camelCase((size, 'months')), cal)),
|
||||
';'.join(get[n][0](i, x) for i, x in enumerate(names)))
|
||||
yield ('_'.join((camelCase(('standalone', size, 'months')), cal)),
|
||||
';'.join(get[n][1](i, x) for i, x in enumerate(names)))
|
||||
del fullName, firstThree, initial, number
|
||||
|
||||
@classmethod
|
||||
def C(cls,
|
||||
# Empty entries at end to ensure final separator when join()ed:
|
||||
months = ('January', 'February', 'March', 'April', 'May', 'June', 'July',
|
||||
'August', 'September', 'October', 'November', 'December', ''),
|
||||
def C(cls, calendars=('gregorian',),
|
||||
# Empty entry at end to ensure final separator when join()ed:
|
||||
days = ('Sunday', 'Monday', 'Tuesday', 'Wednesday',
|
||||
'Thursday', 'Friday', 'Saturday', ''),
|
||||
quantifiers=('k', 'M', 'G', 'T', 'P', 'E')):
|
||||
"""Returns an object representing the C locale."""
|
||||
return cls(language='C', language_code='0', language_endonym='',
|
||||
return cls(dict(cls.__monthNames(calendars)),
|
||||
language='C', language_code='0', language_endonym='',
|
||||
script='AnyScript', script_code='0',
|
||||
country='AnyCountry', country_code='0', country_endonym='',
|
||||
decimal='.', group=',', list=';', percent='%',
|
||||
@ -245,12 +281,6 @@ class Locale:
|
||||
weekendStart='sat', weekendEnd='sun',
|
||||
longDateFormat='EEEE, d MMMM yyyy', shortDateFormat='d MMM yyyy',
|
||||
longTimeFormat='HH:mm:ss z', shortTimeFormat='HH:mm:ss',
|
||||
longMonths=';'.join(months),
|
||||
shortMonths=';'.join(m[:3] for m in months),
|
||||
narrowMonths='1;2;3;4;5;6;7;8;9;10;11;12;',
|
||||
standaloneLongMonths=';'.join(months),
|
||||
standaloneShortMonths=';'.join(m[:3] for m in months),
|
||||
standaloneNarrowMonths=';'.join(m[:1] for m in months),
|
||||
longDays=';'.join(days),
|
||||
shortDays=';'.join(d[:3] for d in days),
|
||||
narrowDays='7;1;2;3;4;5;6;',
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python2
|
||||
#############################################################################
|
||||
##
|
||||
## Copyright (C) 2017 The Qt Company Ltd.
|
||||
## Copyright (C) 2018 The Qt Company Ltd.
|
||||
## Contact: https://www.qt.io/licensing/
|
||||
##
|
||||
## This file is part of the test suite of the Qt Toolkit.
|
||||
@ -42,6 +42,10 @@ from enumdata import language_aliases, country_aliases, script_aliases
|
||||
|
||||
from localexml import Locale
|
||||
|
||||
# TODO: Make calendars a command-line parameter
|
||||
# map { CLDR name: Qt file name }
|
||||
calendars = {'gregorian': 'roman',} # 'persian': 'jalali', 'islamic': 'hijri', 'hebrew': 'hebrew',
|
||||
|
||||
generated_template = """
|
||||
/*
|
||||
This part of the file was generated on %s from the
|
||||
@ -165,7 +169,7 @@ def loadLocaleMap(doc, language_map, script_map, country_map, likely_subtags_map
|
||||
result = {}
|
||||
|
||||
for locale_elt in eachEltInGroup(doc.documentElement, "localeList", "locale"):
|
||||
locale = Locale.fromXmlData(lambda k: firstChildText(locale_elt, k))
|
||||
locale = Locale.fromXmlData(lambda k: firstChildText(locale_elt, k), calendars.keys())
|
||||
language_id = languageNameToId(locale.language, language_map)
|
||||
if language_id == -1:
|
||||
sys.stderr.write("Cannot find a language id for '%s'\n" % locale.language)
|
||||
@ -268,6 +272,7 @@ class StringData:
|
||||
self.data = []
|
||||
self.hash = {}
|
||||
self.name = name
|
||||
|
||||
def append(self, s):
|
||||
if s in self.hash:
|
||||
return self.hash[s]
|
||||
@ -293,6 +298,11 @@ class StringData:
|
||||
self.data += lst
|
||||
return token
|
||||
|
||||
def write(self, fd):
|
||||
fd.write("\nstatic const ushort %s[] = {\n" % self.name)
|
||||
fd.write(wrap_list(self.data))
|
||||
fd.write("\n};\n")
|
||||
|
||||
def escapedString(s):
|
||||
result = ""
|
||||
i = 0
|
||||
@ -443,7 +453,6 @@ def main():
|
||||
list_pattern_part_data = StringData('list_pattern_part_data')
|
||||
date_format_data = StringData('date_format_data')
|
||||
time_format_data = StringData('time_format_data')
|
||||
months_data = StringData('months_data')
|
||||
days_data = StringData('days_data')
|
||||
am_data = StringData('am_data')
|
||||
pm_data = StringData('pm_data')
|
||||
@ -483,12 +492,6 @@ def main():
|
||||
+ ' lDtFmt '
|
||||
+ ' sTmFmt ' # Time format
|
||||
+ ' lTmFmt '
|
||||
+ ' ssMonth ' # Months
|
||||
+ ' slMonth '
|
||||
+ ' snMonth '
|
||||
+ ' sMonth '
|
||||
+ ' lMonth '
|
||||
+ ' nMonth '
|
||||
+ ' ssDays ' # Days
|
||||
+ ' slDays '
|
||||
+ ' snDays '
|
||||
@ -533,7 +536,7 @@ def main():
|
||||
# Quotation marks:
|
||||
+ '%8d,' * 4
|
||||
# List patterns, date/time formats, month/day names, am/pm:
|
||||
+ '%11s,' * 22
|
||||
+ '%11s,' * 16
|
||||
# SI/IEC byte-unit abbreviations:
|
||||
+ '%8s,' * 3
|
||||
# Currency ISO code:
|
||||
@ -569,12 +572,6 @@ def main():
|
||||
date_format_data.append(l.longDateFormat),
|
||||
time_format_data.append(l.shortTimeFormat),
|
||||
time_format_data.append(l.longTimeFormat),
|
||||
months_data.append(l.standaloneShortMonths),
|
||||
months_data.append(l.standaloneLongMonths),
|
||||
months_data.append(l.standaloneNarrowMonths),
|
||||
months_data.append(l.shortMonths),
|
||||
months_data.append(l.longMonths),
|
||||
months_data.append(l.narrowMonths),
|
||||
days_data.append(l.standaloneShortDays),
|
||||
days_data.append(l.standaloneLongDays),
|
||||
days_data.append(l.standaloneNarrowDays),
|
||||
@ -600,7 +597,7 @@ def main():
|
||||
l.weekendEnd)
|
||||
+ ", // %s/%s/%s\n" % (l.language, l.script, l.country))
|
||||
data_temp_file.write(line_format # All zeros, matching the format:
|
||||
% ( (0,) * (3 + 8 + 4) + ("0,0",) * (22 + 3)
|
||||
% ( (0,) * (3 + 8 + 4) + ("0,0",) * (16 + 3)
|
||||
+ (currencyIsoCodeData(0),)
|
||||
+ ("0,0",) * 6 + (0,) * (2 + 3))
|
||||
+ " // trailing 0s\n")
|
||||
@ -608,13 +605,11 @@ def main():
|
||||
|
||||
# StringData tables:
|
||||
for data in (list_pattern_part_data, date_format_data,
|
||||
time_format_data, months_data, days_data,
|
||||
time_format_data, days_data,
|
||||
byte_unit_data, am_data, pm_data, currency_symbol_data,
|
||||
currency_display_name_data, currency_format_data,
|
||||
endonyms_data):
|
||||
data_temp_file.write("\nstatic const ushort %s[] = {\n" % data.name)
|
||||
data_temp_file.write(wrap_list(data.data))
|
||||
data_temp_file.write("\n};\n")
|
||||
data.write(data_temp_file)
|
||||
|
||||
data_temp_file.write("\n")
|
||||
|
||||
@ -739,6 +734,62 @@ def main():
|
||||
os.remove(qtsrcdir + "/src/corelib/text/qlocale_data_p.h")
|
||||
os.rename(data_temp_file_path, qtsrcdir + "/src/corelib/text/qlocale_data_p.h")
|
||||
|
||||
# Generate calendar data
|
||||
calendar_format = ' {%6d,%6d,%6d,{%5s},{%5s},{%5s},{%5s},{%5s},{%5s}}, '
|
||||
for calendar, stem in calendars.items():
|
||||
months_data = StringData('months_data')
|
||||
calendar_data_file = "q%scalendar_data_p.h" % stem
|
||||
calendar_template_file = open(os.path.join(qtsrcdir, 'src', 'corelib', 'time',
|
||||
calendar_data_file), "r")
|
||||
(calendar_temp_file, calendar_temp_file_path) = tempfile.mkstemp(calendar_data_file, dir=qtsrcdir)
|
||||
calendar_temp_file = os.fdopen(calendar_temp_file, "w")
|
||||
s = calendar_template_file.readline()
|
||||
while s and s != GENERATED_BLOCK_START:
|
||||
calendar_temp_file.write(s)
|
||||
s = calendar_template_file.readline()
|
||||
calendar_temp_file.write(GENERATED_BLOCK_START)
|
||||
calendar_temp_file.write(generated_template % (datetime.date.today(), cldr_version))
|
||||
calendar_temp_file.write("static const QCalendarLocale locale_data[] = {\n")
|
||||
calendar_temp_file.write(' // '
|
||||
# IDs, width 7 (6 + comma)
|
||||
+ ' lang '
|
||||
+ ' script'
|
||||
+ ' terr '
|
||||
# Month-name start-end pairs, width 8 (5 plus '{},'):
|
||||
+ ' sShort '
|
||||
+ ' sLong '
|
||||
+ ' sNarrow'
|
||||
+ ' short '
|
||||
+ ' long '
|
||||
+ ' narrow'
|
||||
# No trailing space on last; be sure
|
||||
# to pad before adding later entries.
|
||||
+ '\n')
|
||||
for key in locale_keys:
|
||||
l = locale_map[key]
|
||||
calendar_temp_file.write(
|
||||
calendar_format
|
||||
% (key[0], key[1], key[2],
|
||||
months_data.append(l.standaloneShortMonths[calendar]),
|
||||
months_data.append(l.standaloneLongMonths[calendar]),
|
||||
months_data.append(l.standaloneNarrowMonths[calendar]),
|
||||
months_data.append(l.shortMonths[calendar]),
|
||||
months_data.append(l.longMonths[calendar]),
|
||||
months_data.append(l.narrowMonths[calendar]))
|
||||
+ "// %s/%s/%s\n " % (l.language, l.script, l.country))
|
||||
calendar_temp_file.write(calendar_format % ( (0,) * 3 + ('0,0',) * 6 )
|
||||
+ '// trailing zeros\n')
|
||||
calendar_temp_file.write("};\n")
|
||||
months_data.write(calendar_temp_file)
|
||||
s = calendar_template_file.readline()
|
||||
while s and s != GENERATED_BLOCK_END:
|
||||
s = calendar_template_file.readline()
|
||||
while s:
|
||||
calendar_temp_file.write(s)
|
||||
s = calendar_template_file.readline()
|
||||
os.rename(calendar_temp_file_path,
|
||||
os.path.join(qtsrcdir, 'src', 'corelib', 'time', calendar_data_file))
|
||||
|
||||
# qlocale.h
|
||||
|
||||
(qlocaleh_temp_file, qlocaleh_temp_file_path) = tempfile.mkstemp("qlocale.h", dir=qtsrcdir)
|
||||
|
Loading…
x
Reference in New Issue
Block a user