Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.2.1
-
None
-
Windows 7 SP1 x64 Professional, Qt 5.2.1, MinGW 4.8.
-
6d3e5ac6d2f34a0da609f863bed95d3be571c589, 68bcccac228b73c54137304718c3c92460bc1f4b, 4cce7dc19d0243d4d8f6f5f06365e251dbe1e7aa
Description
Consider
const char* tzMoscow = "Europe/Moscow"; QTimeZone moscow(QByteArray::fromRawData(tzMoscow, qstrlen(tzMoscow))); Q_ASSERT(moscow.isValid()); QTimeZone::OffsetDataList odl = moscow.transitions(QDateTime(QDate(2013, 1, 1)), QDateTime(QDate(2014, 12, 31)));
returns empty list, even though there should be transitions in 2014.
That's because QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) returns invalidData() if there are no transitions in the specified year, and
QTimeZonePrivate::DataList QTimeZonePrivate::transitions(qint64 fromMSecsSinceEpoch,
qint64 toMSecsSinceEpoch) const
quits if it gets invalid data during filling the list, even though there are transitions in year 2014 (but not in year 2013, which is the year this function starts with in my example).
QWinTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) and QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) have this bug too. They all look at the specified year only, but here in Russia we had several years without transitions at all.
In addition, consider:
QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const { // Convert MSecs to year to get transitions for, assumes no transitions around 31 Dec/1 Jan int year = msecsToDate(forMSecsSinceEpoch).year(); qint64 first; qint64 second; qint64 next = maxMSecs(); qint64 stdMSecs; qint64 dstMSecs; QWinTransitionRule rule; do { // Convert the transition rules into msecs for the year we want to try rule = ruleForYear(year); // If no transition rules to calculate then no DST, so just use rule for std if (rule.standardTimeRule.wMonth == 0 && rule.daylightTimeRule.wMonth == 0) break; calculateTransitionsForYear(rule, year, &stdMSecs, &dstMSecs); if (stdMSecs < dstMSecs) { first = stdMSecs; second = dstMSecs; } else { first = dstMSecs; second = stdMSecs; } if (forMSecsSinceEpoch >= second && second != invalidMSecs()) next = second; else if (forMSecsSinceEpoch >= first && first != invalidMSecs()) next = first; // If didn't fall in this year, try the previous --year; } while (next == maxMSecs() && year >= MIN_YEAR); return ruleToData(rule, forMSecsSinceEpoch, (next == dstMSecs) ? QTimeZone::DaylightTime : QTimeZone::StandardTime); }
If the function breaks out of the cycle on the 1st pass, it will then use uninitialized local dstMSecs variable.
Attachments
Issue Links
- depends on
-
QTQAINFRA-1468 Coin: Log files are not accessible
- Closed
- is duplicated by
-
QTBUG-46369 QDateTime::toUTC() broken under Windows for (at least) "Europe/Moscow" time zone
- Closed
- relates to
-
QTBUG-46455 Time is incorrect for a given milliseconds since epoch under Moscow's timezone
- Closed
-
QTBUG-64122 Incorrect daylight saving time offset.
- Closed
- resulted in
-
QTBUG-66367 WIN64: 'Cannot open include file: 'unicode/ucal.h'' and 'unresolved external symbol ... QWinTimeZonePrivate' errors for QTimeZone test builds using mingw-w64 and MSVC
- Closed