Avoid using Darwin date formatting before 1583
It turns out that Darwin's date formatting uses the Julian calendar for dates before 1582-10-15, when the Gregorian calendar first came into use (in some countries, while many others continued using Julian). This leads to discrepancies between the (Gregorian) dates we pass it for formatting and the (Julian) dates it actually prints, that are the same number of seconds before 1970. Previously the QLocale system backend for Darwin already had a kludge to work round its handling of negative years, so it suffices to extend that to years before 1583. Fixes: QTBUG-54955 Pick-to: 6.6 6.5 Change-Id: I70f219b73bf20c0cd63bcda2b0e99042354872ca Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
716df4965e
commit
207954d5f0
@ -242,12 +242,6 @@ static QString macDateToStringImpl(QDate date, CFDateFormatterStyle style)
|
||||
// back to 1900. (Alaska and Phillipines may still be borked, though.)
|
||||
QCFType<CFDateRef> myDate = QDateTime(date, QTime(12, 0)).toCFDate();
|
||||
QCFType<CFLocaleRef> mylocale = CFLocaleCopyCurrent();
|
||||
// Note: Darwin take the calendar transition from Julian to Gregorian into
|
||||
// account (see QTBUG-54955, again). This means that, just before that
|
||||
// transition, dates are off by ten days, drifting by one day per century
|
||||
// before that, except when the century is a multiple of 400 years. Unless
|
||||
// we can find a way to suppress that, we're stuck with bogus results for
|
||||
// historic dates more than a few centuries back.
|
||||
QCFType<CFDateFormatterRef> myFormatter
|
||||
= CFDateFormatterCreate(kCFAllocatorDefault, mylocale, style,
|
||||
kCFDateFormatterNoStyle);
|
||||
@ -259,12 +253,14 @@ static QVariant macDateToString(QDate date, bool short_format)
|
||||
{
|
||||
const int year = date.year();
|
||||
QString fakeYear, trueYear;
|
||||
if (year < 0) {
|
||||
if (year < 1583) {
|
||||
// System API (in macOS 11.0, at least) discards sign :-(
|
||||
// Simply negating the year won't do as the resulting year typically has
|
||||
// a different pattern of week-days.
|
||||
// Furthermore (see QTBUG-54955), Darwin uses the Julian calendar for
|
||||
// dates before 1582-10-15, leading to discrepancies.
|
||||
int matcher = QGregorianCalendar::yearSharingWeekDays(date);
|
||||
Q_ASSERT(matcher > 0);
|
||||
Q_ASSERT(matcher >= 1583);
|
||||
Q_ASSERT(matcher % 100 != date.month());
|
||||
Q_ASSERT(matcher % 100 != date.day());
|
||||
// i.e. there can't be any confusion between the two-digit year and
|
||||
@ -277,7 +273,7 @@ static QVariant macDateToString(QDate date, bool short_format)
|
||||
QString text = macDateToStringImpl(date, short_format
|
||||
? kCFDateFormatterShortStyle
|
||||
: kCFDateFormatterLongStyle);
|
||||
if (year < 0) {
|
||||
if (year < 1583) {
|
||||
if (text.contains(fakeYear))
|
||||
return std::move(text).replace(fakeYear, trueYear);
|
||||
// Cope with two-digit year:
|
||||
|
Loading…
Reference in New Issue
Block a user