summaryrefslogtreecommitdiffstats
path: root/src/corelib/time
Commit message (Collapse)AuthorAgeFilesLines
* QDateTime: Limit string processing to known boundariesMårten Nordheim2021-10-201-6/+18
| | | | | | | | | | | We were treating the input as if it was always reasonably good. Since we know the max boundaries anyway lets just stop processing when those are reached Fixes: QTBUG-97489 Change-Id: Ibb78d6d51ad58454b2007ab46d54116ca0be5448 Reviewed-by: Robert Löhning <robert.loehning@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Convert Latin1 to UTF-16 before passing to ICU APIEdward Welbourne2021-10-141-5/+5
| | | | | | | | | | The ICU UChar type is a UTF-16 type, not a single-byte type, so passing it the data() of a QByteArray representing an ID is misguided. Fixes: QTBUG-97486 Pick-to: 6.2 6.2.1 Change-Id: I6789f491674b1d913eb8655d788b497e2fc06f7a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Fix handling of time-zone gap in QTimeZonePrivate::dataForLocalTime()Edward Welbourne2021-10-121-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | This was handled correctly when the backend supplies transitions bracketing the time in question, but the fallback code tried to use the DST offset at the time with larger offset from UTC; this did not work when the gap was due to a change in standard time. Discovered by ANS1 parsing of a date-time with two-digit year, for which the date-time parser tried to use 1921-05-01T00:00 local time when filling in the fields it had parsed; but, when run in Europe/Helsinki, there is no such time due to the 20m 11s skipped when joining EET from the prior local solar mean time. Correct the calculation to use the actual change in offset from UTC, as used in the (far better tested) between-transitions branch of the code, rather than the DST offset after the transition. Add a test-case based on the ASN.1 certificate date whose parsing revealed the issue. Although it seems nothing in Coin can reproduce the issue, the reporter has verified that the test does indeed fail on the system where the bug was found and the fix does fix it. Fixes: QTBUG-96861 Pick-to: 6.2 Change-Id: I12b02bad01daca2073d1a356452cd573684aa688 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* corelib: Fix typos in documentationJonas Kvinge2021-10-122-2/+2
| | | | | | Pick-to: 5.15 6.2 Change-Id: I64d63af708bc6ddaabd12450eb3089e5077f849e Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* corelib: Fix typos in source code commentsJonas Kvinge2021-10-124-6/+6
| | | | | | Pick-to: 6.2 Change-Id: Ic78afb67143112468c6f84677ac88f27a74b53aa Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Set tm_isdst = -1 before calling mktime()Edward Welbourne2021-10-111-0/+3
| | | | | | | | | | | Leaving it set to 0 will cause mktime() to interpret other fields as in standard time, potentially "correcting" them and tm_isdst to represent the equivalent moment in daylight-saving time. Set it to -1 to tell mktime() to let the system work out whether the time is standard or daylight-saving. Change-Id: Id33d4cb0afdb14f236ca5ce04cf605610a30d712 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Broaden condition on use of MS's localtime_s()Edward Welbourne2021-10-111-2/+2
| | | | | | | | | | | | It's available on MinGW, so not limited to MSVC; and the MinGW localtime() and localtime_r() fail in some cases where it works. Use the generic name rather than _localtime64_s(), since localtime_s() now just calls it; and, in any case, we were assuming time_t is __time64_t when calling it. Change-Id: I316cc5b1a3e19cd6725555042dfaba3124a25a03 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Remove an overly-complex assertionEdward Welbourne2021-10-041-9/+0
| | | | | | | | | | | | | | | | | | | | | | | | | It tried to sanity-check the correction being made to the time as a result of converting zone to UTC, but handling also the case where the correction avoided a gap. However, there are too many quirky cases to permit a simple condition. The latest to trip it up is a case of a zone leaving local solar mean time; a time in the gap that hits is shunted by the width of the gap, which could be any old thing, and won't show up on the data describing the zone before or after the transition. In any case, one branch of the check was doubling the zone's standard time offset, which makes no sense. As that was checking for double-DST, it would need to check standard offset plus twice the usual DST offset; but the data it's looking at probably has its DST offset set to the doubled one that needs to deal with. In general a change in DST without going via standard time will have problems here, and a change to standard time could also present problems. Stop trying to shore up the assert and just trust the offset we got. Change-Id: I4519f47e79dfb7595f4a12c259b80a338bc7033c Reviewed-by: Andreas Buhr <andreas.buhr@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QDateTime: fix build with MinGW: need unistd.h very earlyThiago Macieira2021-09-291-3/+0
| | | | | | | | | | | qobject.h has #include <chrono>, which #includes <ctime>, which includes <time.h>. datetime.cpp:2621:23: error: 'localtime_r' was not declared in this scope; did you mean 'localtime_s'? Pick-to: 6.2 Change-Id: I2bbf422288924c198645fffd16a922719c4ce7d4 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Fix QDateTimeParser's handling of 't' format to match serializationEdward Welbourne2021-09-201-1/+4
| | | | | | | | | | | | | | | | | | This amends commit 68f19fb630dc02463c2d61fc511de7407687795e to only consume one 't' from the format string, to match qlocale.cpp's serialization of time-zone specifiers, which only consumes one, so will repeat the time-zone specifier as many times as unquoted t appears in the format. It's hard to imagine why anyone would want this behavior, but it's what our serialization has always done and parsing should match serialization. Add test-cases for double time-zone specifier. Delete a lie in the process. Task-number: QTBUG-95966 Change-Id: I574896040a74085dee89a4fefd8384be44ad827b Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Remove conditioning on Android embeddedEdward Welbourne2021-09-173-11/+11
| | | | | | | | It is no longer handled separately from Android. This effectively reverts commit 6d50f746fe05a7008b63818e77784dd0c99270a1 Change-Id: Ic2d75b8c5a09895810913311ab2fe3355d4d2983 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
* Modernise and simplify handling of qtimezoneprivate_data_p.h's dataEdward Welbourne2021-09-102-120/+68
| | | | | | | | | | | | | | | | | Add some trivial inline methods to the classes that populate the tables to simplify access to their data. Use ranged-for loops to iterate those tables (now that they no longer have bogus all-zero entries at the end). In the process, noticed windowsIdToDefaultIanaId() doing a double iteration of the windowsDataTable, first via toWindowsIdKey() to map a windowsId to a key, then again to map that key to the matching ianaId; inline the former and use the table row from which it got the key to extract its ianaId instead. Change-Id: I76267f53c7e6f5c593e33b6146b8f98bfb6d042f Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Remove trailing zero rows from qtimezoneprivate_data_p.h's tablesEdward Welbourne2021-09-102-8/+4
| | | | | | | | | | They are not needed. Iterations over the table track their sizes. The size-of-table constants just needed their -1s removed. Incidentally use std::size() rather than sizeof(array)/sizeof(element). Change-Id: Ie20eef9f6f5786d93c10b830a87e006d3c5bcc1a Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Add new am/pm format-specifier that preserves locale's caseEdward Welbourne2021-09-083-47/+66
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The existing a, ap, A and AP specifiers all force the case of the formatted am/pm indicator. The indicators returned by QLocale's amText() and pmText() methods are those given in CLDR, with no case coercion. Application writers may reasonably want these strings used verbatim, rather than having to chose a case and impose it on the locale's indicators, in defiance of national custom. For example, while en_US uses upper-case indicators by default, cs_CZ uses lower-case ones. An application author writing a time format has been forced to chose which of these locales to be wrong in. Add support for aP and Ap specifiers, whose mixed case indicates that the locale's case is to be respected. Amend an existing test-case of tst_QLocale's formatDateTime() that used Ap (expecting, of course, an upper-case indicator followed by a stray p) to now expect the locale-appropriate-cased indicator. Extend formatTime() to test cases using aP and Ap, to illustrate the difference between en_US and cs_CZ. Rework QDateTimeParser to also support the new format specifier. This required expanding its Case enum, used by the getAmPmText() method, which was formerly shared with QDateTimeEditPrivate; however, as that class no longer makes any reference to this method, it and the enum can be made private, allowing a systematic clean-up of their use. Added test-cases for both serialization and parsing; and amended some existing parsing tests to verify am/pm indicators are matched case-insensitively. [ChangeLog][QtCore][Important Behavior Changes] Time formats used by QLocale, QTime and QDateTime's parsing and serialization now recognize 'aP' and 'Ap' format specifiers to obtain an AM/PM indicator, using the locale-appropriate case for the indicator, where previously the author of a time format had to pick a case that might conflict with the user's locale. For QTime and QDateTime the locale is always C, whose indicators are uppercase. For QLocale, the case will now match that of amText() or pmText(). Previously, 'aP' would have been read as a lower-case indicator followed by a 'P' and 'Ap' as an upper-case indicator followed by a 'p'. The 'P' or 'p' will now be treated as part of the format specifier: if the prior behavior is desired, either use 'APp' or 'apP' as format specifier or quote the 'p' or 'P' in the format. The prior 'a', 'ap', 'A' and 'AP' specifiers are otherwise unaffected. Fixes: QTBUG-95790 Change-Id: I26603f70f068e132b5c6aa63214ac8c1774ec913 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* Remove a redundant checkEdward Welbourne2021-09-021-1/+1
| | | | | | | | | Missed in a recent fix to QTimeZonePrivate::dataForLocalTime(), but noticed during picking back to 5.12 Pick-to: 6.2 Change-Id: I63964952150fedf857b7aef12dfc866097d2e2d1 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Fix corner case in QTimeZonePrivate::dataForLocalTime()Edward Welbourne2021-09-011-14/+18
| | | | | | | | | | | | | | | If the local time for which we want data is after the last known transition, the two transitions we get to bracket it are the last known and an invalid one. The code checked the former was valid, but neglected to check the latter, leading to nonsense arithmetic later in the function. In this situation we unequivocally want the last known transition, so the problem is easily solved. Fixes: QTBUG-96152 Pick-to: 6.2 6.1 5.15 5.12 Change-Id: I6fc830ce538e8a572093cd8dfe832e10689bf904 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Convert various callers of strtou?ll() to call strntou?ll()Edward Welbourne2021-08-301-9/+3
| | | | | | | | Where size is known or can readily be determined. Change-Id: I442e7ebb3757fdbf7d021a15e19aeba533b590a5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Doc: Fix documentation issues for Qt CoreTopi Reinio2021-08-241-14/+14
| | | | | | | | | | | | | | * Tag deprecated Q(Multi)Map operators in the header to correctly match them with documentation \fn commands. * Add documentation for QByteArrayView comparison operators. * Add a dummy typedef 'jfieldID' for generating docs correctly on non-Android platforms * Fix other minor issues Pick-to: 6.2 Task-number: QTBUG-95860 Change-Id: I141d2f75d6aa10557aa374201f09ad74b4cd6e81 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* wasm: fix assert in QDateTimeLorn Potter2021-08-191-1/+1
| | | | | | | like windows, we dont have historical time data Change-Id: Iab77c1e2949bc909324f18209e6c52324c80a548 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QDateTime: port to QStringTokenizer and QVLAMarc Mutz2021-08-181-3/+6
| | | | | | | | | | | | | The code isn't easily linearized to work directly with QStringTokenizer, which is a forward-only range, but we can at least remove the (non-error) memory allocations by supplying a suitably-sized QVLA to tokenize into instead of the default QList. Change-Id: I1aa11a5fbbe66ede4ec2e5b2090044a39052a241 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QDateTime: port away from takeFirst() useMarc Mutz2021-08-161-6/+11
| | | | | | | | | | | | | | | | | | Use the std-compatible API subset instead. This is in preparation of using QVarLengthArray instead of QList here, which (thankfully, because it's inefficient for arbitray T) doesn't have pop_front(). As a drive-by, port at(0) to front() and introduce a temporary variable. The front() call will briefly emit a detach attempt (but the container isn't shared, so it won't actually detach), but only until the next patch ports to QVLA. Change-Id: I38ee123aa6730aee5ba1e14ec46fc71c5d74986e Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QCalendarRegistry: Explicitly disable moving and copyingIevgenii Meshcheriakov2021-08-101-0/+2
| | | | | | | | | | | | | | | | | | | Add Q_DISABLE_COPY_MOVE to QCalendarRegistry to silence the following warning produced by QtStaticAnalysisBot: class 'QCalendarRegistry' defines a non-default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator QCalendarRegistry is a singleton so it does not need to be moved or copied. The warning was introduced by d0ae1ef33a6eed02acde7304298794f4f0119e16. Task-number: QTBUG-93004 Pick-to: 6.2 Change-Id: I5e018346415b9d0a1ebc3bbde2ab7c3ad5e6d9d0 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QCalendar: Delete registered calendar backends on program exitIevgenii Meshcheriakov2021-08-062-17/+76
| | | | | | | | | Add code to check if the calendar registry is destroyed to all QCalendar methods that dereference QCalendarBackend pointer. Pick-to: 6.2 Change-Id: I9b562355e2e0579396b52968f6065c6927cc9ca8 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QCalendar: Thread-safe calendar backend registrationIevgenii Meshcheriakov2021-08-0615-416/+499
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | All calendar backend accounting was moved into QCalendarRegistry class (renamed from Registry). Calendar backends are no longer registered inside constructors, because in multithreaded environment this may lead to incompletely initialized instances becoming visible via QCalendar API in multithreaded environment. All system backends are registered by QCalendarRegistry itself when they are needed. New method QCalendarBackend::registerCustomBackend() is provided to register any 3rd-party calendar backends. Registration by names was also simplified. The list of names is now passed to QCalendarBackend::registerCustomBackend(). The checks are provided to ensure that all system backends have non-conflicting names. Name conflicts for custom backends are resolved in favor of earlier registered backends, as it is already the case in the existing code. The documentation was updated to reflect that. Method QCalendarBackend::names() was added to query the list of names associated with a backend after it is registered. Calendar backend deregistration was completely removed because it is not possible to perform it safely without reference counting. Fixes: QTBUG-93004 Pick-to: 6.2 Change-Id: I0ab1eccc02fdd1e1c66b5e5dd076c93de32d5a49 Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* time: Rerun cldr2qtimezone.pyIevgenii Meshcheriakov2021-07-271-33/+33
| | | | | | | | | | | | | | This updates qtimezoneprivate_data_p.h changing any mention of Country to Territory in it. The change was introduced by the following commit: e51831260a759b58cb089cac089c202a795fc584 There are no code changes. This reduces number of changes visible after rerunning cldr2qtimezone.py. Pick-to: 6.2 Change-Id: I0898ecf224108604b7178e31fa7e76b4cb13a965 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QCalendar: Make SystemId constructors with one argument explicitIevgenii Meshcheriakov2021-07-271-2/+3
| | | | | | | | This avoids unwanted type conversions. Pick-to: 6.2 Change-Id: Ie57e80da615c6bc162224fa3816fc21a47ab4b00 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QCalendarBackend: Use QAnyStringView to create backends by nameIevgenii Meshcheriakov2021-07-273-17/+5
| | | | | | | | | | | | | | Combine two implementations of QCalendarBackend::byName() accepting QStringView and QLatin1String arguments into one accepting QAnyStringView to reduce code duplication. Add a note to QCalendar constructors accepting strings to do the same for Qt 7. Change-Id: Idfc3b9c61e22712543c723bd94fcd788da52780a Pick-to: 6.2 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Doc: Ensure deprecated APIs in Qt Core are documented as suchNico Vertriest2021-07-231-1/+1
| | | | | | | | | | Added \deprecated [version_since] when needed Remove references to deprecated functions in \sa statements Fixes: QTBUG-94534 Pick-to: 6.2 Change-Id: I3b3d4277d63fc5d6d207c28ff2484aed30b83247 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Remove some now-redundant casts to qint64Edward Welbourne2021-07-221-8/+3
| | | | | | | | | | | | | One was long redundant. The other two, relatively recently added, should be redundant thanks to the former enum member MSECS_PER_DAY being changed to a constexpr qint64 by commit 4059af81d33bb1f6a7773b77d3039f2fc53fcd23 Change-Id: I601ed8dae905fed6399ce29c25545ec651e9838a Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* Make QCalendarBackend's ID an opaque typeEdward Welbourne2021-07-198-60/+107
| | | | | | | | | | As Giuseppe pointed out in API change review, an opaque type should be used. Task-number: QTBUG-94407 Pick-to: 6.2 Change-Id: I862a6f52d284317e1243fd91f45bb0af130d154a Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
* Make locale ordering transitiveEdward Welbourne2021-07-143-24/+24
| | | | | | | | | | | | | | | | | | | | | | | The ordering function used to sort the locale data generated for QLocale attempted to sort the default territory for a given language and script before other territories, but was too tangled for it to be obvious this is what it was doing. The result turned out to be non-transitive. Replace with code that implements the same preference but only applies it where the result is compatible with transitivity. This leads to a shuffling of the order of the Serbian-language locales, which sorts the Cyrillic ones before the Latin ones. This is consistent with my reading of the CLDR data, which fills in Cyrillic and Serbia for Serbian; Serbian/Cyrillic/Serbia did previously sort before all other Serbian variants. Thanks to Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io> for discovering the non-transitivity. Pick-to: 6.2 Change-Id: I0ce9f78e620e714f980f32b85b7100ed0f92ad74 Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io> Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
* Use qMod(, 7) rather than % 7 in day-of-week calculationEdward Welbourne2021-06-251-1/+1
| | | | | | | | | | | | Otherwise, for the first day of a negative year, we'd get an invalid day of the week (required to be in the range 1 through 7). This is a follow-up to commit 1f4b237dade9d0d2ed5439e3834ac22985797561. Change-Id: If1afcd42065c26d5fa5799b0cd47921a3d424dc8 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Use UTC when parsing only a date or only a time, not a date-timeEdward Welbourne2021-06-231-5/+10
| | | | | | | | | | | | | | | | | | | | | | | | This should reduce the amount of fall-out from DST complications. Also document the assumptions of QDateTimeParser's two fromString() methods (and fix the punctuation on the QDateTime parameter). Adjusted some tests to match. Since only QDateTime-returning methods will show the difference, and it's at least somewhat odd to be using those on QDateEdit or QTimeEdit, this should have little impact on API users. [ChangeLog][QtCore][Behavior Change] QDateEdit and QTimeEdit now operate in UTC, to avoid spurious complications arising from time-zone transitions (e.g. DST) causing the implicit other half to combine with the part being edited to make an invalid result. Returns from their dateTime() and other methods returning QDateTime (max/min) shall thus be in UTC where previously they were in local time. QDateTimeEdit continues using local time. The default can be over-ridden by setTimeSpec(), as ever. Change-Id: I44fece004c12342fe536bbe3048217d236fd97b2 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Fix handling of day-of-week in QDateTimeParser and QDateTimeEditEdward Welbourne2021-06-231-21/+82
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDTP's absoluteMax(), setDigit() and getDigit() simply treated day-of-week as synonym for day-of-month. Consequently, QDTE::stepBy() did the same. This meant that wrapping happened at the month boundary, so would jump within the week if it wrapped around, otherwise the up/down arrow would "jam" at a particular day of the week when further steps would leave the month. Instead, when wrapping, wrap round the week while still moving the day-of-month to match, jumping back or forward a week to stay within the month on hitting a month boundary; otherwise, stop backwards stepping on hitting the locale-specific day of the week, or forward stepping when the step would be to or past this first day. Fixed various bugs found in the course of testing this. [ChangeLog][QtWidgets][QDateTimeEdit] Corrected handling of weekdays. Previously, changes to the week-day were simply changes to the day of the month. Weekday fields are now handled as such: changes to them do change the day of the month, but a change that would step past the end (or start) of the month is adjusted to the relevant day of the nearest week within the month. When wrapping is disabled, the locale-specific first and last days of the week are the bounds. Formats which specify day of week but not day of month will now preserve day of week when changing month or year, selecting the nearest day of month that matches. Change-Id: I7868b000fea7a4bc17a1b5687c44bcd56d42ae90 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Use year with same day-of-week pattern as fallback for out-of-rangeEdward Welbourne2021-06-163-22/+51
| | | | | | | | | | | | | | | | | | | The kludge previously implemented for handling dates outside the supported time_t range, by asking for a corresponding date in a year in the range, had a comment remarking that this is broken due to the wrong day of the week and, consequently, the placement of DST transitions, e.g. those scheduled by the last Sunday of a month, happening on different dates in the year asked about and the in-range year passed to the system time_t functions. This can be handled by selecting a year in the time_t range which has the same pattern days of the week (and length of the year, i.e leap-ness). That may (particularly for leap years) need to select a year far from the end of the range (and there may be a change to the zone's rules between the selected year and the end). Change-Id: Ia353b2cc7b7d266b7abf80e37cac61544ce95c2d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QTimeZonePrivate: Reduce copying by not using QByteArrayMårten Nordheim2021-06-141-26/+32
| | | | | | | | | | QByteArray creates copies of data, but we usually don't need the copy and a view, for comparison or fetching substrings, is enough. So instead we use QBAView and QLatin1String (when we need to go through QStringTokenizer). Change-Id: I12e0bd8777fc63f676b9371abfd345fab1046c44 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Rework massageAdjusted and make the most of its DST knowledgeEdward Welbourne2021-06-141-17/+41
| | | | | | | | | | | | | | | | | | Since massageAdjustedDateTime() has to split LocalTime from TimeZone and call {local,zone}MSecsToEpochMSecs() in any case, its call to refreshZonedDateTime(), via checkValidDateTime(), was duplicating that work uselessly. So handle UTC and offset-from-UTC separately with a call to refreshSimple and handle local/zone time by inlining what remains of refreshZonedDateTime() aside from the duplication. At the same time, recent reworking of qt_mktime() make localMSecsToEpochMSecs() handle its DST-hint the same way zoneMSecsToEpochMSecs() has long done so, to take care of the intended handling of DST gaps and repeats. Change-Id: Id6bef7dd0f8983c3e923f4580a62a76aa6fcb810 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* Stop using mixed enum arithmeticGiuseppe D'Angelo2021-06-131-11/+9
| | | | | | | | | | | It's deprecated. Port some unnamed enumerations (used only to declare constants) to constexpr integers instead. Apply qToUnderlying as needed. Task-number: QTBUG-94059 Change-Id: Ifaa64ece966ce08df40dc71ffcfa7ac038110e0b Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QTimeZonePrivate::territory: use QStringTokenizerMårten Nordheim2021-06-121-6/+4
| | | | | | | | | | A follow-up to 6ec3321875b9fb2f72cc875ba191aa8123e7d5a5 where the function was optimized using a hand-rolled lazy-split on a QBAView. Now that QLatin1String::indexOf(QLatin1String) has been optimized we can use QStringTokenizer instead. Change-Id: I30b15d309e7c364c0a4dafe31651b39ea14db7e5 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Fix date parsing when local time lacks the start of the dayEdward Welbourne2021-06-111-13/+26
| | | | | | | | | | | | | | | | | | | The case where a parsed date-time fell in a transition, but only because the default value for some field lead it there, only dealt with the case of parsing a date-time, which is the only time it should be relevant. However, since the date and time do get combined as a date-time (even when only one of them is relevant) the same problem could arise when parsing a date (on which the current time-zone happened to make a transition at the start of the day) or a time (if the default date happens to be one on which the current zone had a transition). So handle both of those cases, as well as the date-time case. Fixes: QTBUG-91120 Pick-to: 5.15 6.1 6.2 Change-Id: I565d115eb85cd2ee69fa500fcd40b05bcf8f6fff Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Correct handling of last second of 1969 (again)Edward Welbourne2021-06-111-48/+139
| | | | | | | | | | | | | | | | | | | | | | | | | | | | In my prior attempt to handle the last second of 1969, I forgot that the QTime we're describing is a local time, so whether *it* thinks we're at the last second of the day is beside the point. Fortunately, preceding second should get -2 as return if mktime()'s initial -1 actually meant the last second of 1969, so we can test via that, after a cheap pre-test to save doing this too often (albeit we only even attempt the check if mktime() returned -1 in any case). Restructured qt_mktime() in the process to deal with the error case's early return promptly instead of doing it in an else clause. Also repackage the calls to mktime to isolate various quirks and simplify the logic in qt_mktime(). This also prepares for setting tm_isdst as a hint when we know when we came from, in massageAdjustedDateTime(). Refined one test, added two more test cases. These didn't fail before this fix, but a judiciously-placed qDebug() in testing revealed that localMSecsToEpochMSecs() resorted to its fall-back handling - as if the date-time were outside the time_t range - due to qt_mktime() failing, for these test-cases (and several others). This fix evades that fall-back behavior; a judiciously-placed qDebug() shows none of our test-cases now fail callMkTime(). Change-Id: I11aa5015191dc4a565c28482307f7bc341c207e7 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Rework setMSecsSinceEpoch() to avoid local->UTC conversionsEdward Welbourne2021-06-111-44/+41
| | | | | | | | | | | | | The function takes a UTC time, which it converts to local time when needed, but its (two) calls to refresh a local time instance were doing the (more expensive) reverse conversion, which we don't need (because we knew UTC to start with) and, in this case, it can't land on an invalid time, so we don't need to cope with that. Change-Id: I49b42bfa9f6a5fde12810f5a0da9ff4466ca86a4 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* QTimeZonePrivate: make windowsId return a QByteArrayViewMårten Nordheim2021-06-071-2/+2
| | | | | | | | In debug this cuts off about 4 seconds off of the qtimezone test on my machine. In release it's about 300-400 milliseconds. Change-Id: I92ec18794247e3846704a7c8e87a8c34fdae5e3c Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Simplify QDate::weekNumber()Edward Welbourne2021-06-071-7/+5
| | | | | | | | | Eliminate two local variables and don't even compute the year if we don't need it. Change-Id: If968c619750cead317641885a0fb9b9974954782 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QDateTime{Parser,EditPrivate}: clean up initializationEdward Welbourne2021-06-031-6/+5
| | | | | | | | Initialize members by assigning them where declared, where possible, rather than duplicating initializations in constructors. Change-Id: I35c398581ad649210aaec979ea7c6c2fc2cb0bca Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Check for overflow in QDateTime::setMSecsSinceEpoch()Edward Welbourne2021-05-261-7/+11
| | | | | | | | | | | | | | | When adding an offset from UTC, arithmetic may overflow. Likewise when combining a date and time (that have been offset for UTC). Also check the return from epochMSecsToLocalTime(), as it can fail; and pay attention to the status stored by setDateTime(), to notice when it hits an overflow. Fixed some tests that only passed because we neglected these checks. Extended a test to check we detect overflow in a couple of cases close to the extremes. Change-Id: I127a670302f94a07bb9b087b1b9c608b7c08785c Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Øystein Heskestad <oystein.heskestad@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Harmonize zoneMSecsToEpochMSecs() and localMSecsToEpochMSecs()Edward Welbourne2021-05-262-26/+27
| | | | | | | | | | | Now that the latter calls the former in its fall-back, this saves that call the need to follow up with determining DST and abbreviation. This also lets refreshZonedDateTime() update its DST guess for timezones as well as for local time. Change-Id: I820b65c1d6db78619defe2af5e947cb98ae336f0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Use time-zone transition data before 1970 as well as afterEdward Welbourne2021-05-263-165/+195
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Doc: Use \deprecated instead of \obsoletePaul Wicking2021-05-261-1/+1
| | | | | | Task-number: QTBUG-93990 Change-Id: I4e512354a49dde6678ca89cabc56bc76ba666bb3 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Initialize SYSTEMTIME to {} instead of memset()ingEdward Welbourne2021-05-251-12/+6
| | | | | | | Change-Id: Ic17b90d10d6b5b7f4610e904e18979fc1d658a0a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>