Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions stl/src/tzdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ namespace {
_STD atomic<decltype(&::ucal_getTimeZoneDisplayName)> _Pfn_ucal_getTimeZoneDisplayName{nullptr};
_STD atomic<decltype(&::ucal_getTimeZoneTransitionDate)> _Pfn_ucal_getTimeZoneTransitionDate{nullptr};
_STD atomic<decltype(&::ucal_getTZDataVersion)> _Pfn_ucal_getTZDataVersion{nullptr};
_STD atomic<decltype(&::ucal_inDaylightTime)> _Pfn_ucal_inDaylightTime{nullptr};
_STD atomic<decltype(&::ucal_open)> _Pfn_ucal_open{nullptr};
_STD atomic<decltype(&::ucal_openTimeZoneIDEnumeration)> _Pfn_ucal_openTimeZoneIDEnumeration{nullptr};
_STD atomic<decltype(&::ucal_setMillis)> _Pfn_ucal_setMillis{nullptr};
Expand Down Expand Up @@ -78,7 +77,6 @@ namespace {
_Load_address(_Icu_module, _Icu_functions._Pfn_ucal_getTimeZoneTransitionDate,
"ucal_getTimeZoneTransitionDate", _Last_error);
_Load_address(_Icu_module, _Icu_functions._Pfn_ucal_getTZDataVersion, "ucal_getTZDataVersion", _Last_error);
_Load_address(_Icu_module, _Icu_functions._Pfn_ucal_inDaylightTime, "ucal_inDaylightTime", _Last_error);
_Load_address(_Icu_module, _Icu_functions._Pfn_ucal_open, "ucal_open", _Last_error);
_Load_address(_Icu_module, _Icu_functions._Pfn_ucal_openTimeZoneIDEnumeration,
"ucal_openTimeZoneIDEnumeration", _Last_error);
Expand Down Expand Up @@ -146,11 +144,6 @@ namespace {
return _Fun(status);
}

[[nodiscard]] UBool __icu_ucal_inDaylightTime(const UCalendar* cal, UErrorCode* status) noexcept {
const auto _Fun = _Icu_functions._Pfn_ucal_inDaylightTime.load(_STD memory_order_relaxed);
return _Fun(cal, status);
}

[[nodiscard]] UCalendar* __icu_ucal_open(
const UChar* zoneID, int32_t len, const char* locale, UCalendarType type, UErrorCode* status) noexcept {
const auto _Fun = _Icu_functions._Pfn_ucal_open.load(_STD memory_order_relaxed);
Expand Down Expand Up @@ -519,12 +512,7 @@ void __stdcall __std_tzdb_delete_current_zone(__std_tzdb_current_zone_info* cons
return _Report_error(_Info, __std_tzdb_error::_Icu_error);
}

const auto _Is_daylight = __icu_ucal_inDaylightTime(_Cal.get(), &_UErr);
if (U_FAILURE(_UErr)) {
return _Report_error(_Info, __std_tzdb_error::_Icu_error);
}

_Info->_Save = _Is_daylight ? __icu_ucal_get(_Cal.get(), UCalendarDateFields::UCAL_DST_OFFSET, &_UErr) : 0;
_Info->_Save = __icu_ucal_get(_Cal.get(), UCalendarDateFields::UCAL_DST_OFFSET, &_UErr);
if (U_FAILURE(_UErr)) {
return _Report_error(_Info, __std_tzdb_error::_Icu_error);
}
Expand Down Expand Up @@ -560,7 +548,7 @@ void __stdcall __std_tzdb_delete_current_zone(__std_tzdb_current_zone_info* cons
}

int32_t _Abbrev_len{};
const auto _Abbrev = _Get_timezone_short_id(_Cal.get(), _Is_daylight, _Abbrev_len, _Info->_Err);
const auto _Abbrev = _Get_timezone_short_id(_Cal.get(), _Info->_Save != 0, _Abbrev_len, _Info->_Err);
if (_Abbrev == nullptr) {
return _Propagate_error(_Info);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,31 @@ void timezone_sorted_vectors_test() {
assert(ranges::is_sorted(my_tzdb.leap_seconds));
}

void timezone_historical_dst_abolished_test() {
// Regression test: timezones that abolished DST must still report
// correct historical offsets for dates when DST was active.
const auto& my_tzdb = get_tzdb();

{ // America/Sao_Paulo - abolished DST Feb 2019
auto tz = my_tzdb.locate_zone("America/Sao_Paulo");
auto info = tz->get_info(sys_days{year{2019} / January / day{1}});
assert(info.offset == seconds{-7200});
assert(info.save == minutes{60});
}
{ // Europe/Istanbul - abolished DST Sep 2016
auto tz = my_tzdb.locate_zone("Europe/Istanbul");
auto info = tz->get_info(sys_days{year{2016} / July / day{1}});
assert(info.offset == seconds{10800});
assert(info.save == minutes{60});
}
{ // Europe/Moscow - abolished DST Oct 2014
auto tz = my_tzdb.locate_zone("Europe/Moscow");
auto info = tz->get_info(sys_days{year{2010} / July / day{1}});
assert(info.offset == seconds{14400});
assert(info.save == minutes{60});
}
}

void test() {
timezone_tzdb_list_test();
timezone_version_test();
Expand All @@ -411,6 +436,7 @@ void test() {
timezone_local_info_test();
timezone_precision_test();
timezone_sorted_vectors_test();
timezone_historical_dst_abolished_test();
}

int main() {
Expand Down