Add a section on date ambiguities to QDate::fromString()
There are various pitfalls and reasons to be wary of short formats. Make clear what the hazards and remedies are. Expand on the existing paragraph about the base-year for the century of two-digit years. Task-number: QTBUG-46843 Change-Id: If7c3d13eec826671f8dce686e520a17c11572bc3 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
9bf7d2a76a
commit
4799516de9
@ -1729,9 +1729,16 @@ QDate QDate::fromString(QStringView string, Qt::DateFormat format)
|
|||||||
starting at \a baseYear are the candidates first considered. Prior to 6.7
|
starting at \a baseYear are the candidates first considered. Prior to 6.7
|
||||||
there was no \a baseYear parameter and 1900 was always used. This is the
|
there was no \a baseYear parameter and 1900 was always used. This is the
|
||||||
default for \a baseYear, selecting a year from then to 1999. Passing 1976 as
|
default for \a baseYear, selecting a year from then to 1999. Passing 1976 as
|
||||||
\a baseYear will select a year from 1976 through 2075, for example. In some
|
\a baseYear will select a year from 1976 through 2075, for example. When the
|
||||||
cases, other fields may lead to the next or previous century being selected,
|
format also includes month, day (of month) and day-of-week, these suffice to
|
||||||
to get a result consistent with all fields given.
|
imply the century. Parsing all but the day of week and then using
|
||||||
|
QCalendar::matchCenturyToWeekday() to combine that with the day of the week
|
||||||
|
could disambiguate such a date, but runs the risk of turning a user error -
|
||||||
|
that would otherwise be recognized by the invalid result of parsing - into a
|
||||||
|
valid result in another century, that wasn't the user's intent. At present,
|
||||||
|
the date parser only considers the century indicated by \a baseYear and the
|
||||||
|
centuries immediately after and before it, to limit the scope for such
|
||||||
|
mistakes. See \l {Date ambiguities} for further details,
|
||||||
|
|
||||||
The following examples demonstrate the default values:
|
The following examples demonstrate the default values:
|
||||||
|
|
||||||
@ -1745,6 +1752,57 @@ QDate QDate::fromString(QStringView string, Qt::DateFormat format)
|
|||||||
\c{"MayMay05"} and set the month to May. Likewise, \c{'MMMMMM'} would match
|
\c{"MayMay05"} and set the month to May. Likewise, \c{'MMMMMM'} would match
|
||||||
\c{"May08"} and find it inconsistent, leading to an invalid date.
|
\c{"May08"} and find it inconsistent, leading to an invalid date.
|
||||||
|
|
||||||
|
\section2 Date ambiguities
|
||||||
|
|
||||||
|
Different cultures use different formats for dates and, as a result, users
|
||||||
|
may mix up the order in which date fields should be given. For example,
|
||||||
|
\c{"Wed 28-Nov-01"} might mean either 2028 November 1st or the 28th of
|
||||||
|
November, 2001 (each of which happens to be a Wednesday). Using format
|
||||||
|
\c{"ddd yy-MMM-dd"} it shall be interpreted the first way, using \c{"ddd
|
||||||
|
dd-MMM-yy"} the second. However, which the user meant may depend on the way
|
||||||
|
the user normally writes dates, rather than the format the code was
|
||||||
|
expecting.
|
||||||
|
|
||||||
|
The example considered above mixed up day of the month and a two-digit year.
|
||||||
|
Similar confusion can arise over interchanging the month and day of the
|
||||||
|
month, when both are given as numbers. In these cases, including a day of
|
||||||
|
the week field in the date format can provide some redundancy, that may help
|
||||||
|
to catch errors of this kind. However, as in the example above, this is not
|
||||||
|
always effective: the interchange of two fields (or their meanings) may
|
||||||
|
produce dates with the same day of the week.
|
||||||
|
|
||||||
|
Including a day of the week in the format can also resolve the century of a
|
||||||
|
date specified using only the last two digits of its year. Unfortunately,
|
||||||
|
when combined with a date in which the user (or other source of data) has
|
||||||
|
mixed up two of the fields, this resolution could lead to finding a date
|
||||||
|
which does match the format's reading but isn't the one intended by its
|
||||||
|
author. This would be in a different century, which would in many cases at
|
||||||
|
least make it possible to recognize there is a problem with the data. At
|
||||||
|
present, date parsing considers the centuries after and before the one
|
||||||
|
indicated by \a baseYear, which may fall foul of this problem. See the
|
||||||
|
discussion above about using QCalendar::matchCenturyToWeekday() to extend
|
||||||
|
that to a wider range of centuries, if that can safely be applied in your
|
||||||
|
use-case.
|
||||||
|
|
||||||
|
The best way to avoid date ambiguities is to use four-digit years and months
|
||||||
|
specified by name (whether full or abbreviated), ideally collected via user
|
||||||
|
interface idioms that make abundantly clear to the user which part of the
|
||||||
|
date they are selecting. Including a day of the week can also help by
|
||||||
|
providing the means to check consistency of the data. Where data comes from
|
||||||
|
the user, using a format supplied by a locale selected by the user, it is
|
||||||
|
best to use a long format as short formats are more likely to use two-digit
|
||||||
|
years. Of course, it is not always possible to control the format - data may
|
||||||
|
come from a source you do not control, for example.
|
||||||
|
|
||||||
|
As a result of these possible sources of confusion, particularly when you
|
||||||
|
cannot be sure an unambiguous format is in use, it is important to check
|
||||||
|
that the result of reading a string as a date is not just valid but
|
||||||
|
reasonable for the purpose for which it was supplied. If the result is
|
||||||
|
outside some range of reasonable values, it may be worth getting the user to
|
||||||
|
confirm their date selection, showing the date read from the string in a
|
||||||
|
long format that does include month name and four-digit year, to make it
|
||||||
|
easier for them to recognize any errors.
|
||||||
|
|
||||||
\sa toString(), QDateTime::fromString(), QTime::fromString(),
|
\sa toString(), QDateTime::fromString(), QTime::fromString(),
|
||||||
QLocale::toDate()
|
QLocale::toDate()
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user