summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qdatetimeedit.cpp
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2022-08-31 15:43:48 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2023-10-19 14:45:56 +0200
commita49ccc08c307b7c7e1acc34752b81dd38ea43bfa (patch)
treeba4194b766a80a9a687d13337158585e309753c6 /src/widgets/widgets/qdatetimeedit.cpp
parent38994ab9accc9aecf1139eb02f7e5fc75fccceec (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.cpp26
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