summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-08-17 11:13:18 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2021-09-08 20:28:40 +0200
commit4641ff0f6a1b0da6f55db5e33c58a77be2032808 (patch)
treea46c1a068c321a583af84b5b188b379e9a8da2a4 /tests
parent7e794d71c0bf0f6e812aa1c7794b709889f202fd (diff)
Add new am/pm format-specifier that preserves locale's case
The existing a, ap, A and AP specifiers all force the case of the formatted am/pm indicator. The indicators returned by QLocale's amText() and pmText() methods are those given in CLDR, with no case coercion. Application writers may reasonably want these strings used verbatim, rather than having to chose a case and impose it on the locale's indicators, in defiance of national custom. For example, while en_US uses upper-case indicators by default, cs_CZ uses lower-case ones. An application author writing a time format has been forced to chose which of these locales to be wrong in. Add support for aP and Ap specifiers, whose mixed case indicates that the locale's case is to be respected. Amend an existing test-case of tst_QLocale's formatDateTime() that used Ap (expecting, of course, an upper-case indicator followed by a stray p) to now expect the locale-appropriate-cased indicator. Extend formatTime() to test cases using aP and Ap, to illustrate the difference between en_US and cs_CZ. Rework QDateTimeParser to also support the new format specifier. This required expanding its Case enum, used by the getAmPmText() method, which was formerly shared with QDateTimeEditPrivate; however, as that class no longer makes any reference to this method, it and the enum can be made private, allowing a systematic clean-up of their use. Added test-cases for both serialization and parsing; and amended some existing parsing tests to verify am/pm indicators are matched case-insensitively. [ChangeLog][QtCore][Important Behavior Changes] Time formats used by QLocale, QTime and QDateTime's parsing and serialization now recognize 'aP' and 'Ap' format specifiers to obtain an AM/PM indicator, using the locale-appropriate case for the indicator, where previously the author of a time format had to pick a case that might conflict with the user's locale. For QTime and QDateTime the locale is always C, whose indicators are uppercase. For QLocale, the case will now match that of amText() or pmText(). Previously, 'aP' would have been read as a lower-case indicator followed by a 'P' and 'Ap' as an upper-case indicator followed by a 'p'. The 'P' or 'p' will now be treated as part of the format specifier: if the prior behavior is desired, either use 'APp' or 'apP' as format specifier or quote the 'p' or 'P' in the format. The prior 'a', 'ap', 'A' and 'AP' specifiers are otherwise unaffected. Fixes: QTBUG-95790 Change-Id: I26603f70f068e132b5c6aa63214ac8c1774ec913 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/text/qlocale/tst_qlocale.cpp19
-rw-r--r--tests/auto/corelib/time/qtime/tst_qtime.cpp17
2 files changed, 30 insertions, 6 deletions
diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
index de72c0a4c4..31f9bd9d33 100644
--- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp
@@ -1675,18 +1675,27 @@ void tst_QLocale::formatTime_data()
<< QTime(14, 2, 3) << "en_US" << "h:m:s ap" << "2:2:3 pm";
QTest::newRow("en_US-H:m:s+AP-pm")
<< QTime(14, 2, 3) << "en_US" << "H:m:s AP" << "14:2:3 PM";
+ QTest::newRow("en_US-H:m:s+Ap-pm")
+ << QTime(14, 2, 3) << "en_US" << "H:m:s Ap" << "14:2:3 PM";
QTest::newRow("en_US-h:m:s+ap-am")
<< QTime(1, 2, 3) << "en_US" << "h:m:s ap" << "1:2:3 am";
QTest::newRow("en_US-H:m:s+AP-am")
<< QTime(1, 2, 3) << "en_US" << "H:m:s AP" << "1:2:3 AM";
+ QTest::newRow("en_US-H:m:s+aP-am")
+ << QTime(1, 2, 3) << "en_US" << "H:m:s aP" << "1:2:3 AM";
+
QTest::newRow("cs_CZ-h:m:s+ap-pm")
<< QTime(14, 2, 3) << "cs_CZ" << "h:m:s ap" << "2:2:3 odp.";
QTest::newRow("cs_CZ-h:m:s+AP-pm")
<< QTime(14, 2, 3) << "cs_CZ" << "h:m:s AP" << "2:2:3 ODP.";
+ QTest::newRow("cs_CZ-h:m:s+Ap-pm")
+ << QTime(14, 2, 3) << "cs_CZ" << "h:m:s Ap" << "2:2:3 odp.";
QTest::newRow("cs_CZ-h:m:s+ap-am")
<< QTime(1, 2, 3) << "cs_CZ" << "h:m:s ap" << "1:2:3 dop.";
QTest::newRow("cs_CZ-h:m:s+AP-am")
<< QTime(1, 2, 3) << "cs_CZ" << "h:m:s AP" << "1:2:3 DOP.";
+ QTest::newRow("cs_CZ-h:m:s+aP-am")
+ << QTime(1, 2, 3) << "cs_CZ" << "h:m:s aP" << "1:2:3 dop.";
}
void tst_QLocale::formatTime()
@@ -1810,7 +1819,7 @@ void tst_QLocale::formatDateTime_data()
<< QString("31-apAP12-1999 23:59:59.999");
QTest::newRow("datetime3") << "en_US" << testLongHour
<< QString("Apdd-MM-yyyy hh:mm:ss.zzz")
- << QString("PMp31-12-1999 11:59:59.999");
+ << QString("PM31-12-1999 11:59:59.999");
QTest::newRow("datetime4") << "en_US" << testLongHour
<< QString("'ap'apdd-MM-yyyy 'AP'hh:mm:ss.zzz")
<< QString("appm31-12-1999 AP11:59:59.999");
@@ -1986,6 +1995,14 @@ void tst_QLocale::toDateTime_data()
<< "en_US" << QDateTime(QDate(2009, 1, 5), QTime(11, 48, 32))
<< "dddd, MMMM d, yyyy h:mm:ss AP " << "Monday, January 5, 2009 11:48:32 AM " << true;
+ // Parsing am/pm indicators case-insensitively:
+ QTest::newRow("am-cs_CZ")
+ << "cs_CZ" << QDateTime(QDate(1945, 8, 6), QTime(8, 15, 44, 400))
+ << "yyyy-MM-dd hh:mm:ss.z aP" << "1945-08-06 08:15:44.4 dOp." << true;
+ QTest::newRow("pm-cs_CZ")
+ << "cs_CZ" << QDateTime(QDate(1945, 8, 15), QTime(12, 0))
+ << "yyyy-MM-dd hh:mm aP" << "1945-08-15 12:00 OdP." << true;
+
const QDateTime dt(QDate(2017, 02, 25), QTime(17, 21, 25));
// These formats correspond to the locale formats, with the timezone removed.
// We hardcode them in case an update to the locale DB changes them.
diff --git a/tests/auto/corelib/time/qtime/tst_qtime.cpp b/tests/auto/corelib/time/qtime/tst_qtime.cpp
index 3626f61ac7..480fbcc14f 100644
--- a/tests/auto/corelib/time/qtime/tst_qtime.cpp
+++ b/tests/auto/corelib/time/qtime/tst_qtime.cpp
@@ -553,11 +553,18 @@ void tst_QTime::fromStringFormat_data()
QTest::newRow("data7") << QString("25") << QString("hh") << invalidTime();
QTest::newRow("data8") << QString("22pm") << QString("Hap") << QTime(22, 0, 0);
QTest::newRow("data9") << QString("2221") << QString("hhhh") << invalidTime();
- QTest::newRow("data10") << QString("02:23PM") << QString("hh:mmAP") << QTime(14,23,0,0);
- QTest::newRow("data11") << QString("02:23pm") << QString("hh:mmap") << QTime(14,23,0,0);
- QTest::newRow("short-msecs-lt100") << QString("10:12:34:045") << QString("hh:m:ss:z") << QTime(10,12,34,45);
- QTest::newRow("short-msecs-gt100") << QString("10:12:34:45") << QString("hh:m:ss:z") << QTime(10,12,34,450);
- QTest::newRow("late") << QString("23:59:59.999") << QString("hh:mm:ss.z") << QTime(23, 59, 59, 999);
+ // Parsing of am/pm indicators is case-insensitive
+ QTest::newRow("pm-upper") << QString("02:23PM") << QString("hh:mmAp") << QTime(14, 23);
+ QTest::newRow("pm-lower") << QString("02:23pm") << QString("hh:mmaP") << QTime(14, 23);
+ QTest::newRow("pm-as-upper") << QString("02:23Pm") << QString("hh:mmAP") << QTime(14, 23);
+ QTest::newRow("pm-as-lower") << QString("02:23pM") << QString("hh:mmap") << QTime(14, 23);
+ // Millisecond parsing must interpolate 0s only at the end and notice them at the start.
+ QTest::newRow("short-msecs-lt100")
+ << QString("10:12:34:045") << QString("hh:m:ss:z") << QTime(10, 12, 34, 45);
+ QTest::newRow("short-msecs-gt100")
+ << QString("10:12:34:45") << QString("hh:m:ss:z") << QTime(10, 12, 34, 450);
+ QTest::newRow("late")
+ << QString("23:59:59.999") << QString("hh:mm:ss.z") << QTime(23, 59, 59, 999);
// Test unicode handling.
QTest::newRow("emoji in format string 1")