From ed5f36eb10d0149783281a8f0e0215095d8b4de5 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 26 Oct 2017 20:53:33 +0200 Subject: Avoid duplicate rules in QWinTimeZonePrivate::init() It was iterating the full range of years, adding a rule for each year. The rules have a startYear member and are used for later years until the next rule's startYear, so we don't need to duplicate them; and the system APIs we get them from do support recurrent rules (with wYear set to 0), that apply to ranges of years. So propagate that recurrence and reuse rules where we can. Change-Id: Ifdd292d3f3d3e07969d7a02bb01f2a0110d32950 Reviewed-by: Thiago Macieira --- src/corelib/tools/qtimezoneprivate_win.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp index ad4860e961..3bce55925f 100644 --- a/src/corelib/tools/qtimezoneprivate_win.cpp +++ b/src/corelib/tools/qtimezoneprivate_win.cpp @@ -277,6 +277,20 @@ readDynamicRule(DYNAMIC_TIME_ZONE_INFORMATION &dtzi, int year, bool *ok) } #endif // QT_USE_REGISTRY_TIMEZONE +static bool isSameRule(const QWinTimeZonePrivate::QWinTransitionRule &last, + const QWinTimeZonePrivate::QWinTransitionRule &rule) +{ + // In particular, when this is true and either wYear is 0, so is the other; + // so if one rule is recurrent and they're equal, so is the other. If + // either rule *isn't* recurrent, it has non-0 wYear which shall be + // different from the other's. Note that we don't compare .startYear, since + // that will always be different. + return equalSystemtime(last.standardTimeRule, rule.standardTimeRule) + && equalSystemtime(last.daylightTimeRule, rule.daylightTimeRule) + && last.standardTimeBias == rule.standardTimeBias + && last.daylightTimeBias == rule.daylightTimeBias; +} + static QList availableWindowsIds() { #ifdef QT_USE_REGISTRY_TIMEZONE @@ -500,7 +514,10 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId) QWinTransitionRule rule = readRegistryRule(dynamicKey, (LPCWSTR)QString::number(year).utf16(), &ruleOk); - if (ruleOk) { + if (ruleOk + // Don't repeat a recurrent rule: + && (m_tranRules.isEmpty() + || !isSameRule(m_tranRules.last(), rule))) { rule.startYear = m_tranRules.isEmpty() ? MIN_YEAR : year; m_tranRules.append(rule); } @@ -532,7 +549,10 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId) for (DWORD year = firstYear; year <= lastYear; ++year) { bool ok = false; QWinTransitionRule rule = readDynamicRule(dtzi, year, &ok); - if (ok) { + if (ok + // Don't repeat a recurrent rule + && (m_tranRules.isEmpty() + || !isSameRule(m_tranRules.last(), rule))) { rule.startYear = m_tranRules.isEmpty() ? MIN_YEAR : year; m_tranRules.append(rule); } -- cgit v1.2.3