Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/2228545/?format=api
{ "id": 2228545, "url": "http://patchwork.ozlabs.org/api/1.2/patches/2228545/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/CAF8dVMW_hrYk3b=dJRfEhjSx_iKQhu6Q3hEZqzua6T=1=RNhSA@mail.gmail.com/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/1.2/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<CAF8dVMW_hrYk3b=dJRfEhjSx_iKQhu6Q3hEZqzua6T=1=RNhSA@mail.gmail.com>", "list_archive_url": null, "date": "2026-04-26T23:53:10", "name": "[v2,2/5] libstdc++: Support ON-format DAY in Zone UNTIL field [PR124852]", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "5eeb7db3e2ac3f4aa8fb6372fc8633fef97af9cd", "submitter": { "id": 93119, "url": "http://patchwork.ozlabs.org/api/1.2/people/93119/?format=api", "name": "Álvaro Begué", "email": "alvaro.begue@gmail.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/CAF8dVMW_hrYk3b=dJRfEhjSx_iKQhu6Q3hEZqzua6T=1=RNhSA@mail.gmail.com/mbox/", "series": [ { "id": 501555, "url": "http://patchwork.ozlabs.org/api/1.2/series/501555/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=501555", "date": "2026-04-26T23:42:54", "name": "libstdc++: chrono tzdb correctness fixes", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/501555/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2228545/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2228545/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "gcc-patches@gcc.gnu.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=U9Vn/Nds;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)", "sourceware.org;\n\tdkim=pass (2048-bit key,\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=U9Vn/Nds", "sourceware.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com", "sourceware.org; spf=pass smtp.mailfrom=gmail.com", "server2.sourceware.org;\n arc=pass smtp.remote-ip=209.85.217.51" ], "Received": [ "from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g3k8R1Xq6z1xvV\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 27 Apr 2026 09:55:03 +1000 (AEST)", "from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 441A34BB1C31\n\tfor <incoming@patchwork.ozlabs.org>; Sun, 26 Apr 2026 23:55:01 +0000 (GMT)", "from mail-vs1-f51.google.com (mail-vs1-f51.google.com\n [209.85.217.51])\n by sourceware.org (Postfix) with ESMTPS id BB19F4BABF16\n for <gcc-patches@gcc.gnu.org>; Sun, 26 Apr 2026 23:53:50 +0000 (GMT)", "by mail-vs1-f51.google.com with SMTP id\n ada2fe7eead31-606045ef716so6948210137.0\n for <gcc-patches@gcc.gnu.org>; Sun, 26 Apr 2026 16:53:50 -0700 (PDT)" ], "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 sourceware.org 441A34BB1C31", "OpenDKIM Filter v2.11.0 sourceware.org BB19F4BABF16" ], "DMARC-Filter": "OpenDMARC Filter v1.4.2 sourceware.org BB19F4BABF16", "ARC-Filter": "OpenARC Filter v1.0.0 sourceware.org BB19F4BABF16", "ARC-Seal": [ "i=2; a=rsa-sha256; d=sourceware.org; s=key; t=1777247630; cv=pass;\n b=vT+jXtmBAOfMfFtuRSUCICnhVCqtDXV1xB5bfDl5SsfnseevS8jwBMT8ZvFsXwMVXoZZMYWiEbwMf0hYBk5xviGfLLyg/ks2vR+VHHMUApcTRPc6RIf1k1Osz7jriluYVCGvAEJidGJz/zkqnRQebXU5/GMhWj4LEbK6FGMIYjE=", "i=1; a=rsa-sha256; t=1777247630; cv=none;\n d=google.com; s=arc-20240605;\n b=Ut/JQDv6I0qqTpsuury2zmFiJ+f2hajHGT3LOmxUBbZqEAjnKawfbfkxScpzTcra0+\n y8obIqrboONrAbYxZVBvkk05yDn+ntaFUhJyyfzYmPFfoaVx7yCKuhvPG0tn20YeOhrM\n Mu9vm24P/EtGBgrJPNLUMD15BAxEgXGlLd544sZpkC9ltU42TsQzERre3lJgYk4oVVtG\n 9DB08N1pJMQoY8Vwx56G0m6Dr5xM3A87qZwggtfcOQ4pqO8epsAi6+6TWccSXAYcGlLv\n rF2op4vGJMaoHmURz5GA+q+/0EtkuKaOstLZeDDk+YO+AIfL+d9aH1svu6jWNnv0YhSA\n xKxA==" ], "ARC-Message-Signature": [ "i=2; a=rsa-sha256; d=sourceware.org; s=key;\n t=1777247630; c=relaxed/simple;\n bh=vn01wykoexttmr2RU2ZRMYet+LkbDCIChn9u2KCIPoM=;\n h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To;\n b=ZA9BCu9hTY0NxgPR8Q/Pxh/+Sn5i0MHMm+ORKZYlAJDEvEHpAWbw1U16eunjeDfXVmcJqVPMEaamvX2z12Ukrxj5WAlzoQ9aX8B1mHLqeD4Di+cCCjAFXa4LXw1U6jtweTO2M7SebjB/BD7egUwlFlQqeFl6m00tmZsN+XubRY8=", "i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n s=arc-20240605;\n h=cc:to:subject:message-id:date:from:mime-version:dkim-signature;\n bh=m2iHuv59j8tcdbXhMQcJWzwy4xLE8s1fIOJKjGOh9mw=;\n fh=sWbBxiX87E8F1zPxXVV3X4tQqxV9sZLoQvmjvveliwE=;\n b=J0J/o2WkPaN5+L3828st7UvOySP21qiJ1VOtxd2fxW58xvsH0OkA2Yfd2Vb7aaKni3\n tVRGz1+99KmJN0eUqWvUz/vvM/zpTnUVpwn1HVe3KiX2tnBCj/G1+bmU0ou7xf+sqMfJ\n GIXIjVPqkoRjoEHjKFPa7ircz80V+nwOUmfFpJ/B8/64/ylRnxVn/Lazy135vspqvsEK\n cp6huh9xy3Agga/zrEorw7Cc8s9DCiJMqVeWG66SUcbFV8kh0F3Lb25ZfP01AwczdxPN\n +ou/OzPCgeuk163h0AY4/ZZeGedgIKLTBykD73MJe00ZHoO2JcKZ1AkzadZo6C4RQrVc\n sJ4A==; darn=gcc.gnu.org" ], "ARC-Authentication-Results": [ "i=2; server2.sourceware.org", "i=1; mx.google.com; arc=none" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1777247630; x=1777852430; darn=gcc.gnu.org;\n h=cc:to:subject:message-id:date:from:mime-version:from:to:cc:subject\n :date:message-id:reply-to;\n bh=m2iHuv59j8tcdbXhMQcJWzwy4xLE8s1fIOJKjGOh9mw=;\n b=U9Vn/NdsXb9g1WEh2bzEHl1RLoBZsWahWVg87/YM7lGMU+ZDdk9huB/jO44zov2Q+8\n mbCHIWhQ6Bjr2lCR7wj4EIFJhCXOmAg5vSekMD0e64ZPIfLUX0sx3mAb2TQ5NEHc8z/c\n peYa3q7cUssrk7BfETP8T6sl5ELbHtPyGHMV/uePaw6114n8mQE4oiH4BuJE/3FV5JWg\n Y7K3YKjbrBOyJBtwFhX9ZgjmJ9GcBHwo2GduN95Ugv/QGx+hyoDsDiJF8qWbs3h0ZanT\n jKNqriBZ8T4wOYk6hn6u0kHCJYOkF/2hRy6ts9x4qKps1wpdWWBewXxNG+wb44WUU6cX\n qvNg==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777247630; x=1777852430;\n h=cc:to:subject:message-id:date:from:mime-version:x-gm-gg\n :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n bh=m2iHuv59j8tcdbXhMQcJWzwy4xLE8s1fIOJKjGOh9mw=;\n b=KnB4Q8uT7Rh+yD/iYQ4nTaqIbwcs2wQPWOIrdeZjXHvTZIBFVazPvjNLuXw3zfMq2C\n v/gZw4aTfep1SmW+rOxzxgJqWxKl0sQ1QcbtC+i58ay0+WET4r4jbosFO1gctKnaN9wM\n wVuP6CnSkYfJH/Nf6rHXWMeESSB85cCgbM/ux/PiWUoXohwbvNyvqSo5DZjN1Z6lVsMa\n 1/uRp/tvfUG+NPRQ+AEUTmbpFOWsG4AlHUkzuE+kSpmyKYWam41fhszmBYJyGKN3GDdl\n 0rfBxHpFV0AldOhsGV2YEnUQF4StCV89MMDukU/jS+ll4dgkBjRdHzgLPvvYX/9j/E3r\n dULA==", "X-Gm-Message-State": "AOJu0YxaC5qrpyPgl8RxZDoJsxyNTDMV7tlKOWypGV6Q3iqAqt1n/OUW\n NyTo1gmAdCL1rCb9rMlnKc7K4AFwPOAprtJ6RJC+BEYNzG3TlER/kmwCgW9qw+nx/UdmD/Auz0L\n VsH1mD8hHcqm122+bQAr8HH4sYP5vcEaTtgnljvo=", "X-Gm-Gg": "AeBDiete7c44F9dSowxvEj6R14B8aLdkvtDOHTZrQjFbURENOWsRuQKfA0d3kzzuDLS\n QU9jqMPbHUTPcRXGiRWI3HShWyF0xcWKQJBpvrWieiLQESBikP/8kNUgkSoGHBjm7aMsdc1QoaK\n /GiUrstl2Cve6WT1xecTnqFUICfOYeVx513pjHuNbnXToMUYecbfqBDDTYsw3D5oiudekdO40LX\n iayt/vc7ZZ3++8c7DTYGK9CwqJKP6SPrfGVL8oDPb2k0u4tbYk7MKIFHMLJm4pOu1Jm1s9g7fOO\n l3tTIv9pw0PC12TFZFMmxRxniDwkZC958fCInKOEk0wxMFy7VB5NI9gdpdxk1CnP9TQmCzsGnhj\n EnBt1uMnkkauKtjdVvcLZWkDOWE3JGvaZxbnKjLRFiLvGnpsPAmcpiwK8kp4fQ0LlCRakqg==", "X-Received": "by 2002:a05:6102:5987:b0:602:86a6:9877 with SMTP id\n ada2fe7eead31-616f68d3997mr20371727137.19.1777247629962; Sun, 26 Apr 2026\n 16:53:49 -0700 (PDT)", "MIME-Version": "1.0", "From": "=?utf-8?b?w4FsdmFybyBCZWd1w6k=?= <alvaro.begue@gmail.com>", "Date": "Sun, 26 Apr 2026 19:53:10 -0400", "X-Gm-Features": "AVHnY4Kre-lpxoFrgJFmPIWDlHmcTEZFmgDA5iqLJp_7LXCLFUV1jdO90tNOSzY", "Message-ID": "\n <CAF8dVMW_hrYk3b=dJRfEhjSx_iKQhu6Q3hEZqzua6T=1=RNhSA@mail.gmail.com>", "Subject": "[PATCH v2 2/5] libstdc++: Support ON-format DAY in Zone UNTIL field\n [PR124852]", "To": "gcc-patches@gcc.gnu.org", "Cc": "jwakely@redhat.com, libstdc++@gcc.gnu.org, tkaminsk@redhat.com,\n\t=?utf-8?b?w4FsdmFybyBCZWd1w6k=?= <alvaro.begue@gmail.com>", "Content-Type": "multipart/alternative; boundary=\"000000000000a97126065065b530\"", "X-BeenThere": "gcc-patches@gcc.gnu.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "Gcc-patches mailing list <gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>", "List-Archive": "<https://gcc.gnu.org/pipermail/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-request@gcc.gnu.org?subject=help>", "List-Subscribe": "<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>", "Errors-To": "gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org" }, "content": "The Zone-line UNTIL parser only accepted a plain day-of-month integer\nfor the DAY field, while the tzdata.zi grammar accepts the same ON-style\nforms as Rule lines: lastSun, Sun>=8, Sat<=20, etc. Real zones use these\nforms in their UNTIL DAY: Europe/Simferopol's `3 - MSK 1997 Mar lastSu\n1u`, for instance, became `Mar 1` (silently misparsed) instead of `Mar\n30`, leaving Simferopol an extra 29 days in MSK.\n\nThe previous parser's `int d = 1; in >> m >> d >> t;` chain silently\nleft d == 1 when the day token wasn't a digit, then went on to parse the\nremainder as the TIME field.\n\nFactor out the day-component parser from operator>>(istream&, on_day&)\nas parse_day_spec(), and reuse it for the UNTIL DAY field. parse_day_spec\nhandles all three on_day forms (DayOfMonth, LastWeekday, LessEq /\nGreaterEq). The MONTH-only and YEAR-only short forms are still accepted\nbecause the DAY/TIME fields are optional and default to day 1, time 00:00.\nThe on_day struct's pin() method handles the year/month-relative\nresolution.\n\nThe DAY field is unambiguously distinguishable from a TIME field that\ncould otherwise follow the MONTH directly: per zic's grammar, MONTH\nmust be followed by DAY before any TIME is allowed. So we always\nattempt to parse a DAY if any non-whitespace remains after the MONTH.\n\nlibstdc++-v3/ChangeLog:\n\nPR libstdc++/124852\n* src/c++20/tzdb.cc (parse_day_spec): New function, factored\nout of operator>>(istream&, on_day&).\n(operator>>(istream&, on_day&)): Use parse_day_spec.\n(operator>>(istream&, ZoneInfo&)): Replace the integer DAY\nparser with parse_day_spec for the UNTIL field.\n* testsuite/std/time/time_zone/until_day_on.cc: New test.\n\nSigned-off-by: Álvaro Begué <alvaro.begue@gmail.com>\n---\n libstdc++-v3/src/c++20/tzdb.cc | 47 +++--\n .../std/time/time_zone/until_day_on.cc | 168 ++++++++++++++++++\n 2 files changed, 199 insertions(+), 16 deletions(-)\n create mode 100644\nlibstdc++-v3/testsuite/std/time/time_zone/until_day_on.cc", "diff": "diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc\nindex 1e49bb749..c0d62bc35 100644\n--- a/libstdc++-v3/src/c++20/tzdb.cc\n+++ b/libstdc++-v3/src/c++20/tzdb.cc\n@@ -2200,22 +2200,23 @@ namespace std::chrono\n }\n };\n\n- istream& operator>>(istream& in, on_day& to)\n+ // Read the day-component of an on_day expression (everything after the\n+ // month). Three forms are accepted: a plain day-of-month number,\n+ // \"lastXxx\" where Xxx is a weekday name (LastWeekday), or \"Xxx<=N\" or\n+ // \"Xxx>=N\" (LessEq / GreaterEq). On failure the function sets failbit\n+ // and leaves `on` unchanged.\n+ istream&\n+ parse_day_spec(istream& in, on_day& on)\n {\n- on_day on{};\n- abbrev_month m{};\n- in >> m;\n- on.month = static_cast<unsigned>(m.m);\n int c = ws(in).peek();\n if ('0' <= c && c <= '9')\n {\n- on.kind = on_day::DayOfMonth;\n unsigned d;\n in >> d;\n if (d <= 31) [[likely]]\n {\n+ on.kind = on_day::DayOfMonth;\n on.day_of_month = d;\n- to = on;\n return in;\n }\n }\n@@ -2226,7 +2227,6 @@ namespace std::chrono\n {\n on.kind = on_day::LastWeekday;\n on.day_of_week = w.wd.c_encoding();\n- to = on;\n return in;\n }\n }\n@@ -2238,14 +2238,13 @@ namespace std::chrono\n {\n if (in.get() == '=')\n {\n- on.kind = c == '<' ? on_day::LessEq : on_day::GreaterEq;\n- on.day_of_week = w.wd.c_encoding();\n unsigned d;\n in >> d;\n if (d <= 31) [[likely]]\n {\n+ on.kind = c == '<' ? on_day::LessEq : on_day::GreaterEq;\n+ on.day_of_week = w.wd.c_encoding();\n on.day_of_month = d;\n- to = on;\n return in;\n }\n }\n@@ -2255,6 +2254,17 @@ namespace std::chrono\n return in;\n }\n\n+ istream& operator>>(istream& in, on_day& to)\n+ {\n+ on_day on{};\n+ abbrev_month m{};\n+ in >> m;\n+ on.month = static_cast<unsigned>(m.m);\n+ if (parse_day_spec(in, on))\n+ to = on;\n+ return in;\n+ }\n+\n istream& operator>>(istream& in, at_time& at)\n {\n int sign = 1;\n@@ -2357,12 +2367,17 @@ namespace std::chrono\n in.exceptions(ios::goodbit); // Don't throw ios::failure if YEAR\nabsent.\n if (int y = int(year::max()); in >> y)\n {\n- abbrev_month m{January};\n- int d = 1;\n+ on_day on{.kind = on_day::DayOfMonth, .month = 1, .day_of_month = 1};\n at_time t{};\n- // XXX DAY should support ON format, e.g. lastSun or Sun>=8\n- in >> m >> d >> t;\n- inf.m_until = sys_days(year(y)/m.m/day(d)) + seconds(t.time);\n+ if (abbrev_month m{January}; in >> m)\n+ {\n+ on.month = static_cast<unsigned>(m.m);\n+ if (!ws(in).eof())\n+ if (parse_day_spec(in, on))\n+ in >> t;\n+ }\n+ year_month_day ymd = on.pin(year(y));\n+ inf.m_until = sys_days(ymd) + seconds(t.time);\n if (t.indicator != at_time::Universal)\n { // UNTIL uses \"the rules in effect just before the transition\"\n // adjust by STDOFF\ndiff --git a/libstdc++-v3/testsuite/std/time/time_zone/until_day_on.cc\nb/libstdc++-v3/testsuite/std/time/time_zone/until_day_on.cc\nnew file mode 100644\nindex 000000000..6b5ce6bae\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/std/time/time_zone/until_day_on.cc\n@@ -0,0 +1,168 @@\n+// { dg-do run { target c++20 } }\n+// { dg-require-effective-target tzdb }\n+// { dg-require-effective-target cxx11_abi }\n+// { dg-xfail-run-if \"no weak override on AIX\" { powerpc-ibm-aix* } }\n+\n+// The DAY portion of a Zone line's UNTIL field accepts not only a\n+// numeric day-of-month but also \"lastXxx\" (last weekday in the month)\n+// and \"Xxx<=N\" / \"Xxx>=N\" forms, just like the ON field of a Rule line.\n+//\n+// Real-world example: Europe/Simferopol has\n+// 3 - MSK 1997 Mar lastSu 1u\n+// which places the boundary on 1997-03-30 (the last Sunday of March).\n+\n+#include <chrono>\n+#include <fstream>\n+#include <testsuite_hooks.h>\n+\n+static bool override_used = false;\n+\n+namespace __gnu_cxx\n+{\n+ const char* zoneinfo_dir_override() {\n+ override_used = true;\n+ return \"./\";\n+ }\n+}\n+\n+void\n+test_lastsu()\n+{\n+ using namespace std::chrono;\n+\n+ std::ofstream(\"tzdata.zi\") << R\"(# version test_lastsu\n+Z Test/LastSu 3 - MSK 1997 Mar lastSu 1u\n+ 3 - X\n+)\";\n+\n+ const auto& db = reload_tzdb();\n+ VERIFY( override_used );\n+ VERIFY( db.version == \"test_lastsu\" );\n+\n+ auto* tz = locate_zone(\"Test/LastSu\");\n+\n+ // True boundary: 1997-03-30 01:00 UTC (lastSu of March 1997 is Mar 30,\n+ // and the indicator is 'u' = Universal so no offset adjustment).\n+ sys_seconds boundary = sys_days{1997y/March/30} + 1h;\n+\n+ // Just before: still in the MSK line.\n+ auto before = tz->get_info(boundary - 1s);\n+ VERIFY( before.abbrev == \"MSK\" );\n+ VERIFY( before.offset == 3h );\n+\n+ // At/after the boundary: in the X line.\n+ auto at = tz->get_info(boundary);\n+ VERIFY( at.abbrev == \"X\" );\n+\n+ // Check that the lastSu day is parsed correctly, and not defaulted\n+ // to the 1st: a March 15 query must still be in the MSK line.\n+ auto mid_march = tz->get_info(sys_days{1997y/March/15});\n+ VERIFY( mid_march.abbrev == \"MSK\" );\n+ VERIFY( mid_march.offset == 3h );\n+}\n+\n+void\n+test_sun_ge_n()\n+{\n+ using namespace std::chrono;\n+\n+ std::ofstream(\"tzdata.zi\") << R\"(# version test_sun_ge_n\n+Z Test/SunGE 0 - A 1990 Jun Sun>=8 0u\n+ 0 - B\n+)\";\n+\n+ const auto& db = reload_tzdb();\n+ VERIFY( override_used );\n+ VERIFY( db.version == \"test_sun_ge_n\" );\n+\n+ auto* tz = locate_zone(\"Test/SunGE\");\n+\n+ // First Sunday >= June 8 1990 = June 10 (June 8 1990 was a Friday).\n+ sys_seconds boundary = sys_days{1990y/June/10};\n+\n+ auto before = tz->get_info(boundary - 1s);\n+ VERIFY( before.abbrev == \"A\" );\n+ auto at = tz->get_info(boundary);\n+ VERIFY( at.abbrev == \"B\" );\n+\n+ // Check that Sun>=8 is parsed correctly, and not defaulted to the 1st.\n+ auto early = tz->get_info(sys_days{1990y/June/1});\n+ VERIFY( early.abbrev == \"A\" );\n+}\n+\n+void\n+test_sun_le_n()\n+{\n+ using namespace std::chrono;\n+\n+ std::ofstream(\"tzdata.zi\") << R\"(# version test_sun_le_n\n+Z Test/SunLE 0 - A 1990 Jun Sun<=15 0u\n+ 0 - B\n+)\";\n+\n+ const auto& db = reload_tzdb();\n+ VERIFY( override_used );\n+ VERIFY( db.version == \"test_sun_le_n\" );\n+\n+ auto* tz = locate_zone(\"Test/SunLE\");\n+\n+ // Last Sunday <= June 15 1990 = June 10.\n+ sys_seconds boundary = sys_days{1990y/June/10};\n+\n+ auto before = tz->get_info(boundary - 1s);\n+ VERIFY( before.abbrev == \"A\" );\n+ auto at = tz->get_info(boundary);\n+ VERIFY( at.abbrev == \"B\" );\n+}\n+\n+void\n+test_year_only()\n+{\n+ using namespace std::chrono;\n+\n+ // MONTH, DAY and TIME default to January 1st 00:00 if not specified.\n+ std::ofstream(\"tzdata.zi\") << R\"(# version test_year_only\n+Z Test/YearOnly 0 - A 1990\n+ 0 - B\n+)\";\n+\n+ const auto& db = reload_tzdb();\n+ VERIFY( db.version == \"test_year_only\" );\n+\n+ auto* tz = locate_zone(\"Test/YearOnly\");\n+ auto before = tz->get_info(sys_days{1989y/December/31} + 23h);\n+ VERIFY( before.abbrev == \"A\" );\n+ auto at = tz->get_info(sys_days{1990y/January/1});\n+ VERIFY( at.abbrev == \"B\" );\n+}\n+\n+void\n+test_year_month_only()\n+{\n+ using namespace std::chrono;\n+\n+ // DAY and TIME default to the 1st 00:00 if not specified.\n+ std::ofstream(\"tzdata.zi\") << R\"(# version test_year_month_only\n+Z Test/YearMonth 0 - A 1990 Jul\n+ 0 - B\n+)\";\n+\n+ const auto& db = reload_tzdb();\n+ VERIFY( db.version == \"test_year_month_only\" );\n+\n+ auto* tz = locate_zone(\"Test/YearMonth\");\n+ auto before = tz->get_info(sys_days{1990y/June/30} + 23h);\n+ VERIFY( before.abbrev == \"A\" );\n+ auto at = tz->get_info(sys_days{1990y/July/1});\n+ VERIFY( at.abbrev == \"B\" );\n+}\n+\n+int\n+main()\n+{\n+ test_lastsu();\n+ test_sun_ge_n();\n+ test_sun_le_n();\n+ test_year_only();\n+ test_year_month_only();\n+}\n", "prefixes": [ "v2", "2/5" ] }