From fd7fc981d8f411d6a20d5f45eb31ed356a197bd2 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 31 Oct 2017 16:08:38 +0100 Subject: Restructure Dynamic TZ query to same form as Registry variant Break out the reading of an individual rule to a function and add a fall-back that tries to get a non-dynamic rule when there's no dynamic data for the zone. At the same time, change the first rule, in all cases to apply for all time (i.e. set its .startYear to MIN_YEAR, instead of 1970 or the advertised start range): we'll use it when extrapolating backwards into the past. Change-Id: Ife548c7c7deebef2427d2838f3e12ed7abb631c1 Reviewed-by: Thiago Macieira --- src/corelib/tools/qtimezoneprivate_win.cpp | 56 +++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 17 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp index 8954f5e685..ad4860e961 100644 --- a/src/corelib/tools/qtimezoneprivate_win.cpp +++ b/src/corelib/tools/qtimezoneprivate_win.cpp @@ -259,6 +259,22 @@ static DYNAMIC_TIME_ZONE_INFORMATION dynamicInfoForId(const QByteArray &windowsI } return dtzInfo; } + +static QWinTimeZonePrivate::QWinTransitionRule +readDynamicRule(DYNAMIC_TIME_ZONE_INFORMATION &dtzi, int year, bool *ok) +{ + TIME_ZONE_INFORMATION tzi; + QWinTimeZonePrivate::QWinTransitionRule rule; + *ok = GetTimeZoneInformationForYear(year, &dtzi, &tzi); + if (*ok) { + rule.startYear = 0; + rule.standardTimeBias = tzi.Bias + tzi.StandardBias; + rule.daylightTimeBias = tzi.Bias + tzi.DaylightBias - rule.standardTimeBias; + rule.standardTimeRule = tzi.StandardDate; + rule.daylightTimeRule = tzi.DaylightDate; + } + return rule; +} #endif // QT_USE_REGISTRY_TIMEZONE static QList availableWindowsIds() @@ -484,16 +500,17 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId) QWinTransitionRule rule = readRegistryRule(dynamicKey, (LPCWSTR)QString::number(year).utf16(), &ruleOk); - rule.startYear = year; - if (ruleOk) + if (ruleOk) { + rule.startYear = m_tranRules.isEmpty() ? MIN_YEAR : year; m_tranRules.append(rule); + } } RegCloseKey(dynamicKey); } else { // No dynamic data so use the base data bool ruleOk; QWinTransitionRule rule = readRegistryRule(baseKey, L"TZI", &ruleOk); - rule.startYear = 1970; + rule.startYear = MIN_YEAR; if (ruleOk) m_tranRules.append(rule); } @@ -510,20 +527,25 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId) DWORD firstYear = 0; DWORD lastYear = 0; DYNAMIC_TIME_ZONE_INFORMATION dtzi = dynamicInfoForId(m_windowsId); - GetDynamicTimeZoneInformationEffectiveYears(&dtzi, &firstYear, &lastYear); - // If there is no dynamic information, you can still query for - // year 0, which helps simplifying following part - for (DWORD year = firstYear; year <= lastYear; ++year) { - TIME_ZONE_INFORMATION tzi; - if (!GetTimeZoneInformationForYear(year, &dtzi, &tzi)) - continue; - QWinTransitionRule rule; - rule.standardTimeBias = tzi.Bias + tzi.StandardBias; - rule.daylightTimeBias = tzi.Bias + tzi.DaylightBias - rule.standardTimeBias; - rule.standardTimeRule = tzi.StandardDate; - rule.daylightTimeRule = tzi.DaylightDate; - rule.startYear = year; - m_tranRules.append(rule); + if (GetDynamicTimeZoneInformationEffectiveYears(&dtzi, &firstYear, &lastYear) + == ERROR_SUCCESS && firstYear < lastYear) { + for (DWORD year = firstYear; year <= lastYear; ++year) { + bool ok = false; + QWinTransitionRule rule = readDynamicRule(dtzi, year, &ok); + if (ok) { + rule.startYear = m_tranRules.isEmpty() ? MIN_YEAR : year; + m_tranRules.append(rule); + } + } + } else { + // At least try to get the non-dynamic data: + dtzi.DynamicDaylightTimeDisabled = false; + bool ok = false; + QWinTransitionRule rule = readDynamicRule(dtzi, 1970, &ok); + if (ok) { + rule.startYear = MIN_YEAR; + m_tranRules.append(rule); + } } } #endif // QT_USE_REGISTRY_TIMEZONE -- cgit v1.2.3