summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
Commit message (Collapse)AuthorAgeFilesLines
* tst_QTZ::localeSpecificDisplayName(): expect failure when data lackingEdward Welbourne24 hours1-0/+2
| | | | | | | | | | QTZ::displayName() returns an empty string if it doesn't know how to localize a zone name. In this case, we can't expect it to match the expected name, which depends on having relevant locale data available. Task-number: QTBUG-115158 Change-Id: I1cd8c1469399502764c354bf24423298f106f23e Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Decouple the TZ and ICU backends for timezone dataEdward Welbourne14 days1-3/+3
| | | | | | | | | | | | The TZ backend was instantiating an ICU backend to look up display names, which entailed locking of the lazy-evaluated ICU member. Instead, break out how ICU looks up display names into the new timezone_locale feature's code, so that it can be shared between the two backends. Linux thus only needs to build one backend. Task-number: QTBUG-115158 Change-Id: I37ebc9a30f1c0ab6fd32d45dffa9f21355fb868d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Break out timezone data from cldr2qtimezone.pyEdward Welbourne2024-05-061-1/+1
| | | | | | | | | | | This separates the large slabs of data (and their documentation) from the code that mixes them with CLDR-derived data and generates the data we actually use. In the process, put the shorter table before the longer one, to make it less likely that folk shall fail to notice it's even there at all. Change-Id: I8457741911657dac0dad53c2e65b977821bb4e71 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* QIcuTimeZonePrivate constructor: save iteration over all zone IDsNicolas Fella2024-02-081-1/+3
| | | | | | | | | | | | | | | | | | | | ICU returns a "valid" representation of GMT when given an unrecognised ID, so QTZ's constructor has been checking the ID is available before passing it to the backend constructor. That availability check was done by generating the list of available IDs to see if the given ID was in it; this is very inefficient. Furthermore, the QTZ constructor was also checking availability, to work round the same issue in only this one backend, making the check redundant. So overide isTimeZoneIdAvailable() in the ICU backend, calling ucal_getCanonicalTimeZoneID(), which answers the question directly; and drop the duplicate check in the QTZ constructor. Expand a test to verify an invalid name is rejected. Fixes: QTBUG-121807 Pick-to: 6.7 6.6 6.5 Change-Id: I34f996b607b958d12607a94eb273bb1b406cca1a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Rework tst_QTimeZone::windowsId() to use initializer-listsEdward Welbourne2024-02-051-40/+48
| | | | | | | | Instead of clearing a list repeatedly to then repopulate it by appending entries. Change-Id: I82594d69c1cb145defff43d84f92f8410d8997aa Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Change license for tests filesLucie Gérard2024-02-041-1/+1
| | | | | | | | | | | | According to QUIP-18 [1], all tests file should be LicenseRef-Qt-Commercial OR GPL-3.0-only [1]: https://contribute.qt-project.org/quips/18 Pick-to: 6.7 Task-number: QTBUG-121787 Change-Id: I9657df5d660820e56c96d511ea49d321c54682e8 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
* Introduce macros to simplify testing comparisonIvan Solovev2024-01-191-1/+1
| | | | | | | | | | | | | | | | | | | | | The problem with the QTestPrivate::testAllComparisonOperators() and QTestPrivate::testEqualityOperators() functions is that if they fail, they point into the helper function, but not into the actual test that called the helper function. This is specially annoying when some test calls the helper function multiple times. This patch introduces the helper macros QT_TEST_ALL_COMPARISON_OPS and QT_TEST_EQUALITY_OPS that wrap the respective function calls together with the QTest::currentTestFailed() check. If the test has failed, the macro generates a meaningful debug message with the original file name and line number. This patch also applies the new macros to qtbase. Task-number: QTBUG-119433 Pick-to: 6.7 Change-Id: Iad709de45e5bf53c82e7afa8e9f51e9275c1e619 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QTimeZone: use new comparison helper macrosIvan Solovev2023-11-281-7/+29
| | | | | | | | | | | | | The class had operator==() and operator!=() defined as public member functions, so use QT_CORE_REMOVED_SINCE and removed_api.cpp to get rid of these methods and replace them with hidden friends. Extend unit-tests by using the helper functions from QTestPrivate. Task-number: QTBUG-104111 Change-Id: Ib9ca613005e2f1521dea5e3cd9e2baa0b47fede4 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QTimeZone(qint32 offsetSeconds): use IANA ID when one is availableEdward Welbourne2023-11-031-2/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | Principle of least surprise: prefer IANA IDs over synthesized ones. This also aligns what id() returns more nearly with what availableTimeZoneIds() reports. Amend some tests to match the new behavior, extend one test to verify id-round-tripping (also for the IANA zones) and another to verify single-digit offset IDs get zero-padded. Document the complications in how id() relates to what is passed to the constructor. (It was already complicated; the present change just aligns it better with IANA IDs, where possible.) Mention, in availableTimeZoneIds(), that (and why) it only includes IANA's offset IDs. Drive-by: fix a typo in another availableTimeZoneIds() overload's doc. [ChangeLog][QtCore][QTimeZone] When created from (only) a UTC offset, or from (only) a non-IANA UTC-offset ID, a QTimeZone instance now uses an IANA UTC-offset ID, where one is available with a matching offset. Previously it used a synthesized UTC±hh[:mm[:ss]] one which would omit trailing :00 for minutes or seconds, which the IANA ID may well include. Task-number: QTBUG-118586 Change-Id: Ifc4976f36361c830c88a8bef0e8b963fe5a2ab43 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Report as available every QTimeZone(qint32).id() resultEdward Welbourne2023-10-301-0/+6
| | | | | | | | | | | | | | | | | | | | | | The QTimeZone(id) constructor accepts these IDs, but isTimeZoneIdAvailable() did not admit to this. Although we cannot sensibly list all 183,047 of them in availableTimeZoneIds(), we should not claim they are unavailable. The custom QTZ constructor needs to know when the ID it's been given is an IANA one (to refuse to use it), so it has to be able ask the backends for "is this IANA", so the UTC backend still has to report these IDs as invalid, leaving the QDT frontend to include the check for these offset zones. Extend isTimeZoneIdAvailable() test to include every offset-zone's ID within QTZ's recognized range of offsets. Although the actual range accepted by offsetFromUtcString() is wider, bounded by ±24:59:59, the constructor from offset seconds (rather than offset string) is bounded by ±16 hours. Pick-to: 6.6 6.5 Fixes: QTBUG-118586 Change-Id: Id9b378aee122ec841635584367022fcb47041fdd Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Warn on failure to construct valid system time zone objectEdward Welbourne2023-09-151-1/+3
| | | | | | | | | | | | | | | | Also move some docs from asBackendZone() to systemTimeZone(), making clear that the system zone object is current at the time of creation and won't be updated if the system is reconfigured. Adapt some tests to fail and make clear that the system is misconfigured if no valid system zone is found. [ChangeLog][QtCore][QTimeZone] If systemTimeZone() is unable to identify a valid system time zone, it now produces a warning the first time it encounters the problem. Task-number: QTBUG-116017 Change-Id: Ia437d8a03ff3cbf2b2cd98e8a8c3aebe50c1ee32 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Use the modern name for zone Asia/KolkattaEdward Welbourne2023-09-131-3/+6
| | | | | | | | | | The old name Asia/Calcutta is being phased out. We can't assign QTzTZP, so select between new name and old using a reference variable. In the process, fix a QCOMPARE() against bool to a QVERIFY(). Pick-to: 6.6 6.5 Change-Id: I7cd8a813f8a88c8ae4ba07213f04f4ad0860cec0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Update QTimeZone data to CLDR v43Edward Welbourne2023-08-071-3/+3
| | | | | | | | | | | Ran the script, no new IDs to add. Revised tests of Central Standard Time: America/Ojinaga has joined Matamoros for it, in Mexico. Pick-to: 6.6 6.5 Fixes: QTBUG-115732 Task-number: QTBUG-111550 Change-Id: I9b41d8c0156b9fbe3961dbe9a35d55493fc55501 Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>
* Correct name of Ukraine's zoneEdward Welbourne2023-07-101-3/+3
| | | | | | Pick-to: 6.6 6.5 Change-Id: I90066ad5ca4ee5f2483cb5eb3208fb9ba98c873d Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>
* Fix QTimeZone::offsetData() for the case without transitionsEdward Welbourne2023-05-111-8/+22
| | | | | | | | | | | | | | | | | | | | | | A zone without transitions, such as any UTC-based one, would previously return invalid data for the offset data at a given time. The method was documented to be "the equivalent of calling offsetFromUtc(), abbreviation(), etc" but these methods do return sensible data for a zone with no transitions. Furthermore, the backend data() method on which it depends is implemented by all backends, including the UTC one, with no transitions. Fix offsetData() to also return data when no transitions are available. Improve docs. Adapt the checkOffset() test to test offsetData() as well as the various functions to get parts of it. In the process, change that test to use a QTimeZone row instead of its name as a QByteArray, so that we can also have rows for lightweight time representations. Change-Id: I241ecf02a26a228cca972bca5e2db687fe41feb4 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Change QTimeZone's offset range into constants, not an enumEdward Welbourne2023-04-281-2/+2
| | | | | | | | | | | | | | Use static constexpr int values instead of abusing enum. [ChangeLog][QtCore][QTimeZone] The MinUtcOffsetSecs and MaxUtcOffsetSecs constants are now static constexpr members of QTimeZone, rather than members of an anonymous enum. Their values are now 16 hours either side of zero, to allow for some historical zones. Change-Id: I1c3a0f85a2b83b5010f021ca0f5ca5baefbf32e4 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* Expand range of allowed UTC offsets to 16 hoursEdward Welbourne2023-04-201-4/+4
| | | | | | | | | It turns out that Alaska and The Philippines had historical offsets exceeding 15 hours, prior to day-transitions to bring their dates in sync with their respective sides of the international date line. Change-Id: I48fdf3aa6d8c0bacb368d08316733a10ee11a281 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Adapt corelib to use QTimeZone in place of Qt::TimeSpecEdward Welbourne2022-12-091-71/+89
| | | | | | | | | This saves (mostly in corelib/time/) some complications that used to arise from needing different code-paths for different time-specs. Task-number: QTBUG-108199 Change-Id: I5dbd09859fce7599f1ba761f8a0bfc4633d0bef9 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Adapt QTimeZone to handle Qt::TimeSpec machineryEdward Welbourne2022-12-091-24/+173
| | | | | | | | | | | | | | | | | [ChangeLog][QtCore][QTimeZone] QTimeZone is now always defined; feature timezone now controls most of its prior API and some new API is added, most of it always present, to enable QTimeZone to package a Qt::TimeSpec and, for Qt::OffsetFromUTC, its offset. Prior to this change, APIs using Qt::TimeSpec had to provide a separate function taking a QTimeZone alongside a function taking a Qt::TimeSpec and optional offset; it will now be possible to unify these into a single function taking a QTimeZone. Adaptation of other Qt classes to do so shall follow. Task-number: QTBUG-108199 Change-Id: If5ec3cc63920af882ebb333bf69cde266b1f6ad7 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Suppress output of debug message only produced to test against crashEdward Welbourne2022-12-071-0/+1
| | | | | | | | As a result, also make sure the test will fail if output to debug stream doesn't produce the expected result. Change-Id: I9914c9c41c8d8b79f32dfb8e0c735f12e2d59f5e Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Port from container::count() and length() to size() - V5Marc Mutz2022-11-031-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a semantic patch using ClangTidyTransformator as in qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to handle typedefs and accesses through pointers, too: const std::string o = "object"; auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); }; auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) { auto exprOfDeclaredType = [&](auto decl) { return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o); }; return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes)))); }; auto renameMethod = [&] (ArrayRef<StringRef> classes, StringRef from, StringRef to) { return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)), callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))), changeTo(cat(access(o, cat(to)), "()")), cat("use '", to, "' instead of '", from, "'")); }; renameMethod(<classes>, "count", "size"); renameMethod(<classes>, "length", "size"); except that the on() matcher has been replaced by one that doesn't ignoreParens(). a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'. Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache, to avoid porting calls that explicitly test count(). Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Tidy up tst_QTimeZoneEdward Welbourne2022-09-141-10/+2
| | | | | | | | | Its debug member can be set where it's declared, making the constructor redundant. Change-Id: Ic1195108766a6a86c3392a5bcf7f197ea31e8068 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Use SPDX license identifiersLucie Gérard2022-05-161-27/+2
| | | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Task-number: QTBUG-67283 Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
* QTimeZone: add construction from std::chrono::time_zone*Giuseppe D'Angelo2022-04-121-0/+48
| | | | | | | | | | | A time_zone represents a timezone identified by its IANA ID. This allows for a straightforward conversion to QTimeZone. [ChangeLog][QtCore][QTimeZone] QTimeZone can now be constructed from a std::chrono::time_zone pointer. Change-Id: I093d9fc2e989475d30730a9dcdef491903a2aeb2 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Android: use BCP 47 tag to create a correct Locale for QTimeZone::displayName()Ivan Solovev2022-04-081-0/+52
| | | | | | | | | | | | | | | | | | Before the patch we tried to create a java Locale object by passing the human-readable language, territory and variant strings. However, the Locale constructor accepts ISO-defined codes. Fix it by using a factory method Locale.forLanguageTag() [0] that constructs a Java Locale object based on BCP 47 tag. [0]: https://developer.android.com/reference/java/util/Locale#forLanguageTag(java.lang.String) Fixes: QTBUG-101460 Pick-to: 6.3 6.2 5.15 Change-Id: If414c66cf0e5b7e8299ffc3a6038b6f9eb79d5ec Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
* Include zone name on tst_QTimeZone::isTimeZoneIdAvailable() failureEdward Welbourne2022-03-251-1/+1
| | | | | | | | | The zone name was reported if isValid() failed, but not if isTimeZoneIdAvailable(), where it also proved useful in uncovering ICU's use of over-long zone name components. Change-Id: I4b3b65b1a4a338b638c01fc7ad47294118ee0efc Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Apply the East-Saskatchewan exception to zone-fragment lengths to ICUEdward Welbourne2022-03-251-2/+2
| | | | | | | | | | | | The exception was previously limited to Android, but I now find that ICU has the same over-long names; it seems likely that's where Android gets them. Also update the link to the theory page from the TZ DB, as it now has an official home on www.iana.org. Task-number: QTBUG-99747 Pick-to: 6.3 6.2 Change-Id: I9af67426d15609dfaf5f335405ceb1218fcf40ff Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Tidy up tst_QTimeZone::specificTransition()Edward Welbourne2022-02-181-7/+8
| | | | | | | | | It can now use startOfDay()/endOfDay() for the end-points of its search range; and it should check transit is not empty before dereferencing transits.at(0). Change-Id: Ib1568f4d8d6ce301d601071bb58185be906c631a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Convert a table iteration to use ranged-forEdward Welbourne2022-02-151-10/+6
| | | | | | | | | | | The loop used an int counter that was initialized from a size_t, provoking a warning from MSVC. Since the indexing is irrelevant in any case, use a ranged-for loop. Since the loop was formerly in decreasing index order, reverse the table being iterated so that entries remain in their prior order. Change-Id: I79b93c5a3f39a502b0cae83215b8e3665d0e17f5 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Fix an inaccurate comment and update a test caseEdward Welbourne2022-02-091-2/+2
| | | | | | | | | | | | | The offset fields for tst_QTimeZone::specificTransition() had a comment claiming they are in minutes; they are in fact in seconds, so fix that. At the same time, Moscow hasn't had a time-zone change since 2017, so the end-date for one of the test intervals can be nudged a little closer to the present without harm. Change-Id: I66822cb758f7e00d6added801466a6745be3e31a Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Skip QTimeZone::checkOffset() if there are no valid zones to testEdward Welbourne2021-11-261-0/+4
| | | | | Change-Id: I62df34fe40b8e89b99912e8ad0d1d2f2f11fd71e Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* Use a local check-macro to save lots of repetition in time-zone testsEdward Welbourne2021-11-101-90/+53
| | | | | | | | | | Tests of QTimeZone::dispayName() were burying most of what was interesting in the variations among them by repetition of a large amount of boilerplate. Package the repetition in a macro so that the differences between checks are more evident. Change-Id: I23bcafab641b7d3bed50248ba5313250c150d30c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Correct and clarify some commentsEdward Welbourne2021-11-081-3/+3
| | | | | Change-Id: I011b04cf0dccea51c00c597c8dff74d574fe36ad Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Express 64-bit integral constants consistentlyEdward Welbourne2021-11-081-6/+7
| | | | | | | | Use the Q_INT64_C() macro and qint64()-as-function instead of C-style casts. Change-Id: I9d169715da96a49898e9c9e2a6d3ee5182e1d91c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Give symbolic names to some constants used in time-zone testsEdward Welbourne2021-11-081-12/+15
| | | | | | | | | | Where std::numeric_limits<...>::min() is used used as invalid value for an API return, save it as a named constant so that the comparisons are against an informative name, rather than leaving the reader to guess the significance of the min-value. Change-Id: Ia99c75e21856f65cb4494120d05eed36f5fc2d50 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Remove conditioning on Android embeddedEdward Welbourne2021-09-171-2/+2
| | | | | | | | It is no longer handled separately from Android. This effectively reverts commit 6d50f746fe05a7008b63818e77784dd0c99270a1 Change-Id: Ic2d75b8c5a09895810913311ab2fe3355d4d2983 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
* Use time-zone transition data before 1970 as well as afterEdward Welbourne2021-05-261-3/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDateTime has long followed a convention of ignoring what it knows about time-zone transitions before the epoch. This produces unhelpful artefacts (such as an ahistorical spring-forward skipping the first hour of 1970 in Europe/London, which was in permanent DST at the time) and complicates the code. It documented that DST transitions were ignored, but in fact ignored all transitions prior to 1970 and simply assumed that the current time-zone properties (half a century later) applied to all times before 1970. This appears to be based on the fact that the MS APIs using time_t all limit their range to after 1970. Given that we have to resort to "other means" to deal with times after the end of time_t, when it's only 32-bit (and after year 3000, on MS systems), we have the means in place to handle times outside the range supported by the system APIs, so have no need to mimic this restriction. (Those means are not as robust as we might want, but they are less bad than assuming that the present zone properites were always in effect prior to 1970.) On macOS, the time_t functions only reach back to the start of 1900; it reaches to the end of its time_t range and Linux covers the whole range. Given this variety, the range is now auto-detected the first time it is needed (based on some quick and dirty heuristics). Various CET-specific tests now need adjustments in tests of times before the introduction of time-zones (when they are in fact on LMT, not CET). The systemZone() test of QTimeZone can now restore its pre-zone test cases. Various comments on tests needed updates. [ChangeLog][QtCore][QDateTime] Available time-zone information is now used to its full extent, where previously QDateTime used LocalTime's current standard time for all dates before 1970. Where we have time-zone information, it is considered reliable, so we use it. This changes the "best efforts" used for times outside the range supported by the system APIs, in most cases giving less misleading results. Fixes: QTBUG-80421 Change-Id: I7b1df7622dd9be244b0238ed9c08845fb5b32215 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Revert early return from QTimeZone on invalid IDEdward Welbourne2021-04-291-1/+1
| | | | | | | | | | | | | | This reverts commit ec8808c3020abbc436f1a2d90fecf3245fd6417b but retains its test, as the problem it fixed is now solved by having the TZ backend validate the ID it's passed, so that it now only accepts valid POSIX zone-descriptions and valid IANA IDs. The former were being excluded by this check. Amended a POSIX test to fail with the check in place; it passes now. Change-Id: I0d5e8c6e0a315ac2509f3d23bebb52aede8f79d0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Robert Löhning <robert.loehning@qt.io>
* Check POSIX rules during QTzTimeZone creationEdward Welbourne2021-04-271-0/+1
| | | | | | | | | | | | | | | | | | | | | Previously, an apparent POSIX rule would be saved and any defects in it would only be discovered when trying to use it to generate transitions. Instead, check that it has the right form during the initial parsing of its data. In the process, since checking for DST in the process is trivial, implement a long-standing TODO to cache hasDaylightTime()'s answer. The array it scanned was in any case being scanned during construction, so detecting DST in init()'s scan is trivial; and its failure to check the POSIX rule mean it failed to notice when zones entirely specified by a POSIX rule have DST. Adapt a test using a POSIX-only rule to verify it does know the zone has DST; it did not, before this change. Change-Id: I690c013d3331600f7348dae61c35d41e5599da70 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Fix handling of a POSIX zone rule describing permanent DSTEdward Welbourne2021-04-271-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | The description necessarily has fake transitions at start and end of the year, potentially outside the year. These transitions should not be reported by QTzTimeZonePrivate as transitions, although its data() must find a "transition" whose data it can use (as in the permanent standard time case, which could potentially be represented the same way, although there's a saner way to do so, that the code already handles) to report the zone's properties. In the process, fix (and make more straightforward) the convoluted decision-making code that was deciding which transitions to include in the returned list. It was assuming invalidMSecs() would be set as the atMSecsSinceEpoch of a transition, although this is computed in a way that makes that value most unlikely, even when the result is invalid. It also rather confusingly mixed < 0 tests as tests for overflow with the one < 0 test that's about ignoring DST before 1970. Also added comments to clarify some of what's going on there. Expanded a recently-added test of a permanent DST zone to verify this now works correctly. Change-Id: Ia8d98f433fb1e479dba5479220a62196c30f0244 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Correct the parsing of POSIX rule day-of-year fieldsEdward Welbourne2021-04-271-0/+12
| | | | | | | | | | | | | | | | | There are two formats for such fields: one with a J prefix on a number in the range 1 to 365, the other with no prefix and a range from 0 to 365. The code mistakenly treated the latter as if its range were from 1 to 366. The J-form doesn't count Feb 29th, so March always starts on day 60; the code tried to take that into account, but adjusted in the wrong direction (and this mislead me, in a recent partial fix, into a fence-post error). Add a test-case based on the Africa/Casablanca POSIX rule seen on RHEL 8.2, which tripped over the off-by-one error without a J prefix. This incidentally also tests the J case. Change-Id: I692ca511e5c960f91a6c21073d3b2f037f5e445f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Correct the range of allowed hours for a POSIX rule's transitionEdward Welbourne2021-04-201-1/+1
| | | | | | | | | | | | | | | | | | | | A POSIX rule's transition time is allowed an hour in the range from -137 to 137; in particular, a negative hour is allowed, and used by some Greenland zones using Europe's time-of-transition which, as they are more than two hours west of Greenwich, happens before midnight. This means the time of transition can't be represented by a QTime(), so propagate the int that represents it to the code that consumes it; and treat parsing failure as an error rather than "correcting" it - if the transition time is given, it must be valid. Changed tst_QTimeZone::isTimeZoneIdAvailable()'s verification of validity to report the name of the zone it thought was invalid. (A later change, validating POSIX rules, caued this to fail for America/Nuuk without the present fix.) Change-Id: I5c9127ac34d878554dd0aca1c1c7338c7e0e1c28 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Return early from QTimeZone constructor if alleged IANA ID is invalidEdward Welbourne2021-04-201-0/+3
| | | | | | | | | | | | If the ID isn't even valid, don't waste cycles trying to make sense of it as identifying a time-zone. Add test of an invalid ID that provoked an integer overflow on trying to parse it as a POSIX zone specification. Fixes: QTBUG-92842 Change-Id: Ib80bbb88c11c0484ce0358acabbdc25c5bd8e0b3 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Catch invalid offset returns from QTimeZone backendsEdward Welbourne2021-04-161-2/+2
| | | | | | | | | | If the backends run into an error in computing the offset, they return INT_MIN; but they are valled via the front-end, which returns zero when the zone is invalid. So treat INT_MIN returns from the backend the same as the case of being invalid. Change-Id: Ic3c4dfe964dbfba4030c770213eca8a63e84736d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Add the "Territory" enumerated type for QLocaleJiDe Zhang2021-04-151-12/+12
| | | | | | | | | | | | | | | | | | | The use of "Country" is misleading as some entries in the enumeration are not countries (eg, HongKong), for all that most are. The Unicode Consortium's Common Locale Data Repository (CLDR, from which QLocale's data is taken) calls these territories, so introduce territory-based names and prepare to deprecate the country-based ones in due course. [ChangeLog][QtCore][QLocale] QLocale now has Territory as an alias for its Country enumeration, and associated territory-based names to match its country-named methods, to better match the usage in relevant standards. The country-based names shall in due course be deprecated in favor of the territory-based names. Fixes: QTBUG-91686 Change-Id: Ia1ae1ad7323867016186fb775c9600cd5113aa42 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Make POSIX transition rule parser more robustEdward Welbourne2021-04-141-0/+16
| | | | | | | | | | | | | | | | | | | | | | | | The POSIX rule parser used by QTzTimeZonePrivate recklessly assumed that, if splitting the rule on a dot produced more than one part, it necessarily produced at least three. That's true for well-formed POSIX rules, but we should catch the case of malformed rules. Likewise, when calculating the dates of transitions, splitting the date rule on dots might produce too few fragments; and the fragments might not parse as valid numbers, or might be out of range for their respective fields in a date. Check all these cases, too. Added a test that crashed previously. Changed QTimeZone::offsetFromUtc() so that its "return zero on invalid" applies also to the case where the backend returns invalid, in support of this. Fixes: QTBUG-92808 Pick-to: 6.1 6.1.0 6.0 5.15 Change-Id: Ica383a7a987465483341bdef8dcfd42edb6b43d6 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Robert Löhning <robert.loehning@qt.io>
* Extend system zone test to check it matches LocalTimeEdward Welbourne2021-03-181-0/+15
| | | | | | | | | | | | | | | | | | | | Test we get the same starts of various days. Some coming changes shall break some of these, but they should all be back to working by the time we're taking account of DST before 1970 as well as after. The first two or three test-cases work by accident in most zones, at present, due to the zone-based code-path ignoring the LMT period before the zone's first transition; but Europe/Helsinki had a renaming transition in 1878, so does see its pre-zone offset between then and the switch to UTC+2 in 1921, leading to failures in exactly the zone Coin tests. So suppress these three test-cases pending later fixes. On Windows, the next text (still pre-epoch) gets bogus zone data for its LocalTime, so suppress that likewise. Task-number: QTBUG-80421 Change-Id: I2264e0e436d92112b03264faa410e30057b8f73b Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Fix transitionEachZone() failures on AndroidEdward Welbourne2021-02-241-14/+20
| | | | | | | | | | | | | | | | | | | In QTimeZonePrivate::dataForLocalTime(), mistrust the Android backend's hasDaylightTime(), as it has a comment saying it only knows about future transitions, not past. This caller of it really needs to query "has ever had a transition", which this doesn't answer. Many zones that have no plans for future transitions have had transitions in the past; these were failing the transitionEachZone() test. In the process, refine the test itself, making sure we catch some quirk cases that shouldn't arise and making the debug message on failure more informative (while eliding the zone name, as this is part of the test name anyway, so added to the output by qDebug() itself). Fixes: QTBUG-69131 Change-Id: I88a0528182c247acb8b6327b40516178e455bcc0 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Return early after test-helpers if they failEdward Welbourne2021-02-181-0/+10
| | | | | | | | | | | The QTimeZone tests have some helper functions to test details of a QTZP instance; these use QCOMPARE(), so may return early on failure. The callers then need to notice the failure and, in their turn, also return. Change-Id: I0a188e9641ced70c9ffedd95e91f39681fad768a Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* Skip a timezone transition test on AndroidEdward Welbourne2021-02-181-0/+4
| | | | | | | | | | | | Its back-end lacks transition data, so the test can't possibly succeed. Make the skip conditional on the tested zone having transitions, so that the test will come back into play if we ever gain support for transitions on Android. Fixes: QTBUG-69129 Change-Id: Ie4f96601b8b18cd496efbde7cf2557875cf3c1c9 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>