When parsing a string whose time-zone part matches local time's name,
use local time in preference to the QTimeZone with that name. The case
is ambiguous, and the bug was already fixed (by something else) in
dev, but this caused a failure in 6.2 through 6.5; and using local
time is more natural to QDateTime in any case. The fix incidentally
makes the the logic of the zone-resolution code more straightforward
and a closer match to how findTimeZone() found the match.
The issue was hidden from 6.6 by a change [*] to the handling of POSIX
rules, that lead to plain abbreviations such as CEST and BST - for
which the IANA DB has no entry - no longer being considered "valid"
zones, despite being technically valid POSIX zone descriptors
(effectively as aliases for UTC).
[*] commit 41c561ddde
Pick-to: 6.6 6.5 6.2
Fixes: QTBUG-114575
Change-Id: I4369901afd26961d038e382f4c4a7beb83659ad7
Reviewed-by: Konrad Kujawa <konrad.kujawa@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Add the boilerplate standalone test prelude to each test, so that they
can be opened with an IDE without the qt-cmake-standalone-test script,
but directly with qt-cmake or cmake.
Boilerplate was added using the following scripts:
https://git.qt.io/alcroito/cmake_refactor
Manual adjustments were made where the code was inserted in the wrong
location.
Task-number: QTBUG-93020
Change-Id: I28b6d3815c5f43d2c33ea65764f6f3f8f129eaf3
Reviewed-by: Amir Masoud Abdol <amir.abdol@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Some zones that fell into one or another of the supported groups had
different start times or even dates for their transitions, causing the
tests to fail in those zones. Adapt the test data to them.
In the process, arrange for part of the test to report more: verifying
a value is 1 or -1 sadly leaves no report of what it was when it
wasn't. So use the scope-guard report pattern to do that on failure.
Change-Id: I01cc4a90e3b45867ba0edb2d6c46397d465046ff
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
It turns out glibc stops varying DST changes past where a 32-bit
signed day-count from 1970 reaches (which, all things considered, can
hardly be called a bug, for all that it's ...), at odds with QTZ's
extrapolations from the current IANA DB rules. As the last date QDT
can represent happens to be in the opposite side of everyone's DST
from the one that leaves zones in, this lead to the 2038
local-time-type not reliably being useful for predicting the max-date
behavior. So add a distant-future time-type that probes beyond glibc's
cut-off, and have relevant tests check that instead of the 2038 one.
Change-Id: If4e244d80fe2447da3bb9d5c406808c6c22c0a73
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
There's no need to check the year or day-of-month (which involve
calendrical calculations) when we can perfectly well just check the
Julian Day number that's implied by the day-number parameters to
setType(), which could just as well return the LocalTimeType to be
assigned to the relevant parameter instead of doing the setting
itself. With that rearrangement, making it into a private static
method, the members it's used to initialize can then be const and
initialized during construction.
Change-Id: Ib7d295c3fbb9b90652952627456cdfb6176b8119
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The second pass through each test case, going via UTC, applied an
adjustment to the time; however QTime wraps around modulo the day, so
applying a negative adjustment to a time too near the start of the day
could produce a time at the end of the day. I'm preparing to add some
test-case variants for which the transition's UTC date differs from
the date in the zone doing it, which trigger this. Combine the time
with the date before applying the adjustment, so that the date gets
decremented to match the time's wrap-around and conversion from UTC
duly gets back to the correct place, not a day later. The new test
cases (in an imminent commit) thus pass.
Change-Id: I1bd5f191c7673a56ac3fbfc69eab0bc03c9e40b3
Reviewed-by: Mate Barany <mate.barany@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>
It seems glibc's extrapolation of existing DST-rules cuts off at some
point in the distant future, where the IANA DB gives no end-time for
such rules, leading QTimeZone to keep applying them. This lead to
tst_QDateTime::fromSecsSinceEpoch() not getting an invalid date in one
of its bounds-probing tests, due to a within-bounds datetime getting
glibc's offset and then the out-of-bounds one falling back to the IANA
rule's offset that put it back within the bounds.
This directly affected Australasian zones (which glibc locks into
daylight-saving time in this distant future) which were fixed by using
the IANA DB's offset; but the relevant date is in August so other
zones, north of the equator, that glibc locks into standard time, then
had the reverse problem, so we have to take the minimum of the two
sources' offsets to get all zones on board.
Change-Id: I0c94af2ba108dea31bee46aafa4a8cca8d373a5c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Konrad Kujawa <konrad.kujawa@qt.io>
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
This follows up on commit b906796af6.
Fix an off-by-one error - I was testing the last days of December 1799
and June 1800.
Change-Id: I79ab622978d35f91e3e1b1b8d00d93b0d4b31c07
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
MET is an alias for CET, so the test's attempts to detect whether it's
in CET can't distinguish them other than by checking the abbreviation.
Change-Id: Ibb467d9bb2d983ca16302111b54f664a614057c2
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The classification of local time as ahead of UTC, behind it or equal
to it gets complicated by zones near the prime meridian - some of
which have varied which side of it they nominally are - or the
international date line, which a few zones have crossed.
So, instead of having one classifying variable, split to having three,
one for the distant past (when using local solar mean time), one for
the epoch and one for the distant future.
Change-Id: I7c0da376e1625372086dc51afa815756f0bde442
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The zone had a transition at the start of 1900, so QDTP's default date
ends up being 1900-01-01 at 00:02:20 instead of at 00:00:00; and any
parsing of date-time strings that doesn't set the minutes and seconds
consequently ends up "wrong" (about a field that wasn't specified).
Change-Id: If4b9864616fa08bc023a6974dae255f96ca90f83
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
America/Sao_Paulo was not alone in starting 2008-10-19 with a spring
forward. Include the other affected zones in the check to tune the
expected start-of-day time. See [0] for details.
[0] https://github.com/eggert/tz/blob/main/southamerica
Pick-to: 6.5
Change-Id: If251d8b715090319441790696983273637765d2e
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Some QDateTime tests get tripped up by a transition at the epoch in
Baja Mexico. For the operator_eq() and time-difference test, simply
using startOfDay() instead of QTime(0, 0) - which was skipped - solves
the problem. For addDays() and fromStringDateFormat(), skip the
affected tests.
Change-Id: I3620f0d1e4b05d9f799662eea96a40c8284de331
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
We check three sample dates, in different years, so don't compare
their year() to 1970, but to their respective actual years. In the
process, package the arrays iterated for these checks into a constexpr
struct array and reverse them so that, instead of reverse-iterating
and indexing, we can use a ranged-for loop.
Change-Id: I214685346c637875a4ea31125c324851eb4308db
Reviewed-by: Øystein Heskestad <oystein.heskestad@qt.io>
Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>
Reviewed-by: Konrad Kujawa <konrad.kujawa@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
When the test failed, it did so in triplicate.
Pick-to: 6.5
Change-Id: Ia871aed0a5960120a2659a6778c10dccd4b2953a
Reviewed-by: Jason McDonald <macadder1@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
I got tired of being told off by the inanity 'bot for faithfully
reflecting existing #if-ery in new #if-ery. Retain only the
documentation and definition of the deprecated define.
Change-Id: I47f47b76bd239a360f27ae5afe593dfad8746538
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
The new name better matches the names of existing functions there.
A comment on the old code noted that such a move should really be
done, so as to correctly share the environment-mutex locking.
In the process, move the (now three) time-related internal functions
from qglobal_p.h to a new qtenvironmentvariables_p.h since that's the
natural place for them given where they're defined (and the fact that
they're for internal use only).
Change-Id: Ib028baebaf31a806a2c0c97caaaba0a466c11cea
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
As foreshadowed when QDateTime adapted to route all QTimeSpec use
through QTimeZone, this commit deprecates the old API in favor of the
newly more capable QTimeZone-based API.
Fixes: QTBUG-108199
Change-Id: I9a3f9f94d4a5d8cc229db72b3e4731a9e318a076
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
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>
For now, just addDays() and the springForward() test, as proofs of
concept for future work to be more systematic.
Change-Id: Id2c4e9ad304d3aef6fdfb48ae6328df8c638c934
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Free most APIs using QTimeZone from feature timezone and route all
APIs taking a naked QTimeSpec via these, in preparation for their
eventual deprecation. Since qtimezone.h includes qdatetime.h (and MSVC
blocks our ability to remove the need for that), qdatetime.h's
declarations can't use a default value for QTimeZone parameters; so
add overloads taking no zone (or spec) to handle that.
[ChangeLog][QtCore][QDateTime] All QDateTime APIs involving a
Qt::TimeSpec can now be routed via QTimeZone's lightweight time
description support, saving the need to have different code paths for
different time specs. In the process, QDateTime gains a
timeRepresentation() method to return a QTimeZone reporting the
(possibly lightweight) time description it uses. (The older timeZone()
method always returns a non-lightweight QTimeZone, whose timeSpec() is
Qt::TimeZone.)
Task-number: QTBUG-108199
Change-Id: I23e43401eb2dbe9b7b534ca6401389920dd96b3c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
In the process, split some long lines. The test relies on omitting the
hour (so as to get the default, 0) from both the format string and the
string parsed, so as to test that the parser correctly handles the
corner case where the zone skips the first hour of the day. This was
not entirely obvious when reading the row data, so make it explicit in
a comment.
Change-Id: I919b292b78bd399a8749806a0e913d43f5b414e1
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mate Barany <mate.barany@qt.io>
Test a few more cases are correctly handled.
Change-Id: I7f286ba93f59bf0168cac789cd30590f40e98cee
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The spec deseralized isn't a Qt::TimeSpec; handle it correctly instead
of taking for granted that QDateTimePrivate::Spec's values happen to
match.
Change-Id: I67f3c960f3a3b90cdad3c1eca673f7ec8fd10b82
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Mostly pedagogic checks in operator_insert_extract(), but also
sanity-checking, to confirm spec conversions produce results equal to
what each came from.
In daylightTransitions(), verify the spring forward goes from standard
time to daylight-saving time.
Change-Id: Ieb9c603ee2eadecea055da4e8889528161f4d999
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Use QCOMPARE(a, b) in place of QVERIFY(a == b), similar with
QCOMPARE_LT() and QCOMPARE_LE(); and use a scope-guard to emit a
message on failure instead of incurring the cost of building a string
for the message, even when the passing test doesn't need it.
Change-Id: I3884bc40e89a4b1ba881968b99faab27d4b1abc9
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Principally to get Qt::LocalTime mentions out of the way ahead of the
QTimeZone work on Qt::TimeSpec, but also mop up trailing 0 parameters
to QTime for seconds and milliseconds.
Change-Id: I51041582faae100894a567c9e5ae96a60a3b2d8c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Mate Barany <mate.barany@qt.io>
Left over from long ago, making confused use of Qt::hex.
Change-Id: I7f411e4888ee1a637d2212fd6976dd003f8da9ce
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Several were overlong (or soon to get so by being made longer); others
were inconsistent with neighbors; one was inconsistent with itself.
Change-Id: I272680499605a757e4827d27021bf234a91cf77a
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Comparing to true and false doesn't enrich the output.
Change-Id: Ie26a3f3d584f88310b8d4a31cad07be8dc8cb646
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
[ChangeLog][QtCore][QDateTime] The 't' format character in a
toString() template can now be repeated to get alternatives to the
(unparseable) zone abbreviation. Thus 'tt' now gets the zone offset
without colon, [+-]hhmm; 'ttt' gets the same with colon, [+-]hh:mm,
and 'tttt' gets the zone name. Previously, each 't' was replaced by
another copy of the abbreviation.
Task-number: QTBUG-95966
Change-Id: Iccccd11f06fa732ed27c0e5d4e40a3d4b5f79f8d
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
[ChangeLog][QtCore][QDateTime] The 't' format used in fromString() can
now be repeated to restrict parsing to particular forms. Thus 'tt' now
matches the [+-]hhmm offset format (no colon), 'ttt' the [+-]hh:mm
offset format (with colon), and 'tttt' matches an actual zone
name. When used singly, 't' still matches anything the parser knows
how to interpret as a zone specifier.
[ChangeLog][QtCore][QLocale] The 't' format in toDateTime() now has
repeated forms, as for QDateTime::fromString().
Task-number: QTBUG-95966
Change-Id: I73753145cb66a56bc25a5c2dd5cb051ba982fa2c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Expand a test to cover millsecond format variants more thoroughly,
including a test for the new usage of zz. This applies to parsing the
complement to commit 0a36a7c1db173089c25ea09029505a589a1c59e5's change
to serialization. Fixed minor glitch in the serialization's doc, too.
[ChangeLog][QtCore][QDateTime] When parsing a datetime, the 'zz'
format specifier is now equivalent to 'z', as for serialization.
Change-Id: I1c5700064738d9c92d5e8ce10bff8050131e190f
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
And include qcore_mac_p.h where needed.
Task-number: QTBUG-99313
Change-Id: Idb1b005f1b5938e8cf329ae06ffaf0d249874db2
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
The vast majority of in-tree users pass simple and short C string
literals as the value. By porting to QByteArrayView, we document that
we'll accept non-NUL-terminated data, and do the NUL-termination
internally, using SSO'ed std::string, saving memory allocations in the
common case of short strings.
I didn't bother to check which direction std::string takes for
nullptrs these days (there was a change accepted in that area for
C++20 or 23), so play it safe and protect against them.
Follow-up to
Task-number: QTBUG-105302
Change-Id: I2369acc62f1d5cbc26135396cfe0602d8c75300c
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
When tst_QDateTime::fromStringStringFormat_localTimeZone_data() skips
due to feature timezone being undefined, it should report that as the
issue, rather than claiming the system doesn't support the particular
zones used in the test.
Change-Id: I9837ac95c6d92317fbec7fcca184f7b7e6f81441
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Also document the (seldom helpful) handling of over-long repeats of a
format. Add test to QDateTime and amend QLocale test.
[ChangeLog][QtCore][QDateTime] Doubling the 'z' format in a date-time
or time format string now produces the same output as a single 'z'.
Previously, this would have produced two copies of the milliseconds
field (eliding any trailing zeros in each). Contrast with 'zzz', which
produces the full milliseconds field, including any trailing zeros.
Change-Id: I4c60462b062fee4079370096d745c191c1939506
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
CMakeLists.txt and .cmake files of significant size
(more than 2 lines according to our check in tst_license.pl)
now have the copyright and license header.
Existing copyright statements remain intact
Task-number: QTBUG-88621
Change-Id: I3b98cdc55ead806ec81ce09af9271f9b95af97fa
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
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>
To complement the existing addSecs / MSecs / etc., add a function
that takes any compatible std::chrono::duration.
QTime also features similar functions, but it's also "unique" in that
it uses modular arithmetic (it wraps around in case of "overflow").
I'm not so sure that adding durations to a QTime object therefore
makes sense, and I'm not doing it in this patch.
[ChangeLog][QtCore][QDate] Added addDuration().
[ChangeLog][QtCore][QDateTime] Added addDuration().
Change-Id: I02aa37ff024d7f56fa976dc8f4f73523bdba8d94
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>