On Thu, Jul 23, 2026 at 1:28 PM Tomasz Kamiński <[email protected]> wrote:
> When _M_get_sys_info seeds a Zone line by looking up the active rule > just before info.begin, the previous code interpreted each rule in > isolation against ri.offset() (the line's standard offset alone), > ignoring the running save accumulated by earlier rules in the same > year. For most zones this gives the right answer because the search > only matters when no rule has fired yet, but for zones whose rule > set has wall-time rules whose effective firing time depends on a > prior rule's save it produces wrong answers. > > Canonical case: Europe/Paris around 1945. France's rules > > R Fr 1945 o - Apr 2 2 2 M > R Fr 1945 o - Sep 16 3 0 - > > both use plain wall time. In Paris's stdoff=1 frame, the September > rule's at_time of 03:00 wall translates to UT Sep 16 02:00 if no > prior save is applied, but to UT Sep 16 00:00 once the running save > of 2h from the April rule is taken into account. When seeding a > sys_info whose info.begin falls between those two values, the simple > search picks the April rule (save=2 → CEMT, total offset 3h) when > the correct answer is the September rule (save=0 → CET, total offset > 1h). libstdc++ reports this as a sustained CEMT stretch where zic > and libc agree on CET. > > To address above we now consider rules triggering at info.begin (not > only before), and the find algorithm is expanded to collect three > rule transitions around specified time t, while continuing to ignore > the save: > * curr_tran: transition happening before or at time t, > * prev_tran: transition preceding above transition, > * next_tran: transition happening after time t. > > This collects sufficient information to adjust the start_time (if > Wall time is used) for curr_tran (save of prev_tran) and next_tran > (save of curr_tran). Assuming that applying save value does not > change order of transition (cascading save would be ill-defined > otherwise), after the adjustment the actual active rule is: > * next_tran.rule: if the adjustment pushed next_tran.when to > time before or at t, which happen for positive save (see > test_positive), > * prev_tran.rule: if adjustment pushed curr_tran.when to time > after time t, which happens for negative save (see test_negative), > * curr_tran.rule. > > For the time at the start (Jan/1) or end of the year (December/31), > for each rule, in addition to transition in year of t, we check > transitions in previous or next year respectively (years in range > [first_year, last_year]). This handle rules whose firing (specified > in local time) crosses a year boundary due to a large stdoff or save. > One example is Pacific/Auckland's 1946 Jan 1 rule, in stdoff=12h, > fires at 1945-12-31 11:30 UT, see test_next_year. > > The fallback "earliest STD rule" logic is preserved for the case > where no rule has fired yet, but is extracted to separate function. > This lookup is optimized, by searching the rules by name, from, and > save in that order, grouping std rules in given year together. > > PR libstdc++/124853 > > libstdc++-v3/ChangeLog: > > * src/c++20/tzdb.cc > (time_zone::_M_get_sys_info): Extract code blocks to > separate functions, and invoke them. > (<unnamed>::find_active_rule): Modify algorithm to > handle cascading saves. > (<unnamed>::find_first_std): Simplified implementation > benefiting from reordering of rules. > (chrono::reload_tzdb): Sort rules by name, from and save. > * testsuite/std/time/time_zone/wall_cascade.cc: New test. > > Reviewed-by: Tomasz Kamiński <[email protected]> > Co-authored-by: Álvaro Begué <[email protected]> > Signed-off-by: Tomasz Kamiński <[email protected]> > Signed-off-by: Álvaro Begué <[email protected]> > > (cherry picked from commits > f7cde200320e0800e4fcc5cea399e9faef50f8d4) > (610134a51fa3d0bcd3e0980c6574557172dc88c0) > --- > This squashes "- seconds(1)" from the follow up (r17-2462-g610134a51fa3d0), > and I have modified the first sentece of paragraph of commit description > that starts with: > To address above we now consider rules triggering at info.begin... > > As mentioned in the follow up patch, this is now pure improvment in > consistency with date library and reduces number of differences to > 271 from 422 (after parsing/stop condition patches) and 635 (16.1) > respectively. > > I have also tried to measure the performance impact on this change, > but the difference is affecting only first query. So I have tried > to measure the time it takes to iterate each Zone by sys_info > (query end next) from year -5000 to 2000. This is not perfect > as we expand follow up zones, but the best think I could come up > with. The percante difference between state before/this patch > as follows (PXX% is XX percentile): > MIN MED P90% P95% P99% MAX AVG > -60,56% 0.55% 46.42% 56.35% 80.4%% 175.46% 0.43% > I have attached the csv file that lists the results collected for all zones. > > It's hard to make anything from this numbers, and we cannot really > do repeated measurments. The Avarate is certainly acceptable, and > that does not affect any following calls. > > (I believe the reduction come from the fact that finding first DST > rule is now much quicker). > > As the original patch is on trunk since Jun 30, and the follow up > is really small change, I think given above this is fine to backport. > > Tested on x86_64-linux locally and powerpc64le. OK for GCC-16? > > libstdc++-v3/src/c++20/tzdb.cc | 209 ++++++++++---- > .../std/time/time_zone/wall_cascade.cc | 273 ++++++++++++++++++ > 2 files changed, 425 insertions(+), 57 deletions(-) > create mode 100644 > libstdc++-v3/testsuite/std/time/time_zone/wall_cascade.cc > > diff --git a/libstdc++-v3/src/c++20/tzdb.cc > b/libstdc++-v3/src/c++20/tzdb.cc > index a1148355303..6af5768a58e 100644 > --- a/libstdc++-v3/src/c++20/tzdb.cc > +++ b/libstdc++-v3/src/c++20/tzdb.cc > @@ -689,6 +689,147 @@ namespace std::chrono > } > #endif > }; > + > + const Rule* > + find_active_rule(span<const Rule> rules, sys_seconds t, seconds > std_offset) > + { > + struct Transition { > + const Rule* rule; > + sys_seconds when; > + }; > + > + const year_month_day date(chrono::floor<days>(t)); > + // Expand the search window for a time near the end > + // of the year which can be pushed to next/previous > + // year by 'offset'. This assumes that 'offset' is > + // never greater than 24h. > + year first_year = date.year(), last_year = date.year(); > + if (std_offset.count() > 0) > + if (date.month() == December && date.day() == day(31)) > + ++last_year; > + if (std_offset.count() < 0) > + if (date.month() == January && date.day() == day(1)) > + --first_year; > + > + // Rule specifying start time as Wall time, should apply > + // running 'save' accumulated by earlier rules. To handle > + // that we firstly collect transitions surrounding specified > + // time t, ignoring the 'save': > + // * curr_tran - rule active directly before or at t, > + // * prev_tran - rule transition before curr_tran > + // * next_tran - rule transition directly after t > + Transition prev_tran{nullptr, sys_seconds::min()}; > + Transition curr_tran{nullptr, sys_seconds::min()}; > + Transition next_tran{nullptr, sys_seconds::max()}; > + for (const auto& rule : rules) > + { > + if (last_year < rule.from) // Rule doesn't apply yet at time t. > + break; // Rules are ordered by 'from' in ascending order. > + > + seconds offset{}; // appropriate for at_time::Universal > + if (rule.when.indicator == at_time::Wall > + || rule.when.indicator == at_time::Standard) > + offset = std_offset; > + > + // Times at which rule takes affect before (or equal) t, > + // and after t, respectively. > + sys_seconds start_before = sys_seconds::min(); > + sys_seconds start_after = sys_seconds::max(); > + auto for_year = [&](year y) > + { > + // Time the rule takes effect on year y: > + const sys_seconds rule_start = rule.start_time(y, offset); > + if (rule_start <= t) > + { > + start_before = rule_start; > + if (y == last_year && rule.to > y) > + start_after = rule.start_time(++y, offset); > + } > + // Do not override start_after set for first_year > + else if (rule_start < start_after) > + { > + start_after = rule_start; > + if (y == first_year && rule.from < y) > + start_before = rule.start_time(--y, offset); > + } > + }; > + > + if (first_year > rule.to) > + // Rule no longer applies at time t, record last transition > + start_before = rule.start_time(rule.to, offset); > + else if (first_year == last_year) > + for_year(first_year); > + else > + { > + // Local time may of t may be in prev/next year. > + if (first_year >= rule.from) > + for_year(first_year); > + if (last_year <= rule.to) > + for_year(last_year); > + } > + > + if (curr_tran.when < start_before) > + { > + prev_tran = curr_tran; > + curr_tran = {&rule, start_before}; > + } > + else if (prev_tran.when < start_before) > + prev_tran = {&rule, start_before}; > + > + if (start_after < next_tran.when) > + next_tran = {&rule, start_after}; > + } > + > + // No rule was active at the time of t, running 'save' > + // cannot change this output, as we have no save to apply. > + if (!curr_tran.rule) > + return nullptr; > + > + auto cascade_save = [](const Rule* from, Transition& to) > + { > + if (!from || from->save == seconds(0)) > + return false; > + if (!to.rule || to.rule->when.indicator != at_time::Wall) > + return false; > + to.when -= from->save; > + return true; > + }; > + > + if (cascade_save(curr_tran.rule, next_tran)) > + // Running save moved what we considered next_tran to time > + // before or at t, in that case next_tran is active rule. > + if (next_tran.when <= t) > + return next_tran.rule; > + > + if (cascade_save(prev_tran.rule, curr_tran)) > + // Running save moved what we consider curr_tran to > + // time after t, in that case prev_tran is active rule. > + if (curr_tran.when > t) > + return prev_tran.rule; > + > + return curr_tran.rule; > + } > + > + const Rule* > + find_first_std(span<const Rule> rules) > + { > + auto is_std = [](const Rule& rule) { return !rule.save.count(); }; > + // Rules with same name are sorted by 'from' and then 'save' in > ascending order. > + auto it = ranges::find_if(rules, is_std); > + if (it == rules.end()) > + return nullptr; > + > + const Rule* first = &*it; > + const year y = first->from; > + for (const Rule& next : span<const Rule>(++it, rules.end())) > + { > + if (!is_std(next) || next.from > y) > + break; > + if (next.start_time(y, {}) < first->start_time(y, {})) > + first = &next; > + } > + return first; > + } > } // namespace > #endif // TZDB_DISABLED > > @@ -877,70 +1018,17 @@ namespace std::chrono > > if (letters.empty()) > { > - sys_seconds t = info.begin - seconds(1); > - const year_month_day date(chrono::floor<days>(t)); > - > // Try to find a Rule active before this time, to get initial > // SAVE and LETTERS values. There may not be a Rule for the period > // before the first DST transition, so find the earliest DST->STD > // transition and use the LETTERS from that. > - const Rule* active_rule = nullptr; > - sys_seconds active_rule_start = sys_seconds::min(); > - const Rule* first_std = nullptr; > - for (const auto& rule : rules) > - { > - if (rule.save == minutes(0)) > - { > - if (!first_std) > - first_std = &rule; > - else if (rule.from < first_std->from) > - first_std = &rule; > - else if (rule.from == first_std->from) > - { > - if (rule.start_time(rule.from, {}) > - < first_std->start_time(first_std->from, {})) > - first_std = &rule; > - } > - } > - > - year y = date.year(); > - > - if (y > rule.to) // rule no longer applies at time t > - continue; > - if (y < rule.from) // rule doesn't apply yet at time t > - continue; > - > - sys_seconds rule_start; > - > - seconds offset{}; // appropriate for at_time::Universal > - if (rule.when.indicator == at_time::Wall) > - offset = info.offset; > - else if (rule.when.indicator == at_time::Standard) > - offset = ri.offset(); > - > - // Time the rule takes effect this year: > - rule_start = rule.start_time(y, offset); > - > - if (rule_start >= t && rule.from < y) > - { > - // Try this rule in the previous year. > - rule_start = rule.start_time(--y, offset); > - } > - > - if (active_rule_start < rule_start && rule_start < t) > - { > - active_rule_start = rule_start; > - active_rule = &rule; > - } > - } > - > - if (active_rule) > + if (const Rule* active_rule = find_active_rule(rules, info.begin, > ri.offset())) > { > info.offset = ri.offset() + active_rule->save; > info.save = chrono::duration_cast<minutes>(active_rule->save); > letters = active_rule->letters; > } > - else if (first_std) > + else if (const Rule* first_std = find_first_std(rules)) > letters = first_std->letters; > } > > @@ -1828,7 +1916,14 @@ constinit tzdb_list::_Node::NumLeapSeconds > tzdb_list::_Node::num_leap_seconds; > > ranges::sort(node->db.zones, {}, &time_zone::name); > ranges::sort(node->db.links, {}, &time_zone_link::name); > - ranges::stable_sort(node->rules, {}, &Rule::name); > + ranges::sort(node->rules, [](const Rule& lhs, const Rule& rhs) > + { > + if (auto result = lhs.name <=> rhs.name; result != 0) > + return result < 0; > + if (auto result = lhs.from <=> rhs.from; result != 0) > + return result < 0; > + return lhs.save < rhs.save; > + }); > > return Node::_S_replace_head(std::move(head), std::move(node)); > #else > @@ -2441,7 +2536,7 @@ constinit tzdb_list::_Node::NumLeapSeconds > tzdb_list::_Node::num_leap_seconds; > { > if (c = in.get(); c == '<' || c == '>') > if (in.get() == '=') > - if (unsigned d; (in >> d) && (d <= 31)) [[likely]] > + if (unsigned d; (in >> d) && (d <= 31)) [[likely]] > { > on.kind = c == '<' ? LessEq : GreaterEq; > on.day_of_week = w.wd.c_encoding(); > diff --git a/libstdc++-v3/testsuite/std/time/time_zone/wall_cascade.cc > b/libstdc++-v3/testsuite/std/time/time_zone/wall_cascade.cc > new file mode 100644 > index 00000000000..3529c2de852 > --- /dev/null > +++ b/libstdc++-v3/testsuite/std/time/time_zone/wall_cascade.cc > @@ -0,0 +1,273 @@ > +// { dg-do run { target c++20 } } > +// { dg-require-effective-target tzdb } > +// { dg-require-effective-target cxx11_abi } > +// { dg-xfail-run-if "no weak override on AIX" { powerpc-ibm-aix* } } > + > +// Wall-time rules in the same rule set whose effective firing time > +// depends on a prior rule's save (Europe/Paris 1945): > +// 1945 Apr 2 02:00 wall save=2 M > +// 1945 Sep 16 03:00 wall save=0 - > +// In the (stdoff=1, save=2) frame the September rule fires at > +// Sep 16 00:00 UT, not Sep 16 02:00 UT. > + > +#include <chrono> > +#include <fstream> > +#include <testsuite_hooks.h> > + > +static bool override_used = false; > + > +namespace __gnu_cxx > +{ > + const char* zoneinfo_dir_override() { > + override_used = true; > + return "./"; > + } > +} > + > +using namespace std::chrono; > + > +void > +test_positive() > +{ > + // Line 1 ends at "1945 Sep 16 1u" (Universal time, no save > shenanigans), > + // so info.begin for line 2 is exactly 1945-09-16 01:00 UT. > + // > + // Two-line zone whose second line begins at 1945 Sep 16 01:00 UT, > + // between the cascaded firing time (Sep 16 00:00 UT) and the > + // non-cascaded firing time (Sep 16 02:00 UT) of the September rule. > + // The seeding must pick the September rule (save=0, CET) at info.begin. > + std::ofstream("tzdata.zi") << R"(# version test_wall_cascade > +R Fr 1945 o - Apr 2 2 2 M > +R Fr 1945 o - Sep 16 3 0 - > +Z Test/Paris 0 - X 1945 Sep 16 1u > + 1 Fr CE%sT > +)"; > + > + const auto& db = reload_tzdb(); > + VERIFY( override_used ); // If this fails then XFAIL for the target. > + VERIFY( db.version == "test_wall_cascade" ); > + > + auto* tz = locate_zone("Test/Paris"); > + > + // Line 2 begins at exactly 1945-09-16 01:00 UT. Sample one second > + // after the boundary, well inside line 2's first sys_info. > + auto info = tz->get_info(sys_seconds{ > + sys_days(1945y/September/16) + 1h + 1s}); > + VERIFY( info.offset == 1h ); > + VERIFY( info.save == 0min ); > + VERIFY( info.abbrev == "CET" ); > + > + // The boundary instant itself is in the new line. > + auto at_boundary > + = tz->get_info(sys_seconds{sys_days(1945y/September/16) + 1h}); > + VERIFY( at_boundary.offset == 1h ); > + VERIFY( at_boundary.save == 0min ); > + > + // Sample later still in line 2 (winter): unchanged. > + auto winter = tz->get_info(sys_days(1945y/December/1)); > + VERIFY( winter.offset == 1h ); > + VERIFY( winter.save == 0min ); > +} > + > +void > +test_negative() > +{ > + // This is synthetic version of above example, with negative > + // running save. > + // > + // Two-line zone whose second line begins at 1945 Sep 16 01:00 UT, > + // before the cascaded firing time (Sep 16 02:00 UT), but after > + // non-cascaded firing time (Sep 16 00:00 UT) of the September rule. > + // The seeding must pick the April rule (save=-2, CEST) at info.begin. > + std::ofstream("tzdata.zi") << R"(# version test_negative_cascade > +R Fr 1945 o - Apr 2 2 -3 M > +R Fr 1945 o - Sep 16 0 0 - > +Z Test/Negative 0 - X 1945 Sep 16 1u > + 1 Fr CE%sT > +)"; > + > + const auto& db = reload_tzdb(); > + VERIFY( override_used ); // If this fails then XFAIL for the target. > + VERIFY( db.version == "test_negative_cascade" ); > + > + auto* tz = locate_zone("Test/Negative"); > + > + // Line 2 begins at exactly 1945-09-16 01:00 UT, sample > + // one second after. > + auto info = tz->get_info(sys_seconds{ > + sys_days(1945y/September/16) + 1h + 1s}); > + VERIFY( info.offset == -2h ); > + VERIFY( info.save == -3h ); > + VERIFY( info.abbrev == "CEMT" ); > + > + // The boundary instant. > + auto at_boundary > + = tz->get_info(sys_seconds{sys_days(1945y/September/16) + 1h}); > + VERIFY( at_boundary.offset == -2h ); > + VERIFY( at_boundary.save == -3h ); > + > + // Test the firing of Sep 16 rule > + auto at_sep_rule = tz->get_info(sys_seconds{ > + sys_days(1945y/September/16) + 2h}); > + // The transition_window < 1d condition triggers, and > + // transition is ignored. > + // VERIFY( at_sep_rule.offset == 1h ); > + // VERIFY( at_sep_rule.save == 0h ); > + // VERIFY( at_sep_rule.abbrev == "CET" ); > +} > + > +void > +test_next_year() > +{ > + // The NZ 1946 rule triggers at 1946 Jan 1 00:00:00 > + // local time, which correspond to 1946 Dec 13 12:00:00 UT. > + std::ofstream("tzdata.zi") << R"(# version test_next_year > +R NZ 1934 1940 - Ap lastSu 2 0 M > +R NZ 1934 1940 - S lastSu 2 0:30 S > +R NZ 1946 o - Ja 1 0 0 S > +Z Pacific/Auckland 11:39:4 - LMT 1868 N 2 > +11:30 NZ NZ%sT 1946 > +12 NZ NZ%sT > +Z Pacific/AucklandUT 11:39:4 - LMT 1868 N 2 > +11:30 NZ NZ%sT 1945 Dec 31 13u > +12 NZ NZ%sT > +)"; > + > + const auto& db = reload_tzdb(); > + VERIFY( override_used ); // If this fails then XFAIL for the target. > + VERIFY( db.version == "test_next_year" ); > + > + // Pacific/Auckland requires both PR124854 and PR116110 to work > + // correctly. TODO test it once implemented. > + // The UT version uses 1945-12-31 13:00:00 UT after > + // the rule application change. > + auto* utz = locate_zone("Pacific/AucklandUT"); > + > + // Before the change > + auto before_utboundary > + = utz->get_info(sys_seconds{sys_days(1945y/December/31) + 11h}); > + VERIFY( before_utboundary.offset == 12h ); > + VERIFY( before_utboundary.save == 30min ); > + VERIFY( before_utboundary.abbrev == "NZST" ); > + > + auto at_utboundary > + = utz->get_info(sys_seconds{sys_days(1945y/December/31) + 13h}); > + VERIFY( at_utboundary.offset == 12h ); > + VERIFY( at_utboundary.save == 0h ); > + VERIFY( at_utboundary.abbrev == "NZST" ); > + > + auto after_utboundary > + = utz->get_info(sys_seconds{sys_days(1945y/December/31) + 14h}); > + VERIFY( after_utboundary.offset == 12h ); > + VERIFY( after_utboundary.save == 0h ); > + VERIFY( after_utboundary.abbrev == "NZST" ); > +} > + > +void > +test_prev_year() > +{ > + // The synthetic version of above, where the local > + // time for rule is moved to previous year. > + // The NZ 1946 rule triggers at 1946 Dec 31 22:00:00 > + // local time, which correspond to 1947 Jan 1 10:00:00 UT. > + std::ofstream("tzdata.zi") << R"(# version test_prev_year > +R PY 1934 1940 - Ap lastSu 2 0 M > +R PY 1934 1940 - S lastSu 2 0:30 S > +R PY 1946 o - D 31 22 0 S > +Z Test/PrevYear -11:39:4 - LMT 1868 N 2 > +-12:30 PY PY%sT 1947 Jan 1 11u > +-12 PY PY%sT > +)"; > + > + const auto& db = reload_tzdb(); > + VERIFY( override_used ); // If this fails then XFAIL for the target. > + VERIFY( db.version == "test_prev_year" ); > + > + // The UT version uses 1945-12-31 13:00:00 UT after > + // the rule application change. > + auto* tz = locate_zone("Test/PrevYear"); > + > + // Before the change > + auto before_boundary > + = tz->get_info(sys_seconds{sys_days(1947y/January/1) + 9h}); > + VERIFY( before_boundary.offset == -12h ); > + VERIFY( before_boundary.save == 30min ); > + VERIFY( before_boundary.abbrev == "PYST" ); > + > + auto at_boundary > + = tz->get_info(sys_seconds{sys_days(1947y/January/1) + 11h}); > + VERIFY( at_boundary.offset == -12h ); > + VERIFY( at_boundary.save == 0h ); > + VERIFY( at_boundary.abbrev == "PYST" ); > + > + auto after_boundary > + = tz->get_info(sys_seconds{sys_days(1947y/January/1) + 12h}); > + VERIFY( after_boundary.offset == -12h ); > + VERIFY( after_boundary.save == 0h ); > + VERIFY( after_boundary.abbrev == "PYST" ); > +} > + > +void > +test_earlier_year() > +{ > + // Synthetic example where PY 1941 rule is still running. > + std::ofstream("tzdata.zi") << R"(# version test_earlier_year > +R EY 1934 1941 - Ap lastSu 2 0 M > +R EY 1934 1940 - S lastSu 2 0:30 S > +Z Test/EarielYear 11:39:4 - LMT 1868 N 2 > +11:30 EY EY%sT 1943 Jan 1 12u > +12 EY EY%sT > + )"; > + > + const auto& db = reload_tzdb(); > + VERIFY( override_used ); // If this fails then XFAIL for the target. > + VERIFY( db.version == "test_earlier_year" ); > + > + auto* utz = locate_zone("Test/EarielYear"); > + auto at_boundary > + = utz->get_info(sys_seconds{sys_days(1943y/January/1) + 12h}); > + VERIFY( at_boundary.offset == 12h ); > + VERIFY( at_boundary.save == 0min ); > + VERIFY( at_boundary.abbrev == "EYMT" ); > +} > + > +void > +test_at_boundary() > +{ > + std::ofstream("tzdata.zi") << R"(# version test_at_boundary > +R p 1947 1966 - Ap Su>=1 2s 1 S > +R p 1947 1965 - O Su>=1 2s 0 - > +R p 1976 o - S lastSu 1 0 - > +R p 1977 o - Mar lastSu 0s 1 S > +R p 1977 o - S lastSu 0s 0 - > +Z Europe/Lisbon -0:36:45 - LMT 1884 > +1 - CET 1976 S 26 1 > +0 p WE%sT 1986 > + )"; > + > + const auto& db = reload_tzdb(); > + VERIFY( override_used ); // If this fails then XFAIL for the target. > + VERIFY( db.version == "test_at_boundary" ); > + > + // The change from CET to WE%sT line happens 1976 Sep 26 00:00:00 UT, > + // should take into consideration 1976 lastSu rule that fires at the > + // same time (running save is 1h from 1966 Ap rule application), > + // and start in standard time (WET period). > + auto* utz = locate_zone("Europe/Lisbon"); > + auto at_boundary > + = utz->get_info(sys_seconds{sys_days(1976y/September/26) + 0h}); > + VERIFY( at_boundary.offset == 0h ); > + VERIFY( at_boundary.save == 0min ); > + VERIFY( at_boundary.abbrev == "WET" ); > +} > + > +int > +main() > +{ > + test_positive(); > + test_negative(); > + test_next_year(); > + test_prev_year(); > + test_earlier_year(); > + test_at_boundary(); > +} > -- > 2.55.0 > >
AVG 21121 21020 -101 0.43% MIN 610 629 -45836 -60.56% MEDIAN 16909 18205 23 0.55% P90% 49874 48489 7018 46.42% P95% 64902 57982 12983 56.35% P99% 86505 97889 26668 80.48% MAX 131650 133930 39195 175.46% Africa/Abidjan 2545 1265 -1280 -50.29% Africa/Accra 1322 1304 -18 -1.36% Africa/Addis_Ababa 3398 2283 -1115 -32.81% Africa/Algiers 14702 15182 480 3.26% Africa/Asmara 3112 1421 -1691 -54.34% Africa/Asmera 2530 2098 -432 -17.08% Africa/Bamako 1240 1260 20 1.61% Africa/Bangui 1717 1778 61 3.55% Africa/Banjul 1298 1316 18 1.39% Africa/Bissau 1231 925 -306 -24.86% Africa/Blantyre 1265 1355 90 7.11% Africa/Brazzaville 1541 1940 399 25.89% Africa/Bujumbura 1202 1320 118 9.82% Africa/Cairo 67264 68101 837 1.24% Africa/Casablanca 67714 68462 748 1.10% Africa/Ceuta 24477 26193 1716 7.01% Africa/Conakry 1283 1291 8 0.62% Africa/Dakar 1306 1332 26 1.99% Africa/Dar_es_Salaam 2467 2039 -428 -17.35% Africa/Djibouti 2513 2072 -441 -17.55% Africa/Douala 1651 1196 -455 -27.56% Africa/El_Aaiun 58339 56374 -1965 -3.37% Africa/Freetown 818 898 80 9.78% Africa/Gaborone 1307 790 -517 -39.56% Africa/Harare 844 1268 424 50.24% Africa/Johannesburg 5027 5225 198 3.94% Africa/Juba 9658 9614 -44 -0.46% Africa/Kampala 1818 1290 -528 -29.04% Africa/Khartoum 12731 13659 928 7.29% Africa/Kigali 1355 1265 -90 -6.64% Africa/Kihasa 1616 1858 242 14.98% Africa/Lagos 2310 1530 -780 -33.77% Africa/Libreville 1701 1339 -362 -21.28% Africa/Lome 768 788 20 2.60% Africa/Luanda 1499 1922 423 28.22% Africa/Lubumbashi 1243 1282 39 3.14% Africa/Lusaka 881 1209 328 37.23% Africa/Malabo 2281 1305 -976 -42.79% Africa/Maputo 864 775 -89 -10.30% Africa/Maseru 4156 3562 -594 -14.29% Africa/Mbabane 3058 5096 2038 66.64% Africa/Mogadishu 1538 2147 609 39.60% Africa/Monrovia 939 1543 604 64.32% Africa/Nairobi 2623 1442 -1181 -45.02% Africa/Ndjamena 1008 1070 62 6.15% Africa/Niamey 1729 1286 -443 -25.62% Africa/Nouakchott 748 1290 542 72.46% Africa/Ouagadougou 783 845 62 7.92% Africa/Porto-Novo 1521 1867 346 22.75% Africa/Sao_Tome 1203 1200 -3 -0.25% Africa/Timbuktu 758 920 162 21.37% Africa/Tripoli 12741 12328 -413 -3.24% Africa/Tunis 11779 13268 1489 12.64% Africa/Windhoek 16876 16429 -447 -2.65% America/Adak 27649 55904 28255 102.19% America/Anchorage 41269 31601 -9668 -23.43% America/Anguilla 4030 3947 -83 -2.06% America/Antigua 5862 3582 -2280 -38.89% America/Araguaina 29107 41188 12081 41.51% America/Argentina/Buenos_Aires 33499 32790 -709 -2.12% America/Argentina/Catamarca 23064 22014 -1050 -4.55% America/Argentina/ComodRivadavia 34442 23618 -10824 -31.43% America/Argentina/Cordoba 24963 23353 -1610 -6.45% America/Argentina/Jujuy 21415 34129 12714 59.37% America/Argentina/La_Rioja 34126 22514 -11612 -34.03% America/Argentina/Mendoza 34361 33099 -1262 -3.67% America/Argentina/Rio_Gallegos 21073 20671 -402 -1.91% America/Argentina/Salta 34200 22960 -11240 -32.87% America/Argentina/San_Juan 23428 23328 -100 -0.43% America/Argentina/San_Luis 21521 22697 1176 5.46% America/Argentina/Tucuman 38701 22761 -15940 -41.19% America/Argentina/Ushuaia 33630 33902 272 0.81% America/Aruba 4032 3590 -442 -10.96% America/Asuncion 48003 32999 -15004 -31.26% America/Atikokan 905 990 85 9.39% America/Atka 28019 43865 15846 56.55% America/Bahia 47969 29484 -18485 -38.54% America/Bahia_Banderas 21173 21640 467 2.21% America/Barbados 8937 8942 5 0.06% America/Belem 27784 26729 -1055 -3.80% America/Belize 22853 22084 -769 -3.36% America/Blanc-Sablon 3709 5433 1724 46.48% America/Boa_Vista 31472 19190 -12282 -39.03% America/Bogota 4775 2987 -1788 -37.45% America/Boise 30272 43806 13534 44.71% America/Buenos_Aires 21109 33415 12306 58.30% America/Cambridge_Bay 27521 26787 -734 -2.67% America/Campo_Grande 38235 54401 16166 42.28% America/Cancun 11461 17967 6506 56.77% America/Caracas 2561 1468 -1093 -42.68% America/Catamarca 26294 21989 -4305 -16.37% America/Cayenne 1315 1740 425 32.32% America/Cayman 1032 895 -137 -13.28% America/Chicago 64800 72200 7400 11.42% America/Chihuahua 14585 21385 6800 46.62% America/Ciudad_Juarez 28371 20027 -8344 -29.41% America/Coral_Harbour 842 862 20 2.38% America/Cordoba 22213 34966 12753 57.41% America/Costa_Rica 5823 4893 -930 -15.97% America/Coyhaique 83041 46137 -36904 -44.44% America/Creston 6300 9740 3440 54.60% America/Cuiaba 57754 35942 -21812 -37.77% America/Curacao 3745 3369 -376 -10.04% America/Danmarkshavn 13243 14945 1702 12.85% America/Dawson 23681 22073 -1608 -6.79% America/Dawson_Creek 20894 15684 -5210 -24.94% America/Denver 35283 48096 12813 36.31% America/Detroit 41328 28024 -13304 -32.19% America/Dominica 3704 3538 -166 -4.48% America/Edmonton 26924 41901 14977 55.63% America/Eirunepe 22437 19983 -2454 -10.94% America/El_Salvador 4735 5055 320 6.76% America/Eenada 34213 52955 18742 54.78% America/Fort_Nelson 41025 27569 -13456 -32.80% America/Fort_Wayne 23120 23859 739 3.20% America/Fortaleza 22306 34476 12170 54.56% America/Glace_Bay 28753 28850 97 0.34% America/Godthab 34847 57504 22657 65.02% America/Goose_Bay 44527 70276 25749 57.83% America/Grand_Turk 32492 21526 -10966 -33.75% America/Grenada 3801 3631 -170 -4.47% America/Guadeloupe 4067 5598 1531 37.64% America/Guatemala 6384 4664 -1720 -26.94% America/Guayaquil 3142 5008 1866 59.39% America/Guyana 1550 2025 475 30.65% America/Halifax 79565 53743 -25822 -32.45% America/Havana 46934 43774 -3160 -6.73% America/Hermosillo 6215 9282 3067 49.35% America/Indiana/Indianapolis 22783 23292 509 2.23% America/Indiana/Knox 46788 47565 777 1.66% America/Indiana/Marengo 21877 34091 12214 55.83% America/Indiana/Petersburg 37463 24866 -12597 -33.63% America/Indiana/Tell_City 22706 22142 -564 -2.48% America/Indiana/Vevay 26558 26036 -522 -1.97% America/Indiana/Vincennes 26036 23935 -2101 -8.07% America/Indiana/Winamac 33771 35009 1238 3.67% America/Indianapolis 22266 32692 10426 46.82% America/Inuvik 26748 23734 -3014 -11.27% America/Iqaluit 27008 24885 -2123 -7.86% America/Jamaica 8043 12633 4590 57.07% America/Jujuy 22815 23044 229 1.00% America/Juneau 42622 43069 447 1.05% America/Kentucky/Louisville 33392 52416 19024 56.97% America/Kentucky/Monticello 42648 28836 -13812 -32.39% America/Knox_IN 32505 47560 15055 46.32% America/Kralendijk 3763 5360 1597 42.44% America/La_Paz 2248 1271 -977 -43.46% America/Lima 10057 10218 161 1.60% America/Los_Angeles 33543 38790 5247 15.64% America/Louisville 51381 36286 -15095 -29.38% America/Lower_Princes 3788 5605 1817 47.97% America/Maceio 24356 25793 1437 5.90% America/Managua 7601 8006 405 5.33% America/Manaus 31196 29949 -1247 -4.00% America/Marigot 3620 3601 -19 -0.52% America/Martinique 1667 996 -671 -40.25% America/Matamoros 17971 19833 1862 10.36% America/Mazatlan 15256 14834 -422 -2.77% America/Mendoza 21616 33171 11555 53.46% America/Menominee 40882 41663 781 1.91% America/Merida 12363 13169 806 6.52% America/Metlakatla 31990 18898 -13092 -40.93% America/Mexico_City 16942 24283 7341 43.33% America/Miquelon 22300 22141 -159 -0.71% America/Moncton 40175 60238 20063 49.94% America/Monterrey 21441 21997 556 2.59% America/Montevideo 34877 34750 -127 -0.36% America/Montreal 68036 76110 8074 11.87% America/Montserrat 3862 6966 3104 80.37% America/Nassau 47523 52446 4923 10.36% America/New_York 42805 71337 28532 66.66% America/Nipigon 69110 52224 -16886 -24.43% America/Nome 27386 29562 2176 7.95% America/Noronha 36120 25107 -11013 -30.49% America/North_Dakota/Beulah 29076 43388 14312 49.22% America/North_Dakota/Center 28957 29763 806 2.78% America/North_Dakota/New_Salem 42845 42847 2 0.00% America/Nuuk 34854 27159 -7695 -22.08% America/Ojinaga 19961 21941 1980 9.92% America/Panama 1650 1020 -630 -38.18% America/Pangnirtung 28319 28347 28 0.10% America/Paramaribo 1464 1352 -112 -7.65% America/Phoenix 10157 7204 -2953 -29.07% America/Port-au-Prince 28839 21590 -7249 -25.14% America/Port_of_Spain 3399 3549 150 4.41% America/Porto_Acre 28254 19492 -8762 -31.01% America/Porto_Velho 18484 26871 8387 45.37% America/Puerto_Rico 3887 3946 59 1.52% America/Punta_Arenas 81825 49043 -32782 -40.06% America/Rainy_River 52691 38550 -14141 -26.84% America/Rankin_Inlet 23544 24466 922 3.92% America/Recife 35510 44484 8974 25.27% America/Regina 14702 24117 9415 64.04% America/Resolute 23878 25287 1409 5.90% America/Rio_Branco 27979 18979 -9000 -32.17% America/Rosario 34311 23509 -10802 -31.48% America/Santa_Isabel 33961 35275 1314 3.87% America/Santarem 18443 25841 7398 40.11% America/Santiago 58706 54752 -3954 -6.74% America/Santo_Domingo 6079 6816 737 12.12% America/Sao_Paulo 39871 40523 652 1.64% America/Scoresbysund 35637 35908 271 0.76% America/Shiprock 31315 31430 115 0.37% America/Sitka 29601 43334 13733 46.39% America/St_Barthelemy 4130 5536 1406 34.04% America/St_Joh 53719 64045 10326 19.22% America/St_Kitts 5834 3914 -1920 -32.91% America/St_Lucia 5763 4066 -1697 -29.45% America/St_Thomas 3688 3515 -173 -4.69% America/St_Vincent 3790 5481 1691 44.62% America/Swift_Current 10006 13824 3818 38.16% America/Tegucigalpa 3657 4427 770 21.06% America/Thule 17799 19570 1771 9.95% America/Thunder_Bay 68710 54693 -14017 -20.40% America/Tijuana 34189 37138 2949 8.63% America/Toronto 47915 74555 26640 55.60% America/Tortola 4062 5482 1420 34.96% America/Vancouver 29570 33283 3713 12.56% America/Virgin 5717 3942 -1775 -31.05% America/Whitehorse 30431 29727 -704 -2.31% America/Winnipeg 40283 36492 -3791 -9.41% America/Yakutat 28833 41491 12658 43.90% America/Yellowknife 28898 41229 12331 42.67% Antarctica/Casey 2867 2722 -145 -5.06% Antarctica/Davis 2737 1585 -1152 -42.09% Antarctica/DumontDUrville 1991 1568 -423 -21.25% Antarctica/Macquarie 34736 37957 3221 9.27% Antarctica/Mawson 1438 1633 195 13.56% Antarctica/McMurdo 33622 49654 16032 47.68% Antarctica/Palmer 32296 33871 1575 4.88% Antarctica/Rothera 1164 930 -234 -20.10% Antarctica/South_Pole 49962 48873 -1089 -2.18% Antarctica/Syowa 1229 960 -269 -21.89% Antarctica/Troll 13391 19084 5693 42.51% Antarctica/Vostok 1609 1790 181 11.25% Arctic/Longyearbyen 27771 32056 4285 15.43% Asia/Aden 1950 1122 -828 -42.46% Asia/Almaty 21182 20985 -197 -0.93% Asia/Amman 27020 43542 16522 61.15% Asia/Anadyr 18439 24919 6480 35.14% Asia/Aqtau 14420 39721 25301 175.46% Asia/Aqtobe 13978 16170 2192 15.68% Asia/Ashgabat 8589 12975 4386 51.07% Asia/Ashkhabad 13015 8940 -4075 -31.31% Asia/Atyrau 14461 14599 138 0.95% Asia/Baghdad 15073 14294 -779 -5.17% Asia/Bahrain 1410 1637 227 16.10% Asia/Baku 16972 18411 1439 8.48% Asia/Bangkok 2302 1649 -653 -28.37% Asia/Barnaul 25500 19614 -5886 -23.08% Asia/Beirut 26038 26281 243 0.93% Asia/Bishkek 16418 21854 5436 33.11% Asia/Brunei 6996 8836 1840 26.30% Asia/Calcutta 2027 1524 -503 -24.81% Asia/Chita 29084 24995 -4089 -14.06% Asia/Choibalsan 22264 14481 -7783 -34.96% Asia/Chongqing 8396 8670 274 3.26% Asia/Chungking 11040 13328 2288 20.72% Asia/Colombo 2154 2580 426 19.78% Asia/Dacca 4135 3782 -353 -8.54% Asia/Damascus 63673 56109 -7564 -11.88% Asia/Dhaka 6085 3532 -2553 -41.96% Asia/Dili 1474 1222 -252 -17.10% Asia/Dubai 1326 1435 109 8.22% Asia/Dushanbe 9056 12133 3077 33.98% Asia/Famagusta 25068 28384 3316 13.23% Asia/Gaza 131129 120672 -10457 -7.97% Asia/Harbin 9060 9468 408 4.50% Asia/Hebron 73572 76193 2621 3.56% Asia/Ho_Chi_Minh 2106 2425 319 15.15% Asia/Hong_Kong 18370 19656 1286 7.00% Asia/Hovd 14182 15306 1124 7.93% Asia/Irkutsk 17729 18571 842 4.75% Asia/Istanbul 54526 39687 -14839 -27.21% Asia/Jakarta 2016 1888 -128 -6.35% Asia/Jayapura 1490 1832 342 22.95% Asia/Jerusalem 46093 49461 3368 7.31% Asia/Kabul 1311 1284 -27 -2.06% Asia/Kamchatka 17827 18483 656 3.68% Asia/Karachi 8300 5051 -3249 -39.14% Asia/Kashgar 1189 1003 -186 -15.64% Asia/Kathmandu 1371 1259 -112 -8.17% Asia/Katmandu 1503 1103 -400 -26.61% Asia/Khandyga 18194 20545 2351 12.92% Asia/Kolkata 2658 1608 -1050 -39.50% Asia/Krasnoyarsk 24512 17618 -6894 -28.13% Asia/Kuala_Lumpur 2071 1963 -108 -5.21% Asia/Kuching 7649 8910 1261 16.49% Asia/Kuwait 1260 1142 -118 -9.37% Asia/Macao 22127 25480 3353 15.15% Asia/Macau 35753 24456 -11297 -31.60% Asia/Magadan 24164 17786 -6378 -26.39% Asia/Makassar 1496 1191 -305 -20.39% Asia/Manila 6989 8623 1634 23.38% Asia/Muscat 1245 979 -266 -21.37% Asia/Nicosia 23514 26822 3308 14.07% Asia/Novokuznetsk 16672 17580 908 5.45% Asia/Novosibirsk 25536 18598 -6938 -27.17% Asia/Omsk 16471 17435 964 5.85% Asia/Oral 14309 20608 6299 44.02% Asia/Phnom_Penh 1372 1081 -291 -21.21% Asia/Pontianak 1978 1796 -182 -9.20% Asia/Pyongyang 1076 1760 684 63.57% Asia/Qatar 2102 1009 -1093 -52.00% Asia/Qostanay 13397 14397 1000 7.46% Asia/Qyzylorda 15742 21581 5839 37.09% Asia/Rangoon 1672 1385 -287 -17.17% Asia/Riyadh 1135 1003 -132 -11.63% Asia/Saigon 3018 1770 -1248 -41.35% Asia/Sakhalin 25439 18596 -6843 -26.90% Asia/Samarkand 7881 8358 477 6.05% Asia/Seoul 10777 14875 4098 38.03% Asia/Shanghai 9189 10174 985 10.72% Asia/Singapore 2032 1877 -155 -7.63% Asia/Srednekolymsk 29570 18719 -10851 -36.70% Asia/Taipei 14748 10792 -3956 -26.82% Asia/Tashkent 8514 9076 562 6.60% Asia/Tbilisi 17558 24666 7108 40.48% Asia/Tehran 23450 24134 684 2.92% Asia/Tel_Aviv 43278 49655 6377 14.73% Asia/Thimbu 1370 1190 -180 -13.14% Asia/Thimphu 2231 1082 -1149 -51.50% Asia/Tokyo 4119 5049 930 22.58% Asia/Tomsk 18843 19460 617 3.27% Asia/Ujung_Pandang 1545 1333 -212 -13.72% Asia/Ulaanbaatar 13665 15510 1845 13.50% Asia/Ulan_Bator 21552 21488 -64 -0.30% Asia/Urumqi 1825 939 -886 -48.55% Asia/Ust-Nera 17019 18611 1592 9.35% Asia/Vientiane 2109 1611 -498 -23.61% Asia/Vladivostok 18947 18475 -472 -2.49% Asia/Yakutsk 16515 18995 2480 15.02% Asia/Yangon 2606 2025 -581 -22.29% Asia/Yekaterinburg 25238 17601 -7637 -30.26% Asia/Yerevan 17000 18096 1096 6.45% Atlantic/Azores 66857 102814 35957 53.78% Atlantic/Bermuda 32338 32494 156 0.48% Atlantic/Canary 19768 26843 7075 35.79% Atlantic/Cape_Verde 2425 1867 -558 -23.01% Atlantic/Faeroe 28346 19582 -8764 -30.92% Atlantic/Faroe 19530 19989 459 2.35% Atlantic/Jan_Mayen 29570 41296 11726 39.66% Atlantic/Madeira 60128 65559 5431 9.03% Atlantic/Reykjavik 748 853 105 14.04% Atlantic/South_Georgia 1968 1535 -433 -22.00% Atlantic/St_Helena 1225 734 -491 -40.08% Atlantic/Stanley 19662 19190 -472 -2.40% Australia/ACT 33569 36211 2642 7.87% Australia/Adelaide 30466 32203 1737 5.70% Australia/Brisbane 7095 8435 1340 18.89% Australia/Broken_Hill 53218 38298 -14920 -28.04% Australia/Canberra 51180 37163 -14017 -27.39% Australia/Currie 61207 39206 -22001 -35.95% Australia/Darwin 5080 7941 2861 56.32% Australia/Eucla 11891 9014 -2877 -24.19% Australia/Hobart 37324 40808 3484 9.33% Australia/LHI 43084 42638 -446 -1.04% Australia/Lindeman 14046 8950 -5096 -36.28% Australia/Lord_Howe 28703 29779 1076 3.75% Australia/Melbourne 33176 49744 16568 49.94% Australia/W 31974 35407 3433 10.74% Australia/North 8896 5707 -3189 -35.85% Australia/Perth 13041 8645 -4396 -33.71% Australia/Queeland 6867 7585 718 10.46% Australia/South 30677 31528 851 2.77% Australia/Sydney 33524 35733 2209 6.59% Australia/Tasmania 59927 41908 -18019 -30.07% Australia/Victoria 49836 35892 -13944 -27.98% Australia/West 10721 8527 -2194 -20.46% Australia/Yancowinna 33618 35776 2158 6.42% Brazil/Acre 18410 26298 7888 42.85% Brazil/DeNoronha 24251 34487 10236 42.21% Brazil/East 58061 39966 -18095 -31.17% Brazil/West 31396 22438 -8958 -28.53% CET 53457 42100 -11357 -21.25% CST6CDT 42964 70528 27564 64.16% Canada/Atlantic 54416 61068 6652 12.22% Canada/Central 35207 53101 17894 50.83% Canada/Eastern 68561 55798 -12763 -18.62% Canada/Mountain 40768 32340 -8428 -20.67% Canada/Newfoundland 86446 60162 -26284 -30.41% Canada/Pacific 30894 31914 1020 3.30% Canada/Saskatchewan 15180 23478 8298 54.66% Canada/Yukon 19982 20989 1007 5.04% Chile/Continental 88407 57597 -30810 -34.85% Chile/EasterIsland 79607 51069 -28538 -35.85% Cuba 76383 46201 -30182 -39.51% EET 27551 27470 -81 -0.29% EST 899 1654 755 83.98% EST5EDT 42689 52178 9489 22.23% Egypt 67219 47429 -19790 -29.44% Eire 69817 69619 -198 -0.28% Etc/GMT 1162 1149 -13 -1.12% Etc/GMT+0 631 791 160 25.36% Etc/GMT+1 1019 835 -184 -18.06% Etc/GMT+10 1031 962 -69 -6.69% Etc/GMT+11 1808 845 -963 -53.26% Etc/GMT+12 1792 803 -989 -55.19% Etc/GMT+2 1790 1384 -406 -22.68% Etc/GMT+3 1101 1305 204 18.53% Etc/GMT+4 967 841 -126 -13.03% Etc/GMT+5 1118 787 -331 -29.61% Etc/GMT+6 1772 830 -942 -53.16% Etc/GMT+7 1780 751 -1029 -57.81% Etc/GMT+8 1792 1327 -465 -25.95% Etc/GMT+9 961 1288 327 34.03% Etc/GMT-0 785 769 -16 -2.04% Etc/GMT-1 1015 896 -119 -11.72% Etc/GMT-10 1801 901 -900 -49.97% Etc/GMT-11 1752 761 -991 -56.56% Etc/GMT-12 1845 4307 2462 133.44% Etc/GMT-13 1028 1260 232 22.57% Etc/GMT-14 1266 801 -465 -36.73% Etc/GMT-2 1044 1273 229 21.93% Etc/GMT-3 1838 817 -1021 -55.55% Etc/GMT-4 1817 770 -1047 -57.62% Etc/GMT-5 1797 1306 -491 -27.32% Etc/GMT-6 1026 1257 231 22.51% Etc/GMT-7 1032 806 -226 -21.90% Etc/GMT-8 1194 905 -289 -24.20% Etc/GMT-9 920 776 -144 -15.65% Etc/GMT0 1140 642 -498 -43.68% Etc/Greenwich 1201 1209 8 0.67% Etc/UCT 668 1118 450 67.37% Etc/UTC 674 629 -45 -6.68% Etc/Universal 678 1158 480 70.80% Etc/Zulu 1155 653 -502 -43.46% Europe/Amsterdam 54763 38538 -16225 -29.63% Europe/Andorra 27548 28057 509 1.85% Europe/Astrakhan 17609 24263 6654 37.79% Europe/Athe 25283 31266 5983 23.66% Europe/Belfast 76746 92632 15886 20.70% Europe/Belgrade 31942 25200 -6742 -21.11% Europe/Berlin 44747 42331 -2416 -5.40% Europe/Bratislava 40900 40866 -34 -0.08% Europe/Brussels 40801 39357 -1444 -3.54% Europe/Bucharest 26487 31302 4815 18.18% Europe/Budapest 31018 35507 4489 14.47% Europe/Busingen 31389 21494 -9895 -31.52% Europe/Chisinau 46020 45648 -372 -0.81% Europe/Copenhagen 41203 45390 4187 10.16% Europe/Dublin 70916 110111 39195 55.27% Europe/Gibraltar 65480 72474 6994 10.68% Europe/Guerey 75260 87045 11785 15.66% Europe/Helsinki 29762 30571 809 2.72% Europe/Isle_of_Man 131491 132408 917 0.70% Europe/Istanbul 39048 56044 16996 43.53% Europe/Jersey 80149 82394 2245 2.80% Europe/Kaliningrad 21348 23824 2476 11.60% Europe/Kiev 23530 35547 12017 51.07% Europe/Kirov 23806 27499 3693 15.51% Europe/Kyiv 35061 35230 169 0.48% Europe/Lisbon 93579 97866 4287 4.58% Europe/Ljubljana 24038 22885 -1153 -4.80% Europe/London 75229 88115 12886 17.13% Europe/Luxembourg 36086 40114 4028 11.16% Europe/Madrid 49772 35227 -14545 -29.22% Europe/Malta 54583 55181 598 1.10% Europe/Mariehamn 29888 21797 -8091 -27.07% Europe/Mik 18530 18585 55 0.30% Europe/Monaco 37165 40619 3454 9.29% Europe/Moscow 19650 21535 1885 9.59% Europe/Nicosia 33819 24879 -8940 -26.43% Europe/Oslo 41238 41490 252 0.61% Europe/Paris 57151 56900 -251 -0.44% Europe/Podgorica 23036 23915 879 3.82% Europe/Prague 27016 30361 3345 12.38% Europe/Riga 24294 26604 2310 9.51% Europe/Rome 55333 42517 -12816 -23.16% Europe/Samara 25788 26203 415 1.61% Europe/San_Marino 56980 56532 -448 -0.79% Europe/Sarajevo 24024 24340 316 1.32% Europe/Saratov 16820 17450 630 3.75% Europe/Simferopol 19062 21468 2406 12.62% Europe/Skopje 30961 22185 -8776 -28.35% Europe/Sofia 35927 28842 -7085 -19.72% Europe/Stockholm 61930 30918 -31012 -50.08% Europe/Tallinn 30075 29543 -532 -1.77% Europe/Tirane 25078 26307 1229 4.90% Europe/Tiraspol 30569 46400 15831 51.79% Europe/Ulyanovsk 24736 19152 -5584 -22.57% Europe/Uzhgorod 35002 35532 530 1.51% Europe/Vaduz 59043 23595 -35448 -60.04% Europe/Vatican 39830 42401 2571 6.45% Europe/Vienna 27807 29450 1643 5.91% Europe/Vilnius 24444 26784 2340 9.57% Europe/Volgograd 23738 18314 -5424 -22.85% Europe/Warsaw 50443 40915 -9528 -18.89% Europe/Zagreb 30647 24064 -6583 -21.48% Europe/Zaporozhye 25175 35929 10754 42.72% Europe/Zurich 21104 23074 1970 9.33% Factory 651 1059 408 62.67% GB 129735 83899 -45836 -35.33% GB-Eire 131650 133930 2280 1.73% GMT 1942 766 -1176 -60.56% GMT+0 731 1109 378 51.71% GMT-0 637 703 66 10.36% GMT0 634 712 78 12.30% Greenwich 1078 1151 73 6.77% HST 6041 4377 -1664 -27.55% Hongkong 26345 18067 -8278 -31.42% Iceland 823 1275 452 54.92% Indian/Antananarivo 1713 1306 -407 -23.76% Indian/Chagos 1406 1108 -298 -21.19% Indian/Christmas 2040 1606 -434 -21.27% Indian/Cocos 2508 1574 -934 -37.24% Indian/Comoro 2514 1285 -1229 -48.89% Indian/Kerguelen 1371 859 -512 -37.35% Indian/Mahe 1189 869 -320 -26.91% Indian/Maldives 1259 1042 -217 -17.24% Indian/Mauritius 5728 5671 -57 -1.00% Indian/Mayotte 2521 1588 -933 -37.01% Indian/Reunion 1866 1035 -831 -44.53% Iran 24736 21404 -3332 -13.47% Israel 43102 44485 1383 3.21% Jamaica 8245 8841 596 7.23% Japan 6302 7016 714 11.33% Kwajalein 2742 1545 -1197 -43.65% Libya 16438 12977 -3461 -21.05% MET 38118 37902 -216 -0.57% MST 6174 6402 228 3.69% MST7MDT 31456 33627 2171 6.90% Mexico/BajaNorte 51752 53226 1474 2.85% Mexico/BajaSur 20595 15706 -4889 -23.74% Mexico/General 23776 18425 -5351 -22.51% NZ 33312 35095 1783 5.35% NZ-CHAT 27395 27615 220 0.80% Navajo 30704 36507 5803 18.90% PRC 12456 13031 575 4.62% PST8PDT 52784 38118 -14666 -27.78% Pacific/Apia 12316 12685 369 3.00% Pacific/Auckland 34055 32540 -1515 -4.45% Pacific/Bougainville 1766 1984 218 12.34% Pacific/Chatham 41134 29624 -11510 -27.98% Pacific/Chuuk 2116 1559 -557 -26.32% Pacific/Easter 78478 50093 -28385 -36.17% Pacific/Efate 8631 11830 3199 37.06% Pacific/Enderbury 1603 1060 -543 -33.87% Pacific/Fakaofo 1248 1104 -144 -11.54% Pacific/Fiji 17186 15793 -1393 -8.11% Pacific/Funafuti 1979 878 -1101 -55.63% Pacific/Galapagos 5718 4755 -963 -16.84% Pacific/Gambier 1263 1422 159 12.59% Pacific/Guadalcanal 1480 988 -492 -33.24% Pacific/Guam 10692 7365 -3327 -31.12% Pacific/Honolulu 3751 5939 2188 58.33% Pacific/Johton 6097 4006 -2091 -34.30% Pacific/Kanton 2330 1376 -954 -40.94% Pacific/Kiritimati 1545 1934 389 25.18% Pacific/Kosrae 2017 1809 -208 -10.31% Pacific/Kwajalein 2691 1546 -1145 -42.55% Pacific/Majuro 1135 1458 323 28.46% Pacific/Marquesas 1970 987 -983 -49.90% Pacific/Midway 1501 1004 -497 -33.11% Pacific/Nauru 1672 2095 423 25.30% Pacific/Niue 1318 1086 -232 -17.60% Pacific/Norfolk 14907 10636 -4271 -28.65% Pacific/Noumea 4558 6172 1614 35.41% Pacific/Pago_Pago 1389 889 -500 -36.00% Pacific/Palau 1989 1113 -876 -44.04% Pacific/Pitcairn 1519 1654 135 8.89% Pacific/Pohnpei 1118 931 -187 -16.73% Pacific/Ponape 1185 1435 250 21.10% Pacific/Port_Moresby 1249 1593 344 27.54% Pacific/Rarotonga 12609 9705 -2904 -23.03% Pacific/Saipan 10714 8046 -2668 -24.90% Pacific/Samoa 788 1453 665 84.39% Pacific/Tahiti 1085 980 -105 -9.68% Pacific/Tarawa 1935 875 -1060 -54.78% Pacific/Tongatapu 6198 8052 1854 29.91% Pacific/Truk 2110 1171 -939 -44.50% Pacific/Wake 2025 951 -1074 -53.04% Pacific/Wallis 1264 1380 116 9.18% Pacific/Yap 1234 1551 317 25.69% Poland 34892 37456 2564 7.35% Portugal 59675 61944 2269 3.80% ROC 14608 11594 -3014 -20.63% ROK 14612 11683 -2929 -20.05% Singapore 2076 2518 442 21.29% Turkey 36420 42660 6240 17.13% UCT 1161 639 -522 -44.96% US/Alaska 27014 42130 15116 55.96% US/Aleutian 42377 32003 -10374 -24.48% US/Arizona 9537 6959 -2578 -27.03% US/Central 44928 69945 25017 55.68% US/East-Indiana 21745 23509 1764 8.11% US/Eastern 65486 51963 -13523 -20.65% US/Hawaii 3824 4336 512 13.39% US/Indiana-Starke 46790 34346 -12444 -26.60% US/Michigan 41186 31103 -10083 -24.48% US/Mountain 32479 48325 15846 48.79% US/Pacific 33663 35691 2028 6.02% US/Samoa 940 1013 73 7.77% UTC 614 1158 544 88.60% Universal 1143 715 -428 -37.45% W-SU 28983 22915 -6068 -20.94% WET 61715 98640 36925 59.83% Zulu 610 696 86 14.10%
