diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2022-08-31 15:43:48 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2023-10-19 14:45:56 +0200 |
commit | a49ccc08c307b7c7e1acc34752b81dd38ea43bfa (patch) | |
tree | ba4194b766a80a9a687d13337158585e309753c6 /src/widgets/widgets/qdatetimeedit.cpp | |
parent | 38994ab9accc9aecf1139eb02f7e5fc75fccceec (diff) |
QDateTime: disambiguate times in a zone transition
Previously, requesting a time that got repeated - on the given date,
due to a fall-back transition - would get one of the two repeats,
giving the caller (no hint that there was a choice and) no way to
select the other. Add a flags parameter that captures the available
ways to resolve such ambiguity or select a suitable time near a gap.
Add such a parameter to relevant QDateTime methods, including
constructors, to enable callers to indicate their preference in the
same way. This replaces DST-hint parameters in various internal
functions, including QTimeZonePrivate's dataForLocalTime(). Adapted
tst_QDateTime to test the new feature.
Adapt to gap-times no longer being invalid (by default; or, when they
are, no longer having a useful toMSecsSinceEpoch() value). Instead,
they don't match what was asked for. Amend documentation to reflect
that. Most of the code change for this is to QDTParser and QDTEdit.
[ChangeLog][QtCore][QDateTime] Added a TransitionResolution parameter
to various QDateTime methods to enable the caller to indicate, when
the indicated datetime falls in a time-zone transition, which side of
the transition to fall or whether to produce an invalid result.
[ChangeLog][QtCore][Possibly Significant Behavior Change] When
QDateTime is instantiated for a combination of date and time that was
skipped, by local time or a time-zone, for example during a
spring-forward DST transition, the result is no longer marked invalid.
Whether the selected nearby date-time is before or after the skipped
interval may have changed on some platforms; unless overridden by an
explicit TransitionResolution, it is now a date-time as long after the
previous day's noon as a naive reading of the requested date and time
would expect. This was the prior behavior at least on Linux.
Fixes: QTBUG-79923
Change-Id: I11d5339abef9e7125c4e0dc95a09a7cd4f169dab
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/widgets/widgets/qdatetimeedit.cpp')
-rw-r--r-- | src/widgets/widgets/qdatetimeedit.cpp | 26 |
1 files changed, 8 insertions, 18 deletions
diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index 61cf20891b..5b14457b0d 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -1450,16 +1450,11 @@ void QDateTimeEdit::fixup(QString &input) const int copy = d->edit->cursorPosition(); QDateTime value = d->validateAndInterpret(input, copy, state, true); - /* - String was valid, but the datetime still is not; use the time that - has the same distance from epoch. - CorrectToPreviousValue correction is handled by QAbstractSpinBox. - */ - if (!value.isValid() && d->correctionMode == QAbstractSpinBox::CorrectToNearestValue) { - value = QDateTime::fromMSecsSinceEpoch(value.toMSecsSinceEpoch(), - value.timeRepresentation()); + // CorrectToPreviousValue correction is handled by QAbstractSpinBox. + // The value might not match the input if the input represents a date-time + // skipped over by its time representation, such as a spring-forward. + if (d->correctionMode == QAbstractSpinBox::CorrectToNearestValue) input = textFromDateTime(value); - } } @@ -1727,11 +1722,7 @@ QDateTime QDateTimeEditPrivate::convertTimeZone(const QDateTime &datetime) QDateTime QDateTimeEditPrivate::dateTimeValue(QDate date, QTime time) const { - QDateTime when = QDateTime(date, time, timeZone); - if (when.isValid()) - return when; - // Hit a spring-forward gap - return QDateTime::fromMSecsSinceEpoch(when.toMSecsSinceEpoch(), timeZone); + return QDateTime(date, time, timeZone); } void QDateTimeEditPrivate::updateTimeZone() @@ -2135,11 +2126,10 @@ QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) c true when date and time are valid, even if the date-time returned isn't), so use the time that has the same distance from epoch. */ - if (setDigit(v, sectionIndex, val) && !v.isValid()) { - auto msecsSinceEpoch = v.toMSecsSinceEpoch(); + if (setDigit(v, sectionIndex, val) && getDigit(v, sectionIndex) != val + && sn.type & HourSectionMask && steps < 0) { // decreasing from e.g 3am to 2am would get us back to 3am, but we want 1am - if (steps < 0 && sn.type & HourSectionMask) - msecsSinceEpoch -= 3600 * 1000; + auto msecsSinceEpoch = v.toMSecsSinceEpoch() - 3600 * 1000; v = QDateTime::fromMSecsSinceEpoch(msecsSinceEpoch, v.timeRepresentation()); } // if this sets year or month it will make |