Make time parsing accept zz as equivalent to z

Expand a test to cover millsecond format variants more thoroughly,
including a test for the new usage of zz. This applies to parsing the
complement to commit 0a36a7c1db173089c25ea09029505a589a1c59e5's change
to serialization. Fixed minor glitch in the serialization's doc, too.

[ChangeLog][QtCore][QDateTime] When parsing a datetime, the 'zz'
format specifier is now equivalent to 'z', as for serialization.

Change-Id: I1c5700064738d9c92d5e8ce10bff8050131e190f
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Edward Welbourne 2022-07-29 15:50:09 +02:00
parent 5832087859
commit 411b17150e
3 changed files with 33 additions and 15 deletions

View File

@ -1929,12 +1929,15 @@ QString QTime::toString(Qt::DateFormat format) const
\row \li ss \li The whole second, with a leading zero where applicable (00 to 59) \row \li ss \li The whole second, with a leading zero where applicable (00 to 59)
\row \li z or zz \row \li z or zz
\li The fractional part of the second, to go after a decimal point, \li The fractional part of the second, to go after a decimal point,
without trailing zeroes. Thus "\c{s.z}" reports the seconds to without trailing zeroes. Thus \c{"s.z"} reports the seconds to full
full available (millisecond) precision without trailing zeroes (0 available (millisecond) precision without trailing zeroes (0 to
to 999). 999). For example, \c{"s.z"} would produce \c{"0.25"} for a time a
quarter second into a minute.
\row \li zzz \row \li zzz
\li The fractional part of the second, to millisecond precision, \li The fractional part of the second, to millisecond precision,
including trailing zeroes where applicable (000 to 999). including trailing zeroes where applicable (000 to 999). For
example, \c{"ss.zzz"} would produce \c{"00.250"} for a time a
quarter second into a minute.
\row \li AP or A \row \li AP or A
\li Use AM/PM display. \c A/AP will be replaced by 'AM' or 'PM'. In \li Use AM/PM display. \c A/AP will be replaced by 'AM' or 'PM'. In
localized forms (only relevant to \l{QLocale::toString()}), the localized forms (only relevant to \l{QLocale::toString()}), the
@ -2332,12 +2335,20 @@ QTime QTime::fromString(QStringView string, Qt::DateFormat format)
\row \li mm \li The minute with a leading zero (00 to 59) \row \li mm \li The minute with a leading zero (00 to 59)
\row \li s \li The whole second, without any leading zero (0 to 59) \row \li s \li The whole second, without any leading zero (0 to 59)
\row \li ss \li The whole second, with a leading zero where applicable (00 to 59) \row \li ss \li The whole second, with a leading zero where applicable (00 to 59)
\row \li z \li The fractional part of the second, to go after a decimal \row \li z or zz
point, without trailing zeroes (0 to 999). Thus "\c{s.z}" \li The fractional part of the second, as would usually follow a
reports the seconds to full available (millisecond) precision decimal point, without requiring trailing zeroes (0 to 999). Thus
without trailing zeroes. \c{"s.z"} matches the seconds with up to three digits of fractional
\row \li zzz \li The fractional part of the second, to millisecond part supplying millisecond precision, without needing trailing
precision, including trailing zeroes where applicable (000 to 999). zeroes. For example, \c{"s.z"} would recognize either \c{"00.250"}
or \c{"0.25"} as representing a time a quarter second into its
minute.
\row \li zzz
\li Three digit fractional part of the second, to millisecond
precision, including trailing zeroes where applicable (000 to 999).
For example, \c{"ss.zzz"} would reject \c{"0.25"} but recognize
\c{"00.250"} as representing a time a quarter second into its
minute.
\row \li AP, A, ap, a, aP or Ap \row \li AP, A, ap, a, aP or Ap
\li Either 'AM' indicating a time before 12:00 or 'PM' for later times, \li Either 'AM' indicating a time before 12:00 or 'PM' for later times,
matched case-insensitively. matched case-insensitively.

View File

@ -501,10 +501,11 @@ bool QDateTimeParser::parseFormat(QStringView newFormat)
case 'z': case 'z':
if (parserType != QMetaType::QDate) { if (parserType != QMetaType::QDate) {
const SectionNode sn = { MSecSection, i - add, countRepeat(newFormat, i, 3) < 3 ? 1 : 3, 0 }; const int repeat = countRepeat(newFormat, i, 3);
const SectionNode sn = { MSecSection, i - add, repeat < 3 ? 1 : 3, 0 };
newSectionNodes.append(sn); newSectionNodes.append(sn);
appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote); appendSeparator(&newSeparators, newFormat, index, i - index, lastQuote);
i += sn.count - 1; i += repeat - 1;
index = i + 1; index = i + 1;
newDisplay |= MSecSection; newDisplay |= MSecSection;
} }

View File

@ -2752,9 +2752,15 @@ void tst_QDateTime::fromStringStringFormat_data()
QTest::newRow("data15") QTest::newRow("data15")
<< QString("Thu January 2004") << QString("ddd MMMM yyyy") << QString("Thu January 2004") << QString("ddd MMMM yyyy")
<< QDate(2004, 1, 1).startOfDay(); << QDate(2004, 1, 1).startOfDay();
QTest::newRow("data16") << QString("2005-06-28T07:57:30.001Z") QTest::newRow("zulu-time-with-z-centisec")
<< QString("yyyy-MM-ddThh:mm:ss.zt") << QString("2005-06-28T07:57:30.01Z") << QString("yyyy-MM-ddThh:mm:ss.zt")
<< QDateTime(QDate(2005, 06, 28), QTime(07, 57, 30, 1), Qt::UTC); << QDateTime(QDate(2005, 06, 28), QTime(07, 57, 30, 10), Qt::UTC);
QTest::newRow("zulu-time-with-zz-decisec")
<< QString("2005-06-28T07:57:30.1Z") << QString("yyyy-MM-ddThh:mm:ss.zzt")
<< QDateTime(QDate(2005, 06, 28), QTime(07, 57, 30, 100), Qt::UTC);
QTest::newRow("zulu-time-with-zzz-centisec")
<< QString("2005-06-28T07:57:30.01Z") << QString("yyyy-MM-ddThh:mm:ss.zzzt")
<< QDateTime(); // Invalid because too few digits for zzz
QTest::newRow("utc-time-spec-as:UTC+0") QTest::newRow("utc-time-spec-as:UTC+0")
<< QString("2005-06-28T07:57:30.001UTC+0") << QString("yyyy-MM-ddThh:mm:ss.zt") << QString("2005-06-28T07:57:30.001UTC+0") << QString("yyyy-MM-ddThh:mm:ss.zt")
<< QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), Qt::UTC); << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), Qt::UTC);