summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2021-09-02 14:52:25 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-09-06 19:00:34 +0000
commitcd8a85d1dcd5a72cbb2f1080c70e42bf53d51875 (patch)
treeb60269b7c3e9d34af16de5b0d46f7fb586ce77af
parent5e2564436694b95ed9dfa86fabb95864c68e67d6 (diff)
Fix QLocale::system() standalone day and month handling
Some backends were missing support for standalone days and months, also the standaloneDayName() implementation was always using the same codepath as dayName(). This patch fixes the issues. Support for narrow format will be added in the following patch. Task-number: QTBUG-84877 Change-Id: I38ee06342cafab544e3c69097bd0e6ae68e85645 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit 78dee15da43597126d0a8579cf5db3ec4f019ca8) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/corelib/text/qlocale.cpp4
-rw-r--r--src/corelib/text/qlocale_mac.mm32
-rw-r--r--src/corelib/text/qlocale_p.h4
-rw-r--r--src/corelib/text/qlocale_unix.cpp4
-rw-r--r--src/corelib/text/qlocale_win.cpp4
-rw-r--r--tests/auto/corelib/text/qlocale/tst_qlocale.cpp127
6 files changed, 167 insertions, 8 deletions
diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp
index 3db222d7c9..47da919922 100644
--- a/src/corelib/text/qlocale.cpp
+++ b/src/corelib/text/qlocale.cpp
@@ -2945,8 +2945,8 @@ QString QCalendarBackend::standaloneWeekDayName(const QLocale &locale, int day,
#ifndef QT_NO_SYSTEMLOCALE
if (locale.d->m_data == &systemLocaleData) {
QVariant res = systemLocale()->query(format == QLocale::LongFormat
- ? QSystemLocale::DayNameLong
- : QSystemLocale::DayNameShort,
+ ? QSystemLocale::StandaloneDayNameLong
+ : QSystemLocale::StandaloneDayNameShort,
day);
if (!res.isNull())
return res.toString();
diff --git a/src/corelib/text/qlocale_mac.mm b/src/corelib/text/qlocale_mac.mm
index 2c63902b91..c1d0c28751 100644
--- a/src/corelib/text/qlocale_mac.mm
+++ b/src/corelib/text/qlocale_mac.mm
@@ -99,7 +99,7 @@ static QString macMonthName(int month, QSystemLocale::QueryType type)
return QString();
}
-static QString macDayName(int day, bool short_format)
+static QString macDayName(int day, QSystemLocale::QueryType type)
{
if (day < 1 || day > 7)
return QString();
@@ -107,9 +107,29 @@ static QString macDayName(int day, bool short_format)
QCFType<CFDateFormatterRef> formatter
= CFDateFormatterCreate(0, QCFType<CFLocaleRef>(CFLocaleCopyCurrent()),
kCFDateFormatterNoStyle, kCFDateFormatterNoStyle);
- QCFType<CFArrayRef> values = static_cast<CFArrayRef>(CFDateFormatterCopyProperty(formatter,
- short_format ? kCFDateFormatterShortWeekdaySymbols
- : kCFDateFormatterWeekdaySymbols));
+
+ CFDateFormatterKey formatterType;
+ switch (type) {
+ case QSystemLocale::DayNameLong:
+ formatterType = kCFDateFormatterWeekdaySymbols;
+ break;
+ case QSystemLocale::DayNameShort:
+ formatterType = kCFDateFormatterShortWeekdaySymbols;
+ break;
+ case QSystemLocale::StandaloneDayNameLong:
+ formatterType = kCFDateFormatterStandaloneWeekdaySymbols;
+ break;
+ case QSystemLocale::StandaloneDayNameShort:
+ formatterType = kCFDateFormatterShortStandaloneWeekdaySymbols;
+ break;
+ default:
+ qWarning("macDayName: Unsupported query type %d", type);
+ return QString();
+ }
+
+ QCFType<CFArrayRef> values =
+ static_cast<CFArrayRef>(CFDateFormatterCopyProperty(formatter, formatterType));
+
if (values != 0) {
CFStringRef cfstring = static_cast<CFStringRef>(CFArrayGetValueAtIndex(values, day % 7));
return QString::fromCFString(cfstring);
@@ -446,7 +466,9 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const
: kCFDateFormatterLongStyle);
case DayNameLong:
case DayNameShort:
- return macDayName(in.toInt(), (type == DayNameShort));
+ case StandaloneDayNameLong:
+ case StandaloneDayNameShort:
+ return macDayName(in.toInt(), type);
case MonthNameLong:
case MonthNameShort:
case StandaloneMonthNameLong:
diff --git a/src/corelib/text/qlocale_p.h b/src/corelib/text/qlocale_p.h
index a547dad7b7..a1bd03ca33 100644
--- a/src/corelib/text/qlocale_p.h
+++ b/src/corelib/text/qlocale_p.h
@@ -124,7 +124,9 @@ public:
NativeLanguageName, // QString
NativeTerritoryName, // QString
StandaloneMonthNameLong, // QString, in: int
- StandaloneMonthNameShort // QString, in: int
+ StandaloneMonthNameShort, // QString, in: int
+ StandaloneDayNameLong, // QString, in: int
+ StandaloneDayNameShort // QString, in: int
};
virtual QVariant query(QueryType type, QVariant in = QVariant()) const;
diff --git a/src/corelib/text/qlocale_unix.cpp b/src/corelib/text/qlocale_unix.cpp
index 29053a7074..d47946f9d6 100644
--- a/src/corelib/text/qlocale_unix.cpp
+++ b/src/corelib/text/qlocale_unix.cpp
@@ -194,6 +194,10 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const
return lc_time.dayName(in.toInt(), QLocale::LongFormat);
case DayNameShort:
return lc_time.dayName(in.toInt(), QLocale::ShortFormat);
+ case StandaloneDayNameLong:
+ return lc_time.standaloneDayName(in.toInt(), QLocale::LongFormat);
+ case StandaloneDayNameShort:
+ return lc_time.standaloneDayName(in.toInt(), QLocale::ShortFormat);
case MonthNameLong:
return lc_time.monthName(in.toInt(), QLocale::LongFormat);
case MonthNameShort:
diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp
index 52ad128b9c..212242e216 100644
--- a/src/corelib/text/qlocale_win.cpp
+++ b/src/corelib/text/qlocale_win.cpp
@@ -758,6 +758,10 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const
return d->dayName(in.toInt(), QLocale::LongFormat);
case DayNameShort:
return d->dayName(in.toInt(), QLocale::ShortFormat);
+ case StandaloneDayNameLong:
+ case StandaloneDayNameShort:
+ // Windows does not provide standalone day names, so fall back to CLDR
+ return QVariant();
case MonthNameLong:
return d->monthName(in.toInt(), QLocale::LongFormat);
case StandaloneMonthNameLong:
diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
index 168f7222a9..16521cc2c1 100644
--- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
@@ -148,6 +148,11 @@ private slots:
void systemLocale_data();
void systemLocale();
+#ifndef QT_NO_SYSTEMLOCALE
+ void systemLocaleDayAndMonthNames_data();
+ void systemLocaleDayAndMonthNames();
+#endif
+
void numberGroupingIndia();
void numberFormatChakma();
@@ -3180,6 +3185,128 @@ void tst_QLocale::systemLocale()
QCOMPARE(QLocale::system(), originalSystemLocale);
}
+#ifndef QT_NO_SYSTEMLOCALE
+
+void tst_QLocale::systemLocaleDayAndMonthNames_data()
+{
+ QTest::addColumn<QByteArray>("locale");
+ QTest::addColumn<QDate>("date");
+ QTest::addColumn<QLocale::FormatType>("format");
+ QTest::addColumn<QString>("month");
+ QTest::addColumn<QString>("standaloneMonth");
+ QTest::addColumn<QString>("day");
+ QTest::addColumn<QString>("standaloneDay");
+
+ // en_US and de_DE locale outputs for ICU and macOS are similar.
+ // ru_RU are different.
+ // Windows has its own representation for all of the locales
+
+#if QT_CONFIG(icu)
+ // августа, август, понедельник, понедельник
+ QTest::newRow("ru_RU 30.08.2021 long")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << QString("\u0430\u0432\u0433\u0443\u0441\u0442\u0430")
+ << QString("\u0430\u0432\u0433\u0443\u0441\u0442")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a");
+ // авг., авг., пн, пн
+ QTest::newRow("ru_RU 30.08.2021 short")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << QString("\u0430\u0432\u0433.") << QString("\u0430\u0432\u0433.")
+ << QString("\u043f\u043d") << QString("\u043f\u043d");
+#elif defined(Q_OS_DARWIN)
+ // августа, август, понедельник, понедельник
+ QTest::newRow("ru_RU 30.08.2021 long")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << QString("\u0430\u0432\u0433\u0443\u0441\u0442\u0430")
+ << QString("\u0430\u0432\u0433\u0443\u0441\u0442")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a");
+ // авг., авг., Пн, Пн
+ QTest::newRow("ru_RU 30.08.2021 short")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << QString("\u0430\u0432\u0433.") << QString("\u0430\u0432\u0433.")
+ << QString("\u041f\u043d") << QString("\u041f\u043d");
+#endif
+
+#if QT_CONFIG(icu) || defined(Q_OS_DARWIN)
+ QTest::newRow("en_US 30.08.2021 long")
+ << QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << "August" << "August" << "Monday" << "Monday";
+ QTest::newRow("en_US 30.08.2021 short")
+ << QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << "Aug" << "Aug" << "Mon" << "Mon";
+
+ QTest::newRow("de_DE 30.08.2021 long")
+ << QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << "August" << "August" << "Montag" << "Montag";
+ QTest::newRow("de_DE 30.08.2021 short")
+ << QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << "Aug." << "Aug" << "Mo." << "Mo";
+#elif defined(Q_OS_WIN)
+ // августа, Август, понедельник, понедельник
+ QTest::newRow("ru_RU 30.08.2021 long")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << QString("\u0430\u0432\u0433\u0443\u0441\u0442\u0430")
+ << QString("\u0410\u0432\u0433\u0443\u0441\u0442")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a")
+ << QString("\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a");
+ // авг, авг, Пн, пн
+ QTest::newRow("ru_RU 30.08.2021 short")
+ << QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << QString("\u0430\u0432\u0433") << QString("\u0430\u0432\u0433")
+ << QString("\u041f\u043d") << QString("\u043f\u043d");
+
+ QTest::newRow("en_US 30.08.2021 long")
+ << QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << "August" << "August" << "Monday" << "Monday";
+ QTest::newRow("en_US 30.08.2021 short")
+ << QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << "Aug" << "Aug" << "Mon" << "Mon";
+
+ QTest::newRow("de_DE 30.08.2021 long")
+ << QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::LongFormat
+ << "August" << "August" << "Montag" << "Montag";
+ QTest::newRow("de_DE 30.08.2021 short")
+ << QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::ShortFormat
+ << "Aug" << "Aug" << "Mo" << "Mo";
+#else
+ QSKIP("This test can't run on this OS");
+#endif
+}
+
+void tst_QLocale::systemLocaleDayAndMonthNames()
+{
+ QFETCH(QByteArray, locale);
+ QFETCH(QDate, date);
+ QFETCH(QLocale::FormatType, format);
+ QFETCH(QString, month);
+ QFETCH(QString, standaloneMonth);
+ QFETCH(QString, day);
+ QFETCH(QString, standaloneDay);
+ locale += ".UTF-8"; // So we don't have to repeat it on every data row !
+
+ const TransientLocale tested(LC_ALL, locale.constData());
+
+ QLocale sys = QLocale::system();
+#if !QT_CONFIG(icu)
+ // setlocale() does not really change locale on Windows and macOS, we
+ // need to actually set the locale manually to run the test
+ if (!locale.startsWith(sys.name().toLatin1()))
+ QSKIP(("Set locale to " + locale + " manually to run this test.").constData());
+#endif
+
+ const int m = date.month();
+ QCOMPARE(sys.monthName(m, format), month);
+ QCOMPARE(sys.standaloneMonthName(m, format), standaloneMonth);
+
+ const int d = date.dayOfWeek();
+ QCOMPARE(sys.dayName(d, format), day);
+ QCOMPARE(sys.standaloneDayName(d, format), standaloneDay);
+}
+
+#endif // QT_NO_SYSTEMLOCALE
+
void tst_QLocale::numberGroupingIndia()
{
const QLocale indian(QLocale::Hindi, QLocale::India);