Rework the tzAbbr() helper of dateTimeToString()
Break out the offset-specific code (partly in preparation for handling its localization better, but also) to ensure we try more candidates and, when using the system locale, only use QTimeZone::displayName() if we must - as it may oblige us to instantiate the system time-zone instance. Tweak ordering of #include headers while I'm about it. Change-Id: I183ddd1bcb181120df5561bfdc4d89a218292ee0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 1b909695a66500b3cceb0fee668b12a663ed3b8b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
04a9d7fe00
commit
fcd52bf984
@ -23,6 +23,7 @@ QT_WARNING_DISABLE_GCC("-Wfree-nonheap-object") // false positive tracking
|
||||
|
||||
#include "qplatformdefs.h"
|
||||
|
||||
#include "qcalendar.h"
|
||||
#include "qdatastream.h"
|
||||
#include "qdebug.h"
|
||||
#include "qhashfunctions.h"
|
||||
@ -56,7 +57,6 @@ QT_WARNING_DISABLE_GCC("-Wfree-nonheap-object") // false positive tracking
|
||||
|
||||
#include "private/qcalendarbackend_p.h"
|
||||
#include "private/qgregoriancalendar_p.h"
|
||||
#include "qcalendar.h"
|
||||
|
||||
#include <q20iterator.h>
|
||||
|
||||
@ -3527,6 +3527,41 @@ QString QLocale::pmText() const
|
||||
return d->m_data->postMeridiem().getData(pm_data);
|
||||
}
|
||||
|
||||
// For the benefit of QCalendar, below.
|
||||
static QString offsetFromAbbreviation(QString &&text)
|
||||
{
|
||||
QStringView tail{text};
|
||||
// May need to strip a prefix:
|
||||
if (tail.startsWith("UTC"_L1) || tail.startsWith("GMT"_L1))
|
||||
tail = tail.sliced(3);
|
||||
// TODO: there may be a locale-specific alternative prefix.
|
||||
// Hard to know without zone-name L10n details, though.
|
||||
return (tail.isEmpty() // The Qt::UTC case omits the zero offset:
|
||||
? u"+00:00"_s
|
||||
// Whole-hour offsets may lack the zero minutes:
|
||||
: (tail.size() <= 3
|
||||
? tail + ":00"_L1
|
||||
: std::move(text).right(tail.size())));
|
||||
}
|
||||
|
||||
static QString zoneOffsetFormat([[maybe_unused]] const QLocale &locale,
|
||||
const QDateTime &when,
|
||||
int offsetSeconds)
|
||||
{
|
||||
QString text =
|
||||
#if QT_CONFIG(timezone)
|
||||
locale != QLocale::system()
|
||||
? when.timeRepresentation().displayName(when, QTimeZone::OffsetName, locale)
|
||||
:
|
||||
#endif
|
||||
when.toOffsetFromUtc(offsetSeconds).timeZoneAbbreviation();
|
||||
|
||||
if (!text.isEmpty())
|
||||
text = offsetFromAbbreviation(std::move(text));
|
||||
// else: no suitable representation of the zone.
|
||||
return text;
|
||||
}
|
||||
|
||||
// Another intrusion from QCalendar, using some of the tools above:
|
||||
|
||||
QString QCalendarBackend::dateTimeToString(QStringView format, const QDateTime &datetime,
|
||||
@ -3700,26 +3735,32 @@ QString QCalendarBackend::dateTimeToString(QStringView format, const QDateTime &
|
||||
case 't': {
|
||||
enum AbbrType { Long, Offset, Short };
|
||||
const auto tzAbbr = [locale](const QDateTime &when, AbbrType type) {
|
||||
QString text;
|
||||
if (type == Offset) {
|
||||
text = zoneOffsetFormat(locale, when, when.offsetFromUtc());
|
||||
// When using timezone_locale data, this should always succeed:
|
||||
if (!text.isEmpty())
|
||||
return text;
|
||||
}
|
||||
#if QT_CONFIG(timezone)
|
||||
if (type != Short || locale != QLocale::system()) {
|
||||
QTimeZone::NameType mode =
|
||||
type == Short ? QTimeZone::ShortName
|
||||
: type == Long ? QTimeZone::LongName : QTimeZone::OffsetName;
|
||||
QString text = when.timeRepresentation().displayName(when, mode, locale);
|
||||
text = when.timeRepresentation().displayName(when, mode, locale);
|
||||
if (!text.isEmpty())
|
||||
return text;
|
||||
// else fall back to an unlocalized one if we can manage it:
|
||||
} // else: prefer QDateTime's abbreviation, for backwards-compatibility.
|
||||
#endif // else, make do with non-localized abbreviation:
|
||||
if (type != Offset) {
|
||||
QString text = when.timeZoneAbbreviation();
|
||||
if (!text.isEmpty())
|
||||
return text;
|
||||
// else fall back to Offset version:
|
||||
}
|
||||
// For Offset, we can coerce to a UTC-based zone's abbreviation:
|
||||
return when.toOffsetFromUtc(when.offsetFromUtc()).timeZoneAbbreviation();
|
||||
// Absent timezone_locale data, Offset might still reach here:
|
||||
if (type == Offset) // Our prior failure might not have tried this:
|
||||
text = when.toOffsetFromUtc(when.offsetFromUtc()).timeZoneAbbreviation();
|
||||
if (text.isEmpty()) // Notably including type != Offset
|
||||
text = when.timeZoneAbbreviation();
|
||||
return type == Offset ? offsetFromAbbreviation(std::move(text)) : text;
|
||||
};
|
||||
|
||||
used = true;
|
||||
repeat = qMin(repeat, 4);
|
||||
// If we don't have a date-time, use the current system time:
|
||||
@ -3732,21 +3773,8 @@ QString QCalendarBackend::dateTimeToString(QStringView format, const QDateTime &
|
||||
case 3: // ±hh:mm
|
||||
case 2: // ±hhmm (we'll remove the ':' at the end)
|
||||
text = tzAbbr(when, Offset);
|
||||
if (!text.isEmpty()) {
|
||||
QStringView tail{text};
|
||||
// May need to strip a prefix:
|
||||
if (tail.startsWith("UTC"_L1) || tail.startsWith("GMT"_L1))
|
||||
tail = tail.sliced(3);
|
||||
// TODO: there may be a locale-specific alternative prefix.
|
||||
text = (tail.isEmpty() // The Qt::UTC case omits the zero offset:
|
||||
? u"+00:00"_s
|
||||
// Whole-hour offsets may lack the zero minutes:
|
||||
: (tail.size() <= 3
|
||||
? tail + ":00"_L1
|
||||
: std::move(text).right(tail.size())));
|
||||
if (repeat == 2)
|
||||
text.remove(u':');
|
||||
} // else: no suitable representation of the zone.
|
||||
break;
|
||||
default:
|
||||
text = tzAbbr(when, Short);
|
||||
|
Loading…
x
Reference in New Issue
Block a user