get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.2/patches/2228545/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "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"
    ]
}