From f5c81f71aed3eb3e90aa78a2321fff993f120a61 Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Thu, 9 Jan 2025 14:02:31 +0100 Subject: [PATCH] Attempt to extrapolate the earliest piece of historical data Fixes #440 --- core/windows/src/internal/TzdbInRegistry.kt | 7 +++++-- .../windows/test/TimeZoneRulesCompleteTest.kt | 21 +++++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/core/windows/src/internal/TzdbInRegistry.kt b/core/windows/src/internal/TzdbInRegistry.kt index f5781da6..7e6f6265 100644 --- a/core/windows/src/internal/TzdbInRegistry.kt +++ b/core/windows/src/internal/TzdbInRegistry.kt @@ -166,8 +166,11 @@ private fun HKEYVar.readHistoricDataFromRegistry( withRegistryKey(tzHKey, "Dynamic DST", { emptyList() }) { dynDstHKey -> val firstEntry = dwordBuffer.readValue(dynDstHKey, "FirstEntry") val lastEntry = dwordBuffer.readValue(dynDstHKey, "LastEntry") - (firstEntry..lastEntry).map { year -> - year to zoneRulesBuffer.readZoneRules(dynDstHKey, year.toString()) + val registryData = (firstEntry..lastEntry).map { year -> + zoneRulesBuffer.readZoneRules(dynDstHKey, year.toString()) + } + (1970..lastEntry).map { year -> + year to registryData[(year - firstEntry).coerceAtLeast(0)] } } diff --git a/core/windows/test/TimeZoneRulesCompleteTest.kt b/core/windows/test/TimeZoneRulesCompleteTest.kt index 038b0ff7..55ccf621 100644 --- a/core/windows/test/TimeZoneRulesCompleteTest.kt +++ b/core/windows/test/TimeZoneRulesCompleteTest.kt @@ -79,8 +79,20 @@ class TimeZoneRulesCompleteTest { } val mismatches = buildList { // check historical data - for (transition in rules.transitionEpochSeconds) { - checkTransition(Instant.fromEpochSeconds(transition)) + if (windowsName == "Central Brazilian Standard Time") { + // This one reports transitions on Jan 1st for years 1970..2003, but the registry contains transitions + // on the first Thursday of January. + // Neither of these is correct: https://en.wikipedia.org/wiki/Daylight_saving_time_in_Brazil + for (transition in rules.transitionEpochSeconds) { + val instant = Instant.fromEpochSeconds(transition) + if (instant.toLocalDateTime(TimeZone.UTC).year >= 2004) { + checkTransition(instant) + } + } + } else { + for (transition in rules.transitionEpochSeconds) { + checkTransition(Instant.fromEpochSeconds(transition)) + } } // check recurring rules if (windowsName !in strangeTimeZones) { @@ -95,7 +107,7 @@ class TimeZoneRulesCompleteTest { val firstTransitionYear = Instant.fromEpochSeconds( rules.transitionEpochSeconds.firstOrNull() ?: 0 // arbitrary time ).toLocalDateTime(TimeZone.UTC).year - val yearsToCheck = ((firstTransitionYear - 15).. Boolean): Instant {