From 50c63446f525a8625b6315597cb0897d89908d6b Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 12 Jan 2021 19:39:04 +0100 Subject: Fix problems with offset-derived ids for QTimeZone When creating a time-zone from a UTC+offset name that isn't known to the system, QTimeZone (since the fix to QTBUG-77738 in 5.15.0) falls back to constructing a suitable UTC-offset backend; however, the id of this is not guaranteed to match the id passed in to the constructor. In all other cases, the id of a QTimeZone does match the id passed to its constructor. Some utcOffsetId testcases had different id() than the id passed to the constructor, due to mismatches where a zone was constructed using the fall-back but the generated id included its minutes (as :00) or omitted its seconds. The omission of seconds is clearly a bug, but we also don't want to include :00 for seconds when it's not needed. So change QTimeZonePrivate::isoOffsetFormat() to accept a QTimeZone::NameType to configure how much we include in an id. Its callers other than the relevant constructor (from offset) still get minutes, even when :00, but will also get seconds added if that isn't zero; and the constructor from offset now gets the short form obtained by omitting all trailing zeros. Since all valid whole-hour offset names that do include :00 for the minutes field are in fact known standard offset names, the elision of minutes will only affect zones created by ID in the case of a whole-hour offset given without :00 minutes specifier, so these shall necessarily in fact get the ID passed to the constructor. Creating by UTC-offset with a name that specifies zero seconds will result in a QTimeZone instance whose id() differs from what was passed to its constructor (eliding the :00 seconds and potentially also minutes, if also zero) but this should be the only case where a QTimeZone's id doesn't match the one passed to the constructor, when constructed by id. Fixed inconsistency between the offset-constructor's declaration (taking offset as int) and definition (taking qint32) in the process. Added an id check to the utcOffsetId() testcase. Amended two tests of offset-derived time-zones' IDs, added comments to make clear how one of those differs from a matching standard name test and converted two uses of QCOMPARE(, true) to QVERIFY(). [ChangeLog][QtCore][QTimeZone] QTimeZone instances created by offset from UTC (in seconds) shall now only include minutes in their ID when the offset is not a whole number of hours. They shall also include the seconds in their ID when the offset is not a whole number of minutes. Pick-to: 6.0 5.15 Task-number: QTBUG-87435 Change-Id: I610e0a78e2aca51e12bfe003497434a998e93dc7 Reviewed-by: Thiago Macieira --- tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp | 2 +- tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index 0cf227611a..7a6b92c53f 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -3633,7 +3633,7 @@ void tst_QDateTime::timeZones() const QCOMPARE(nzStdOffset.date(), QDate(2012, 6, 1)); QCOMPARE(nzStdOffset.time(), QTime(12, 0)); QVERIFY(nzStdOffset.timeZone() == nzTzOffset); - QCOMPARE(nzStdOffset.timeZone().id(), QByteArray("UTC+12:00")); + QCOMPARE(nzStdOffset.timeZone().id(), QByteArray("UTC+12")); QCOMPARE(nzStdOffset.offsetFromUtc(), 43200); QCOMPARE(nzStdOffset.isDaylightTime(), false); QCOMPARE(nzStdOffset.toMSecsSinceEpoch(), utcStd.toMSecsSinceEpoch()); diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp index e33a8f482c..b587ec38ef 100644 --- a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -503,6 +503,7 @@ void tst_QTimeZone::utcOffsetId() QFETCH(int, offset); QCOMPARE(zone.offsetFromUtc(epoch), offset); QVERIFY(!zone.hasDaylightTime()); + QCOMPARE(zone.id(), id); } } @@ -981,11 +982,11 @@ void tst_QTimeZone::utcTest() QCOMPARE(tzp.hasDaylightTime(), false); QCOMPARE(tzp.hasTransitions(), false); - // Test create from UTC Offset + // Test create from UTC Offset (uses minimal id, skipping minutes if 0) QDateTime now = QDateTime::currentDateTime(); QTimeZone tz(36000); - QCOMPARE(tz.isValid(), true); - QCOMPARE(tz.id(), QByteArray("UTC+10:00")); + QVERIFY(tz.isValid()); + QCOMPARE(tz.id(), QByteArray("UTC+10")); QCOMPARE(tz.offsetFromUtc(now), 36000); QCOMPARE(tz.standardTimeOffset(now), 36000); QCOMPARE(tz.daylightTimeOffset(now), 0); @@ -1000,9 +1001,9 @@ void tst_QTimeZone::utcTest() QCOMPARE(QTimeZone(max).isValid(), true); QCOMPARE(QTimeZone(max + 1).isValid(), false); - // Test create from standard name + // Test create from standard name (preserves :00 for minutes in id): tz = QTimeZone("UTC+10:00"); - QCOMPARE(tz.isValid(), true); + QVERIFY(tz.isValid()); QCOMPARE(tz.id(), QByteArray("UTC+10:00")); QCOMPARE(tz.offsetFromUtc(now), 36000); QCOMPARE(tz.standardTimeOffset(now), 36000); -- cgit v1.2.3