From 9a31c9a5d428ab4ddcf1f40601e17fe4c1203c64 Mon Sep 17 00:00:00 2001 From: nick-gorman Date: Thu, 11 Jun 2026 12:24:52 +1000 Subject: [PATCH 1/2] Template timeslice windows as per-reference-year patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AEMO timeslice calendar (timeslice_RefYear5000.csv, shipped under templater/plexos/ with the other PLEXOS data-package extracts) marks hot day / typical summer / winter windows on absolute dates, with each planning year's dates derived from the weather of the reference year AEMO assigned to it. Templating the calendar as absolute windows would bake AEMO's reference-year sequence into every run regardless of the user's configured reference_year_cycle, so peak-day limits would fall on days that aren't peaks in the modelled traces. Instead the templater inverts the calendar: it assigns windows to the planning year they start in, labels them via Table 1 of the Draft 2026 ISP Market Model Instructions (transcribed as the manually extracted reference_year_sequence table, extended cyclically per AEMO's repeating sequence), and emits one month-day window pattern per reference year for the translator to re-sequence. Every occurrence of a reference year must carry an identical pattern — the check that proves the Table 1 decode against the data; it passes for all 33 usable planning years. Planning years truncated at the calendar horizon (windows that never turn off) are dropped whole: their reference years recur earlier with complete windows. Co-Authored-By: Claude Fable 5 --- .../7.5/reference_year_sequence.csv | 17 + .../plexos/7.5/timeslice_RefYear5000.csv | 3388 +++++++++++++++++ src/ispypsa/templater/timeslices.py | 296 ++ .../validation/schemas/timeslices.yaml | 75 + tests/test_templater/test_timeslices.py | 216 ++ 5 files changed, 3992 insertions(+) create mode 100644 src/ispypsa/templater/manually_extracted_template_tables/7.5/reference_year_sequence.csv create mode 100644 src/ispypsa/templater/plexos/7.5/timeslice_RefYear5000.csv create mode 100644 src/ispypsa/templater/timeslices.py create mode 100644 src/ispypsa/validation/schemas/timeslices.yaml create mode 100644 tests/test_templater/test_timeslices.py diff --git a/src/ispypsa/templater/manually_extracted_template_tables/7.5/reference_year_sequence.csv b/src/ispypsa/templater/manually_extracted_template_tables/7.5/reference_year_sequence.csv new file mode 100644 index 00000000..84d58130 --- /dev/null +++ b/src/ispypsa/templater/manually_extracted_template_tables/7.5/reference_year_sequence.csv @@ -0,0 +1,17 @@ +planning_year,reference_year +2026,2015 +2027,2011 +2028,2012 +2029,2013 +2030,2014 +2031,2015 +2032,2016 +2033,2017 +2034,2018 +2035,2019 +2036,2020 +2037,2021 +2038,2022 +2039,2023 +2040,2024 +2041,2025 diff --git a/src/ispypsa/templater/plexos/7.5/timeslice_RefYear5000.csv b/src/ispypsa/templater/plexos/7.5/timeslice_RefYear5000.csv new file mode 100644 index 00000000..8c44038e --- /dev/null +++ b/src/ispypsa/templater/plexos/7.5/timeslice_RefYear5000.csv @@ -0,0 +1,3388 @@ +DATETIME,NAME,TIMESLICE +30/06/2021,NSW Hot Day,0 +18/12/2021,NSW Hot Day,-1 +20/12/2021,NSW Hot Day,0 +01/02/2022,NSW Hot Day,-1 +02/02/2022,NSW Hot Day,0 +10/02/2022,NSW Hot Day,-1 +11/02/2022,NSW Hot Day,0 +17/02/2022,NSW Hot Day,-1 +18/02/2022,NSW Hot Day,0 +26/01/2023,NSW Hot Day,-1 +27/01/2023,NSW Hot Day,0 +11/02/2023,NSW Hot Day,-1 +12/02/2023,NSW Hot Day,0 +06/03/2023,NSW Hot Day,-1 +07/03/2023,NSW Hot Day,0 +16/03/2023,NSW Hot Day,-1 +17/03/2023,NSW Hot Day,0 +19/03/2023,NSW Hot Day,-1 +20/03/2023,NSW Hot Day,0 +09/12/2023,NSW Hot Day,-1 +10/12/2023,NSW Hot Day,0 +14/12/2023,NSW Hot Day,-1 +15/12/2023,NSW Hot Day,0 +21/01/2024,NSW Hot Day,-1 +22/01/2024,NSW Hot Day,0 +26/01/2024,NSW Hot Day,-1 +27/01/2024,NSW Hot Day,0 +29/02/2024,NSW Hot Day,-1 +01/03/2024,NSW Hot Day,0 +27/11/2024,NSW Hot Day,-1 +28/11/2024,NSW Hot Day,0 +17/12/2024,NSW Hot Day,-1 +18/12/2024,NSW Hot Day,0 +27/12/2024,NSW Hot Day,-1 +28/12/2024,NSW Hot Day,0 +28/01/2025,NSW Hot Day,-1 +29/01/2025,NSW Hot Day,0 +28/02/2025,NSW Hot Day,-1 +01/03/2025,NSW Hot Day,0 +14/11/2025,NSW Hot Day,-1 +15/11/2025,NSW Hot Day,0 +21/11/2025,NSW Hot Day,-1 +22/11/2025,NSW Hot Day,0 +23/11/2025,NSW Hot Day,-1 +24/11/2025,NSW Hot Day,0 +25/01/2026,NSW Hot Day,-1 +26/01/2026,NSW Hot Day,0 +01/03/2026,NSW Hot Day,-1 +02/03/2026,NSW Hot Day,0 +01/01/2027,NSW Hot Day,-1 +02/01/2027,NSW Hot Day,0 +31/01/2027,NSW Hot Day,-1 +02/02/2027,NSW Hot Day,0 +05/02/2027,NSW Hot Day,-1 +06/02/2027,NSW Hot Day,0 +19/02/2027,NSW Hot Day,-1 +20/02/2027,NSW Hot Day,0 +08/11/2027,NSW Hot Day,-1 +10/11/2027,NSW Hot Day,0 +14/11/2027,NSW Hot Day,-1 +15/11/2027,NSW Hot Day,0 +20/11/2027,NSW Hot Day,-1 +21/11/2027,NSW Hot Day,0 +04/01/2028,NSW Hot Day,-1 +05/01/2028,NSW Hot Day,0 +30/11/2028,NSW Hot Day,-1 +02/12/2028,NSW Hot Day,0 +08/01/2029,NSW Hot Day,-1 +09/01/2029,NSW Hot Day,0 +18/01/2029,NSW Hot Day,-1 +19/01/2029,NSW Hot Day,0 +22/01/2029,NSW Hot Day,-1 +23/01/2029,NSW Hot Day,0 +08/11/2029,NSW Hot Day,-1 +09/11/2029,NSW Hot Day,0 +20/12/2029,NSW Hot Day,-1 +21/12/2029,NSW Hot Day,0 +22/12/2029,NSW Hot Day,-1 +24/12/2029,NSW Hot Day,0 +02/01/2030,NSW Hot Day,-1 +03/01/2030,NSW Hot Day,0 +14/11/2030,NSW Hot Day,-1 +15/11/2030,NSW Hot Day,0 +21/11/2030,NSW Hot Day,-1 +22/11/2030,NSW Hot Day,0 +23/11/2030,NSW Hot Day,-1 +24/11/2030,NSW Hot Day,0 +25/01/2031,NSW Hot Day,-1 +26/01/2031,NSW Hot Day,0 +01/03/2031,NSW Hot Day,-1 +02/03/2031,NSW Hot Day,0 +19/11/2031,NSW Hot Day,-1 +21/11/2031,NSW Hot Day,0 +14/01/2032,NSW Hot Day,-1 +15/01/2032,NSW Hot Day,0 +20/01/2032,NSW Hot Day,-1 +21/01/2032,NSW Hot Day,0 +25/02/2032,NSW Hot Day,-1 +26/02/2032,NSW Hot Day,0 +11/01/2033,NSW Hot Day,-1 +12/01/2033,NSW Hot Day,0 +30/01/2033,NSW Hot Day,-1 +01/02/2033,NSW Hot Day,0 +05/02/2033,NSW Hot Day,-1 +06/02/2033,NSW Hot Day,0 +10/02/2033,NSW Hot Day,-1 +12/02/2033,NSW Hot Day,0 +14/12/2033,NSW Hot Day,-1 +15/12/2033,NSW Hot Day,0 +20/12/2033,NSW Hot Day,-1 +21/12/2033,NSW Hot Day,0 +24/12/2033,NSW Hot Day,-1 +25/12/2033,NSW Hot Day,0 +07/01/2034,NSW Hot Day,-1 +08/01/2034,NSW Hot Day,0 +18/03/2034,NSW Hot Day,-1 +19/03/2034,NSW Hot Day,0 +28/12/2034,NSW Hot Day,-1 +30/12/2034,NSW Hot Day,0 +05/01/2035,NSW Hot Day,-1 +06/01/2035,NSW Hot Day,0 +18/01/2035,NSW Hot Day,-1 +19/01/2035,NSW Hot Day,0 +31/01/2035,NSW Hot Day,-1 +01/02/2035,NSW Hot Day,0 +19/12/2035,NSW Hot Day,-1 +20/12/2035,NSW Hot Day,0 +31/12/2035,NSW Hot Day,-1 +01/01/2036,NSW Hot Day,0 +04/01/2036,NSW Hot Day,-1 +05/01/2036,NSW Hot Day,0 +23/01/2036,NSW Hot Day,-1 +24/01/2036,NSW Hot Day,0 +01/02/2036,NSW Hot Day,-1 +02/02/2036,NSW Hot Day,0 +16/11/2036,NSW Hot Day,-1 +17/11/2036,NSW Hot Day,0 +28/11/2036,NSW Hot Day,-1 +30/11/2036,NSW Hot Day,0 +24/01/2037,NSW Hot Day,-1 +25/01/2037,NSW Hot Day,0 +26/01/2037,NSW Hot Day,-1 +27/01/2037,NSW Hot Day,0 +18/12/2037,NSW Hot Day,-1 +20/12/2037,NSW Hot Day,0 +01/02/2038,NSW Hot Day,-1 +02/02/2038,NSW Hot Day,0 +10/02/2038,NSW Hot Day,-1 +11/02/2038,NSW Hot Day,0 +17/02/2038,NSW Hot Day,-1 +18/02/2038,NSW Hot Day,0 +26/01/2039,NSW Hot Day,-1 +27/01/2039,NSW Hot Day,0 +11/02/2039,NSW Hot Day,-1 +12/02/2039,NSW Hot Day,0 +06/03/2039,NSW Hot Day,-1 +07/03/2039,NSW Hot Day,0 +16/03/2039,NSW Hot Day,-1 +17/03/2039,NSW Hot Day,0 +19/03/2039,NSW Hot Day,-1 +20/03/2039,NSW Hot Day,0 +09/12/2039,NSW Hot Day,-1 +10/12/2039,NSW Hot Day,0 +14/12/2039,NSW Hot Day,-1 +15/12/2039,NSW Hot Day,0 +21/01/2040,NSW Hot Day,-1 +22/01/2040,NSW Hot Day,0 +26/01/2040,NSW Hot Day,-1 +27/01/2040,NSW Hot Day,0 +29/02/2040,NSW Hot Day,-1 +01/03/2040,NSW Hot Day,0 +27/11/2040,NSW Hot Day,-1 +28/11/2040,NSW Hot Day,0 +17/12/2040,NSW Hot Day,-1 +18/12/2040,NSW Hot Day,0 +27/12/2040,NSW Hot Day,-1 +28/12/2040,NSW Hot Day,0 +28/01/2041,NSW Hot Day,-1 +29/01/2041,NSW Hot Day,0 +28/02/2041,NSW Hot Day,-1 +01/03/2041,NSW Hot Day,0 +14/11/2041,NSW Hot Day,-1 +15/11/2041,NSW Hot Day,0 +21/11/2041,NSW Hot Day,-1 +22/11/2041,NSW Hot Day,0 +23/11/2041,NSW Hot Day,-1 +24/11/2041,NSW Hot Day,0 +25/01/2042,NSW Hot Day,-1 +26/01/2042,NSW Hot Day,0 +01/03/2042,NSW Hot Day,-1 +02/03/2042,NSW Hot Day,0 +01/01/2043,NSW Hot Day,-1 +02/01/2043,NSW Hot Day,0 +31/01/2043,NSW Hot Day,-1 +02/02/2043,NSW Hot Day,0 +05/02/2043,NSW Hot Day,-1 +06/02/2043,NSW Hot Day,0 +19/02/2043,NSW Hot Day,-1 +20/02/2043,NSW Hot Day,0 +08/11/2043,NSW Hot Day,-1 +10/11/2043,NSW Hot Day,0 +14/11/2043,NSW Hot Day,-1 +15/11/2043,NSW Hot Day,0 +20/11/2043,NSW Hot Day,-1 +21/11/2043,NSW Hot Day,0 +04/01/2044,NSW Hot Day,-1 +05/01/2044,NSW Hot Day,0 +30/11/2044,NSW Hot Day,-1 +02/12/2044,NSW Hot Day,0 +08/01/2045,NSW Hot Day,-1 +09/01/2045,NSW Hot Day,0 +18/01/2045,NSW Hot Day,-1 +19/01/2045,NSW Hot Day,0 +22/01/2045,NSW Hot Day,-1 +23/01/2045,NSW Hot Day,0 +08/11/2045,NSW Hot Day,-1 +09/11/2045,NSW Hot Day,0 +20/12/2045,NSW Hot Day,-1 +21/12/2045,NSW Hot Day,0 +22/12/2045,NSW Hot Day,-1 +24/12/2045,NSW Hot Day,0 +02/01/2046,NSW Hot Day,-1 +03/01/2046,NSW Hot Day,0 +14/11/2046,NSW Hot Day,-1 +15/11/2046,NSW Hot Day,0 +21/11/2046,NSW Hot Day,-1 +22/11/2046,NSW Hot Day,0 +23/11/2046,NSW Hot Day,-1 +24/11/2046,NSW Hot Day,0 +25/01/2047,NSW Hot Day,-1 +26/01/2047,NSW Hot Day,0 +01/03/2047,NSW Hot Day,-1 +02/03/2047,NSW Hot Day,0 +19/11/2047,NSW Hot Day,-1 +21/11/2047,NSW Hot Day,0 +14/01/2048,NSW Hot Day,-1 +15/01/2048,NSW Hot Day,0 +20/01/2048,NSW Hot Day,-1 +21/01/2048,NSW Hot Day,0 +25/02/2048,NSW Hot Day,-1 +26/02/2048,NSW Hot Day,0 +11/01/2049,NSW Hot Day,-1 +12/01/2049,NSW Hot Day,0 +30/01/2049,NSW Hot Day,-1 +01/02/2049,NSW Hot Day,0 +05/02/2049,NSW Hot Day,-1 +06/02/2049,NSW Hot Day,0 +10/02/2049,NSW Hot Day,-1 +12/02/2049,NSW Hot Day,0 +14/12/2049,NSW Hot Day,-1 +15/12/2049,NSW Hot Day,0 +20/12/2049,NSW Hot Day,-1 +21/12/2049,NSW Hot Day,0 +24/12/2049,NSW Hot Day,-1 +25/12/2049,NSW Hot Day,0 +07/01/2050,NSW Hot Day,-1 +08/01/2050,NSW Hot Day,0 +18/03/2050,NSW Hot Day,-1 +19/03/2050,NSW Hot Day,0 +28/12/2050,NSW Hot Day,-1 +30/12/2050,NSW Hot Day,0 +05/01/2051,NSW Hot Day,-1 +06/01/2051,NSW Hot Day,0 +18/01/2051,NSW Hot Day,-1 +19/01/2051,NSW Hot Day,0 +31/01/2051,NSW Hot Day,-1 +01/02/2051,NSW Hot Day,0 +19/12/2051,NSW Hot Day,-1 +20/12/2051,NSW Hot Day,0 +31/12/2051,NSW Hot Day,-1 +01/01/2052,NSW Hot Day,0 +04/01/2052,NSW Hot Day,-1 +05/01/2052,NSW Hot Day,0 +23/01/2052,NSW Hot Day,-1 +24/01/2052,NSW Hot Day,0 +01/02/2052,NSW Hot Day,-1 +02/02/2052,NSW Hot Day,0 +16/11/2052,NSW Hot Day,-1 +17/11/2052,NSW Hot Day,0 +28/11/2052,NSW Hot Day,-1 +30/11/2052,NSW Hot Day,0 +24/01/2053,NSW Hot Day,-1 +25/01/2053,NSW Hot Day,0 +26/01/2053,NSW Hot Day,-1 +27/01/2053,NSW Hot Day,0 +18/12/2053,NSW Hot Day,-1 +20/12/2053,NSW Hot Day,0 +01/02/2054,NSW Hot Day,-1 +02/02/2054,NSW Hot Day,0 +10/02/2054,NSW Hot Day,-1 +11/02/2054,NSW Hot Day,0 +17/02/2054,NSW Hot Day,-1 +18/02/2054,NSW Hot Day,0 +26/01/2055,NSW Hot Day,-1 +27/01/2055,NSW Hot Day,0 +11/02/2055,NSW Hot Day,-1 +12/02/2055,NSW Hot Day,0 +06/03/2055,NSW Hot Day,-1 +07/03/2055,NSW Hot Day,0 +16/03/2055,NSW Hot Day,-1 +17/03/2055,NSW Hot Day,0 +19/03/2055,NSW Hot Day,-1 +20/03/2055,NSW Hot Day,0 +09/12/2055,NSW Hot Day,-1 +10/12/2055,NSW Hot Day,0 +14/12/2055,NSW Hot Day,-1 +15/12/2055,NSW Hot Day,0 +21/01/2056,NSW Hot Day,-1 +22/01/2056,NSW Hot Day,0 +26/01/2056,NSW Hot Day,-1 +27/01/2056,NSW Hot Day,0 +29/02/2056,NSW Hot Day,-1 +01/03/2056,NSW Hot Day,0 +27/11/2056,NSW Hot Day,-1 +28/11/2056,NSW Hot Day,0 +17/12/2056,NSW Hot Day,-1 +18/12/2056,NSW Hot Day,0 +27/12/2056,NSW Hot Day,-1 +28/12/2056,NSW Hot Day,0 +28/01/2057,NSW Hot Day,-1 +29/01/2057,NSW Hot Day,0 +28/02/2057,NSW Hot Day,-1 +01/03/2057,NSW Hot Day,0 +14/11/2057,NSW Hot Day,-1 +15/11/2057,NSW Hot Day,0 +21/11/2057,NSW Hot Day,-1 +22/11/2057,NSW Hot Day,0 +23/11/2057,NSW Hot Day,-1 +24/11/2057,NSW Hot Day,0 +25/01/2058,NSW Hot Day,-1 +26/01/2058,NSW Hot Day,0 +01/03/2058,NSW Hot Day,-1 +02/03/2058,NSW Hot Day,0 +30/06/2021,NSW Typical Summer,0 +01/11/2021,NSW Typical Summer,-1 +18/12/2021,NSW Typical Summer,0 +20/12/2021,NSW Typical Summer,-1 +01/02/2022,NSW Typical Summer,0 +02/02/2022,NSW Typical Summer,-1 +10/02/2022,NSW Typical Summer,0 +11/02/2022,NSW Typical Summer,-1 +17/02/2022,NSW Typical Summer,0 +18/02/2022,NSW Typical Summer,-1 +01/04/2022,NSW Typical Summer,0 +01/11/2022,NSW Typical Summer,-1 +26/01/2023,NSW Typical Summer,0 +27/01/2023,NSW Typical Summer,-1 +11/02/2023,NSW Typical Summer,0 +12/02/2023,NSW Typical Summer,-1 +06/03/2023,NSW Typical Summer,0 +07/03/2023,NSW Typical Summer,-1 +16/03/2023,NSW Typical Summer,0 +17/03/2023,NSW Typical Summer,-1 +19/03/2023,NSW Typical Summer,0 +20/03/2023,NSW Typical Summer,-1 +01/04/2023,NSW Typical Summer,0 +01/11/2023,NSW Typical Summer,-1 +09/12/2023,NSW Typical Summer,0 +10/12/2023,NSW Typical Summer,-1 +14/12/2023,NSW Typical Summer,0 +15/12/2023,NSW Typical Summer,-1 +21/01/2024,NSW Typical Summer,0 +22/01/2024,NSW Typical Summer,-1 +26/01/2024,NSW Typical Summer,0 +27/01/2024,NSW Typical Summer,-1 +29/02/2024,NSW Typical Summer,0 +01/03/2024,NSW Typical Summer,-1 +01/04/2024,NSW Typical Summer,0 +01/11/2024,NSW Typical Summer,-1 +27/11/2024,NSW Typical Summer,0 +28/11/2024,NSW Typical Summer,-1 +17/12/2024,NSW Typical Summer,0 +18/12/2024,NSW Typical Summer,-1 +27/12/2024,NSW Typical Summer,0 +28/12/2024,NSW Typical Summer,-1 +28/01/2025,NSW Typical Summer,0 +29/01/2025,NSW Typical Summer,-1 +28/02/2025,NSW Typical Summer,0 +01/03/2025,NSW Typical Summer,-1 +01/04/2025,NSW Typical Summer,0 +01/11/2025,NSW Typical Summer,-1 +14/11/2025,NSW Typical Summer,0 +15/11/2025,NSW Typical Summer,-1 +21/11/2025,NSW Typical Summer,0 +22/11/2025,NSW Typical Summer,-1 +23/11/2025,NSW Typical Summer,0 +24/11/2025,NSW Typical Summer,-1 +25/01/2026,NSW Typical Summer,0 +26/01/2026,NSW Typical Summer,-1 +01/03/2026,NSW Typical Summer,0 +02/03/2026,NSW Typical Summer,-1 +01/04/2026,NSW Typical Summer,0 +01/11/2026,NSW Typical Summer,-1 +01/01/2027,NSW Typical Summer,0 +02/01/2027,NSW Typical Summer,-1 +31/01/2027,NSW Typical Summer,0 +02/02/2027,NSW Typical Summer,-1 +05/02/2027,NSW Typical Summer,0 +06/02/2027,NSW Typical Summer,-1 +19/02/2027,NSW Typical Summer,0 +20/02/2027,NSW Typical Summer,-1 +01/04/2027,NSW Typical Summer,0 +01/11/2027,NSW Typical Summer,-1 +08/11/2027,NSW Typical Summer,0 +10/11/2027,NSW Typical Summer,-1 +14/11/2027,NSW Typical Summer,0 +15/11/2027,NSW Typical Summer,-1 +20/11/2027,NSW Typical Summer,0 +21/11/2027,NSW Typical Summer,-1 +04/01/2028,NSW Typical Summer,0 +05/01/2028,NSW Typical Summer,-1 +01/04/2028,NSW Typical Summer,0 +01/11/2028,NSW Typical Summer,-1 +30/11/2028,NSW Typical Summer,0 +02/12/2028,NSW Typical Summer,-1 +08/01/2029,NSW Typical Summer,0 +09/01/2029,NSW Typical Summer,-1 +18/01/2029,NSW Typical Summer,0 +19/01/2029,NSW Typical Summer,-1 +22/01/2029,NSW Typical Summer,0 +23/01/2029,NSW Typical Summer,-1 +01/04/2029,NSW Typical Summer,0 +01/11/2029,NSW Typical Summer,-1 +08/11/2029,NSW Typical Summer,0 +09/11/2029,NSW Typical Summer,-1 +20/12/2029,NSW Typical Summer,0 +21/12/2029,NSW Typical Summer,-1 +22/12/2029,NSW Typical Summer,0 +24/12/2029,NSW Typical Summer,-1 +02/01/2030,NSW Typical Summer,0 +03/01/2030,NSW Typical Summer,-1 +01/04/2030,NSW Typical Summer,0 +01/11/2030,NSW Typical Summer,-1 +14/11/2030,NSW Typical Summer,0 +15/11/2030,NSW Typical Summer,-1 +21/11/2030,NSW Typical Summer,0 +22/11/2030,NSW Typical Summer,-1 +23/11/2030,NSW Typical Summer,0 +24/11/2030,NSW Typical Summer,-1 +25/01/2031,NSW Typical Summer,0 +26/01/2031,NSW Typical Summer,-1 +01/03/2031,NSW Typical Summer,0 +02/03/2031,NSW Typical Summer,-1 +01/04/2031,NSW Typical Summer,0 +01/11/2031,NSW Typical Summer,-1 +19/11/2031,NSW Typical Summer,0 +21/11/2031,NSW Typical Summer,-1 +14/01/2032,NSW Typical Summer,0 +15/01/2032,NSW Typical Summer,-1 +20/01/2032,NSW Typical Summer,0 +21/01/2032,NSW Typical Summer,-1 +25/02/2032,NSW Typical Summer,0 +26/02/2032,NSW Typical Summer,-1 +01/04/2032,NSW Typical Summer,0 +01/11/2032,NSW Typical Summer,-1 +11/01/2033,NSW Typical Summer,0 +12/01/2033,NSW Typical Summer,-1 +30/01/2033,NSW Typical Summer,0 +01/02/2033,NSW Typical Summer,-1 +05/02/2033,NSW Typical Summer,0 +06/02/2033,NSW Typical Summer,-1 +10/02/2033,NSW Typical Summer,0 +12/02/2033,NSW Typical Summer,-1 +01/04/2033,NSW Typical Summer,0 +01/11/2033,NSW Typical Summer,-1 +14/12/2033,NSW Typical Summer,0 +15/12/2033,NSW Typical Summer,-1 +20/12/2033,NSW Typical Summer,0 +21/12/2033,NSW Typical Summer,-1 +24/12/2033,NSW Typical Summer,0 +25/12/2033,NSW Typical Summer,-1 +07/01/2034,NSW Typical Summer,0 +08/01/2034,NSW Typical Summer,-1 +18/03/2034,NSW Typical Summer,0 +19/03/2034,NSW Typical Summer,-1 +01/04/2034,NSW Typical Summer,0 +01/11/2034,NSW Typical Summer,-1 +28/12/2034,NSW Typical Summer,0 +30/12/2034,NSW Typical Summer,-1 +05/01/2035,NSW Typical Summer,0 +06/01/2035,NSW Typical Summer,-1 +18/01/2035,NSW Typical Summer,0 +19/01/2035,NSW Typical Summer,-1 +31/01/2035,NSW Typical Summer,0 +01/02/2035,NSW Typical Summer,-1 +01/04/2035,NSW Typical Summer,0 +01/11/2035,NSW Typical Summer,-1 +19/12/2035,NSW Typical Summer,0 +20/12/2035,NSW Typical Summer,-1 +31/12/2035,NSW Typical Summer,0 +01/01/2036,NSW Typical Summer,-1 +04/01/2036,NSW Typical Summer,0 +05/01/2036,NSW Typical Summer,-1 +23/01/2036,NSW Typical Summer,0 +24/01/2036,NSW Typical Summer,-1 +01/02/2036,NSW Typical Summer,0 +02/02/2036,NSW Typical Summer,-1 +01/04/2036,NSW Typical Summer,0 +01/11/2036,NSW Typical Summer,-1 +16/11/2036,NSW Typical Summer,0 +17/11/2036,NSW Typical Summer,-1 +28/11/2036,NSW Typical Summer,0 +30/11/2036,NSW Typical Summer,-1 +24/01/2037,NSW Typical Summer,0 +25/01/2037,NSW Typical Summer,-1 +26/01/2037,NSW Typical Summer,0 +27/01/2037,NSW Typical Summer,-1 +01/04/2037,NSW Typical Summer,0 +01/11/2037,NSW Typical Summer,-1 +18/12/2037,NSW Typical Summer,0 +20/12/2037,NSW Typical Summer,-1 +01/02/2038,NSW Typical Summer,0 +02/02/2038,NSW Typical Summer,-1 +10/02/2038,NSW Typical Summer,0 +11/02/2038,NSW Typical Summer,-1 +17/02/2038,NSW Typical Summer,0 +18/02/2038,NSW Typical Summer,-1 +01/04/2038,NSW Typical Summer,0 +01/11/2038,NSW Typical Summer,-1 +26/01/2039,NSW Typical Summer,0 +27/01/2039,NSW Typical Summer,-1 +11/02/2039,NSW Typical Summer,0 +12/02/2039,NSW Typical Summer,-1 +06/03/2039,NSW Typical Summer,0 +07/03/2039,NSW Typical Summer,-1 +16/03/2039,NSW Typical Summer,0 +17/03/2039,NSW Typical Summer,-1 +19/03/2039,NSW Typical Summer,0 +20/03/2039,NSW Typical Summer,-1 +01/04/2039,NSW Typical Summer,0 +01/11/2039,NSW Typical Summer,-1 +09/12/2039,NSW Typical Summer,0 +10/12/2039,NSW Typical Summer,-1 +14/12/2039,NSW Typical Summer,0 +15/12/2039,NSW Typical Summer,-1 +21/01/2040,NSW Typical Summer,0 +22/01/2040,NSW Typical Summer,-1 +26/01/2040,NSW Typical Summer,0 +27/01/2040,NSW Typical Summer,-1 +29/02/2040,NSW Typical Summer,0 +01/03/2040,NSW Typical Summer,-1 +01/04/2040,NSW Typical Summer,0 +01/11/2040,NSW Typical Summer,-1 +27/11/2040,NSW Typical Summer,0 +28/11/2040,NSW Typical Summer,-1 +17/12/2040,NSW Typical Summer,0 +18/12/2040,NSW Typical Summer,-1 +27/12/2040,NSW Typical Summer,0 +28/12/2040,NSW Typical Summer,-1 +28/01/2041,NSW Typical Summer,0 +29/01/2041,NSW Typical Summer,-1 +28/02/2041,NSW Typical Summer,0 +01/03/2041,NSW Typical Summer,-1 +01/04/2041,NSW Typical Summer,0 +01/11/2041,NSW Typical Summer,-1 +14/11/2041,NSW Typical Summer,0 +15/11/2041,NSW Typical Summer,-1 +21/11/2041,NSW Typical Summer,0 +22/11/2041,NSW Typical Summer,-1 +23/11/2041,NSW Typical Summer,0 +24/11/2041,NSW Typical Summer,-1 +25/01/2042,NSW Typical Summer,0 +26/01/2042,NSW Typical Summer,-1 +01/03/2042,NSW Typical Summer,0 +02/03/2042,NSW Typical Summer,-1 +01/04/2042,NSW Typical Summer,0 +01/11/2042,NSW Typical Summer,-1 +01/01/2043,NSW Typical Summer,0 +02/01/2043,NSW Typical Summer,-1 +31/01/2043,NSW Typical Summer,0 +02/02/2043,NSW Typical Summer,-1 +05/02/2043,NSW Typical Summer,0 +06/02/2043,NSW Typical Summer,-1 +19/02/2043,NSW Typical Summer,0 +20/02/2043,NSW Typical Summer,-1 +01/04/2043,NSW Typical Summer,0 +01/11/2043,NSW Typical Summer,-1 +08/11/2043,NSW Typical Summer,0 +10/11/2043,NSW Typical Summer,-1 +14/11/2043,NSW Typical Summer,0 +15/11/2043,NSW Typical Summer,-1 +20/11/2043,NSW Typical Summer,0 +21/11/2043,NSW Typical Summer,-1 +04/01/2044,NSW Typical Summer,0 +05/01/2044,NSW Typical Summer,-1 +01/04/2044,NSW Typical Summer,0 +01/11/2044,NSW Typical Summer,-1 +30/11/2044,NSW Typical Summer,0 +02/12/2044,NSW Typical Summer,-1 +08/01/2045,NSW Typical Summer,0 +09/01/2045,NSW Typical Summer,-1 +18/01/2045,NSW Typical Summer,0 +19/01/2045,NSW Typical Summer,-1 +22/01/2045,NSW Typical Summer,0 +23/01/2045,NSW Typical Summer,-1 +01/04/2045,NSW Typical Summer,0 +01/11/2045,NSW Typical Summer,-1 +08/11/2045,NSW Typical Summer,0 +09/11/2045,NSW Typical Summer,-1 +20/12/2045,NSW Typical Summer,0 +21/12/2045,NSW Typical Summer,-1 +22/12/2045,NSW Typical Summer,0 +24/12/2045,NSW Typical Summer,-1 +02/01/2046,NSW Typical Summer,0 +03/01/2046,NSW Typical Summer,-1 +01/04/2046,NSW Typical Summer,0 +01/11/2046,NSW Typical Summer,-1 +14/11/2046,NSW Typical Summer,0 +15/11/2046,NSW Typical Summer,-1 +21/11/2046,NSW Typical Summer,0 +22/11/2046,NSW Typical Summer,-1 +23/11/2046,NSW Typical Summer,0 +24/11/2046,NSW Typical Summer,-1 +25/01/2047,NSW Typical Summer,0 +26/01/2047,NSW Typical Summer,-1 +01/03/2047,NSW Typical Summer,0 +02/03/2047,NSW Typical Summer,-1 +01/04/2047,NSW Typical Summer,0 +01/11/2047,NSW Typical Summer,-1 +19/11/2047,NSW Typical Summer,0 +21/11/2047,NSW Typical Summer,-1 +14/01/2048,NSW Typical Summer,0 +15/01/2048,NSW Typical Summer,-1 +20/01/2048,NSW Typical Summer,0 +21/01/2048,NSW Typical Summer,-1 +25/02/2048,NSW Typical Summer,0 +26/02/2048,NSW Typical Summer,-1 +01/04/2048,NSW Typical Summer,0 +01/11/2048,NSW Typical Summer,-1 +11/01/2049,NSW Typical Summer,0 +12/01/2049,NSW Typical Summer,-1 +30/01/2049,NSW Typical Summer,0 +01/02/2049,NSW Typical Summer,-1 +05/02/2049,NSW Typical Summer,0 +06/02/2049,NSW Typical Summer,-1 +10/02/2049,NSW Typical Summer,0 +12/02/2049,NSW Typical Summer,-1 +01/04/2049,NSW Typical Summer,0 +01/11/2049,NSW Typical Summer,-1 +14/12/2049,NSW Typical Summer,0 +15/12/2049,NSW Typical Summer,-1 +20/12/2049,NSW Typical Summer,0 +21/12/2049,NSW Typical Summer,-1 +24/12/2049,NSW Typical Summer,0 +25/12/2049,NSW Typical Summer,-1 +07/01/2050,NSW Typical Summer,0 +08/01/2050,NSW Typical Summer,-1 +18/03/2050,NSW Typical Summer,0 +19/03/2050,NSW Typical Summer,-1 +01/04/2050,NSW Typical Summer,0 +01/11/2050,NSW Typical Summer,-1 +28/12/2050,NSW Typical Summer,0 +30/12/2050,NSW Typical Summer,-1 +05/01/2051,NSW Typical Summer,0 +06/01/2051,NSW Typical Summer,-1 +18/01/2051,NSW Typical Summer,0 +19/01/2051,NSW Typical Summer,-1 +31/01/2051,NSW Typical Summer,0 +01/02/2051,NSW Typical Summer,-1 +01/04/2051,NSW Typical Summer,0 +01/11/2051,NSW Typical Summer,-1 +19/12/2051,NSW Typical Summer,0 +20/12/2051,NSW Typical Summer,-1 +31/12/2051,NSW Typical Summer,0 +01/01/2052,NSW Typical Summer,-1 +04/01/2052,NSW Typical Summer,0 +05/01/2052,NSW Typical Summer,-1 +23/01/2052,NSW Typical Summer,0 +24/01/2052,NSW Typical Summer,-1 +01/02/2052,NSW Typical Summer,0 +02/02/2052,NSW Typical Summer,-1 +01/04/2052,NSW Typical Summer,0 +01/11/2052,NSW Typical Summer,-1 +16/11/2052,NSW Typical Summer,0 +17/11/2052,NSW Typical Summer,-1 +28/11/2052,NSW Typical Summer,0 +30/11/2052,NSW Typical Summer,-1 +24/01/2053,NSW Typical Summer,0 +25/01/2053,NSW Typical Summer,-1 +26/01/2053,NSW Typical Summer,0 +27/01/2053,NSW Typical Summer,-1 +01/04/2053,NSW Typical Summer,0 +01/11/2053,NSW Typical Summer,-1 +18/12/2053,NSW Typical Summer,0 +20/12/2053,NSW Typical Summer,-1 +01/02/2054,NSW Typical Summer,0 +02/02/2054,NSW Typical Summer,-1 +10/02/2054,NSW Typical Summer,0 +11/02/2054,NSW Typical Summer,-1 +17/02/2054,NSW Typical Summer,0 +18/02/2054,NSW Typical Summer,-1 +01/04/2054,NSW Typical Summer,0 +01/11/2054,NSW Typical Summer,-1 +26/01/2055,NSW Typical Summer,0 +27/01/2055,NSW Typical Summer,-1 +11/02/2055,NSW Typical Summer,0 +12/02/2055,NSW Typical Summer,-1 +06/03/2055,NSW Typical Summer,0 +07/03/2055,NSW Typical Summer,-1 +16/03/2055,NSW Typical Summer,0 +17/03/2055,NSW Typical Summer,-1 +19/03/2055,NSW Typical Summer,0 +20/03/2055,NSW Typical Summer,-1 +01/04/2055,NSW Typical Summer,0 +01/11/2055,NSW Typical Summer,-1 +09/12/2055,NSW Typical Summer,0 +10/12/2055,NSW Typical Summer,-1 +14/12/2055,NSW Typical Summer,0 +15/12/2055,NSW Typical Summer,-1 +21/01/2056,NSW Typical Summer,0 +22/01/2056,NSW Typical Summer,-1 +26/01/2056,NSW Typical Summer,0 +27/01/2056,NSW Typical Summer,-1 +29/02/2056,NSW Typical Summer,0 +01/03/2056,NSW Typical Summer,-1 +01/04/2056,NSW Typical Summer,0 +01/11/2056,NSW Typical Summer,-1 +27/11/2056,NSW Typical Summer,0 +28/11/2056,NSW Typical Summer,-1 +17/12/2056,NSW Typical Summer,0 +18/12/2056,NSW Typical Summer,-1 +27/12/2056,NSW Typical Summer,0 +28/12/2056,NSW Typical Summer,-1 +28/01/2057,NSW Typical Summer,0 +29/01/2057,NSW Typical Summer,-1 +28/02/2057,NSW Typical Summer,0 +01/03/2057,NSW Typical Summer,-1 +01/04/2057,NSW Typical Summer,0 +01/11/2057,NSW Typical Summer,-1 +14/11/2057,NSW Typical Summer,0 +15/11/2057,NSW Typical Summer,-1 +21/11/2057,NSW Typical Summer,0 +22/11/2057,NSW Typical Summer,-1 +23/11/2057,NSW Typical Summer,0 +24/11/2057,NSW Typical Summer,-1 +25/01/2058,NSW Typical Summer,0 +26/01/2058,NSW Typical Summer,-1 +01/03/2058,NSW Typical Summer,0 +02/03/2058,NSW Typical Summer,-1 +01/04/2058,NSW Typical Summer,0 +30/06/2021,NSW Winter,-1 +01/11/2021,NSW Winter,0 +01/04/2022,NSW Winter,-1 +01/11/2022,NSW Winter,0 +01/04/2023,NSW Winter,-1 +01/11/2023,NSW Winter,0 +01/04/2024,NSW Winter,-1 +01/11/2024,NSW Winter,0 +01/04/2025,NSW Winter,-1 +01/11/2025,NSW Winter,0 +01/04/2026,NSW Winter,-1 +01/11/2026,NSW Winter,0 +01/04/2027,NSW Winter,-1 +01/11/2027,NSW Winter,0 +01/04/2028,NSW Winter,-1 +01/11/2028,NSW Winter,0 +01/04/2029,NSW Winter,-1 +01/11/2029,NSW Winter,0 +01/04/2030,NSW Winter,-1 +01/11/2030,NSW Winter,0 +01/04/2031,NSW Winter,-1 +01/11/2031,NSW Winter,0 +01/04/2032,NSW Winter,-1 +01/11/2032,NSW Winter,0 +01/04/2033,NSW Winter,-1 +01/11/2033,NSW Winter,0 +01/04/2034,NSW Winter,-1 +01/11/2034,NSW Winter,0 +01/04/2035,NSW Winter,-1 +01/11/2035,NSW Winter,0 +01/04/2036,NSW Winter,-1 +01/11/2036,NSW Winter,0 +01/04/2037,NSW Winter,-1 +01/11/2037,NSW Winter,0 +01/04/2038,NSW Winter,-1 +01/11/2038,NSW Winter,0 +01/04/2039,NSW Winter,-1 +01/11/2039,NSW Winter,0 +01/04/2040,NSW Winter,-1 +01/11/2040,NSW Winter,0 +01/04/2041,NSW Winter,-1 +01/11/2041,NSW Winter,0 +01/04/2042,NSW Winter,-1 +01/11/2042,NSW Winter,0 +01/04/2043,NSW Winter,-1 +01/11/2043,NSW Winter,0 +01/04/2044,NSW Winter,-1 +01/11/2044,NSW Winter,0 +01/04/2045,NSW Winter,-1 +01/11/2045,NSW Winter,0 +01/04/2046,NSW Winter,-1 +01/11/2046,NSW Winter,0 +01/04/2047,NSW Winter,-1 +01/11/2047,NSW Winter,0 +01/04/2048,NSW Winter,-1 +01/11/2048,NSW Winter,0 +01/04/2049,NSW Winter,-1 +01/11/2049,NSW Winter,0 +01/04/2050,NSW Winter,-1 +01/11/2050,NSW Winter,0 +01/04/2051,NSW Winter,-1 +01/11/2051,NSW Winter,0 +01/04/2052,NSW Winter,-1 +01/11/2052,NSW Winter,0 +01/04/2053,NSW Winter,-1 +01/11/2053,NSW Winter,0 +01/04/2054,NSW Winter,-1 +01/11/2054,NSW Winter,0 +01/04/2055,NSW Winter,-1 +01/11/2055,NSW Winter,0 +01/04/2056,NSW Winter,-1 +01/11/2056,NSW Winter,0 +01/04/2057,NSW Winter,-1 +01/11/2057,NSW Winter,0 +01/04/2058,NSW Winter,-1 +30/06/2021,QLD Hot Day,0 +20/12/2021,QLD Hot Day,-1 +21/12/2021,QLD Hot Day,0 +01/02/2022,QLD Hot Day,-1 +03/02/2022,QLD Hot Day,0 +08/03/2022,QLD Hot Day,-1 +10/03/2022,QLD Hot Day,0 +06/12/2022,QLD Hot Day,-1 +07/12/2022,QLD Hot Day,0 +03/02/2023,QLD Hot Day,-1 +04/02/2023,QLD Hot Day,0 +12/02/2023,QLD Hot Day,-1 +14/02/2023,QLD Hot Day,0 +16/03/2023,QLD Hot Day,-1 +18/03/2023,QLD Hot Day,0 +15/12/2023,QLD Hot Day,-1 +16/12/2023,QLD Hot Day,0 +28/12/2023,QLD Hot Day,-1 +30/12/2023,QLD Hot Day,0 +22/01/2024,QLD Hot Day,-1 +23/01/2024,QLD Hot Day,0 +27/01/2024,QLD Hot Day,-1 +28/01/2024,QLD Hot Day,0 +08/12/2024,QLD Hot Day,-1 +09/12/2024,QLD Hot Day,0 +16/01/2025,QLD Hot Day,-1 +17/01/2025,QLD Hot Day,0 +22/01/2025,QLD Hot Day,-1 +23/01/2025,QLD Hot Day,0 +24/01/2025,QLD Hot Day,-1 +25/01/2025,QLD Hot Day,0 +16/02/2025,QLD Hot Day,-1 +17/02/2025,QLD Hot Day,0 +16/11/2025,QLD Hot Day,-1 +17/11/2025,QLD Hot Day,0 +17/12/2025,QLD Hot Day,-1 +18/12/2025,QLD Hot Day,0 +30/12/2025,QLD Hot Day,-1 +31/12/2025,QLD Hot Day,0 +15/01/2026,QLD Hot Day,-1 +16/01/2026,QLD Hot Day,0 +17/01/2026,QLD Hot Day,-1 +19/01/2026,QLD Hot Day,0 +25/01/2026,QLD Hot Day,-1 +26/01/2026,QLD Hot Day,0 +05/03/2026,QLD Hot Day,-1 +06/03/2026,QLD Hot Day,0 +19/03/2026,QLD Hot Day,-1 +20/03/2026,QLD Hot Day,0 +18/01/2027,QLD Hot Day,-1 +19/01/2027,QLD Hot Day,0 +20/02/2027,QLD Hot Day,-1 +22/02/2027,QLD Hot Day,0 +01/03/2027,QLD Hot Day,-1 +02/03/2027,QLD Hot Day,0 +22/03/2027,QLD Hot Day,-1 +23/03/2027,QLD Hot Day,0 +15/11/2027,QLD Hot Day,-1 +16/11/2027,QLD Hot Day,0 +27/11/2027,QLD Hot Day,-1 +28/11/2027,QLD Hot Day,0 +09/01/2028,QLD Hot Day,-1 +10/01/2028,QLD Hot Day,0 +11/01/2028,QLD Hot Day,-1 +12/01/2028,QLD Hot Day,0 +06/02/2028,QLD Hot Day,-1 +07/02/2028,QLD Hot Day,0 +04/12/2028,QLD Hot Day,-1 +05/12/2028,QLD Hot Day,0 +02/01/2029,QLD Hot Day,-1 +03/01/2029,QLD Hot Day,0 +12/01/2029,QLD Hot Day,-1 +14/01/2029,QLD Hot Day,0 +19/01/2029,QLD Hot Day,-1 +20/01/2029,QLD Hot Day,0 +05/12/2029,QLD Hot Day,-1 +06/12/2029,QLD Hot Day,0 +29/12/2029,QLD Hot Day,-1 +30/12/2029,QLD Hot Day,0 +03/01/2030,QLD Hot Day,-1 +05/01/2030,QLD Hot Day,0 +22/01/2030,QLD Hot Day,-1 +23/01/2030,QLD Hot Day,0 +16/11/2030,QLD Hot Day,-1 +17/11/2030,QLD Hot Day,0 +17/12/2030,QLD Hot Day,-1 +18/12/2030,QLD Hot Day,0 +30/12/2030,QLD Hot Day,-1 +31/12/2030,QLD Hot Day,0 +15/01/2031,QLD Hot Day,-1 +16/01/2031,QLD Hot Day,0 +17/01/2031,QLD Hot Day,-1 +19/01/2031,QLD Hot Day,0 +25/01/2031,QLD Hot Day,-1 +26/01/2031,QLD Hot Day,0 +05/03/2031,QLD Hot Day,-1 +06/03/2031,QLD Hot Day,0 +19/03/2031,QLD Hot Day,-1 +20/03/2031,QLD Hot Day,0 +21/11/2031,QLD Hot Day,-1 +22/11/2031,QLD Hot Day,0 +29/01/2032,QLD Hot Day,-1 +30/01/2032,QLD Hot Day,0 +01/02/2032,QLD Hot Day,-1 +03/02/2032,QLD Hot Day,0 +16/02/2032,QLD Hot Day,-1 +17/02/2032,QLD Hot Day,0 +27/02/2032,QLD Hot Day,-1 +28/02/2032,QLD Hot Day,0 +05/11/2032,QLD Hot Day,-1 +06/11/2032,QLD Hot Day,0 +13/11/2032,QLD Hot Day,-1 +14/11/2032,QLD Hot Day,0 +21/12/2032,QLD Hot Day,-1 +22/12/2032,QLD Hot Day,0 +01/01/2033,QLD Hot Day,-1 +02/01/2033,QLD Hot Day,0 +12/01/2033,QLD Hot Day,-1 +13/01/2033,QLD Hot Day,0 +14/01/2033,QLD Hot Day,-1 +15/01/2033,QLD Hot Day,0 +18/01/2033,QLD Hot Day,-1 +19/01/2033,QLD Hot Day,0 +11/02/2033,QLD Hot Day,-1 +13/02/2033,QLD Hot Day,0 +25/12/2033,QLD Hot Day,-1 +26/12/2033,QLD Hot Day,0 +13/01/2034,QLD Hot Day,-1 +15/01/2034,QLD Hot Day,0 +31/01/2034,QLD Hot Day,-1 +01/02/2034,QLD Hot Day,0 +11/02/2034,QLD Hot Day,-1 +12/02/2034,QLD Hot Day,0 +28/11/2034,QLD Hot Day,-1 +29/11/2034,QLD Hot Day,0 +21/12/2034,QLD Hot Day,-1 +22/12/2034,QLD Hot Day,0 +11/03/2035,QLD Hot Day,-1 +13/03/2035,QLD Hot Day,0 +24/03/2035,QLD Hot Day,-1 +25/03/2035,QLD Hot Day,0 +08/11/2035,QLD Hot Day,-1 +09/11/2035,QLD Hot Day,0 +16/11/2035,QLD Hot Day,-1 +17/11/2035,QLD Hot Day,0 +05/12/2035,QLD Hot Day,-1 +08/12/2035,QLD Hot Day,0 +16/12/2035,QLD Hot Day,-1 +17/12/2035,QLD Hot Day,0 +03/02/2036,QLD Hot Day,-1 +04/02/2036,QLD Hot Day,0 +06/12/2036,QLD Hot Day,-1 +08/12/2036,QLD Hot Day,0 +16/01/2037,QLD Hot Day,-1 +17/01/2037,QLD Hot Day,0 +07/02/2037,QLD Hot Day,-1 +08/02/2037,QLD Hot Day,0 +22/02/2037,QLD Hot Day,-1 +23/02/2037,QLD Hot Day,0 +20/12/2037,QLD Hot Day,-1 +21/12/2037,QLD Hot Day,0 +01/02/2038,QLD Hot Day,-1 +03/02/2038,QLD Hot Day,0 +08/03/2038,QLD Hot Day,-1 +10/03/2038,QLD Hot Day,0 +06/12/2038,QLD Hot Day,-1 +07/12/2038,QLD Hot Day,0 +03/02/2039,QLD Hot Day,-1 +04/02/2039,QLD Hot Day,0 +12/02/2039,QLD Hot Day,-1 +14/02/2039,QLD Hot Day,0 +16/03/2039,QLD Hot Day,-1 +18/03/2039,QLD Hot Day,0 +15/12/2039,QLD Hot Day,-1 +16/12/2039,QLD Hot Day,0 +28/12/2039,QLD Hot Day,-1 +30/12/2039,QLD Hot Day,0 +22/01/2040,QLD Hot Day,-1 +23/01/2040,QLD Hot Day,0 +27/01/2040,QLD Hot Day,-1 +28/01/2040,QLD Hot Day,0 +08/12/2040,QLD Hot Day,-1 +09/12/2040,QLD Hot Day,0 +16/01/2041,QLD Hot Day,-1 +17/01/2041,QLD Hot Day,0 +22/01/2041,QLD Hot Day,-1 +23/01/2041,QLD Hot Day,0 +24/01/2041,QLD Hot Day,-1 +25/01/2041,QLD Hot Day,0 +16/02/2041,QLD Hot Day,-1 +17/02/2041,QLD Hot Day,0 +16/11/2041,QLD Hot Day,-1 +17/11/2041,QLD Hot Day,0 +17/12/2041,QLD Hot Day,-1 +18/12/2041,QLD Hot Day,0 +30/12/2041,QLD Hot Day,-1 +31/12/2041,QLD Hot Day,0 +15/01/2042,QLD Hot Day,-1 +16/01/2042,QLD Hot Day,0 +17/01/2042,QLD Hot Day,-1 +19/01/2042,QLD Hot Day,0 +25/01/2042,QLD Hot Day,-1 +26/01/2042,QLD Hot Day,0 +05/03/2042,QLD Hot Day,-1 +06/03/2042,QLD Hot Day,0 +19/03/2042,QLD Hot Day,-1 +20/03/2042,QLD Hot Day,0 +18/01/2043,QLD Hot Day,-1 +19/01/2043,QLD Hot Day,0 +20/02/2043,QLD Hot Day,-1 +22/02/2043,QLD Hot Day,0 +01/03/2043,QLD Hot Day,-1 +02/03/2043,QLD Hot Day,0 +22/03/2043,QLD Hot Day,-1 +23/03/2043,QLD Hot Day,0 +15/11/2043,QLD Hot Day,-1 +16/11/2043,QLD Hot Day,0 +27/11/2043,QLD Hot Day,-1 +28/11/2043,QLD Hot Day,0 +09/01/2044,QLD Hot Day,-1 +10/01/2044,QLD Hot Day,0 +11/01/2044,QLD Hot Day,-1 +12/01/2044,QLD Hot Day,0 +06/02/2044,QLD Hot Day,-1 +07/02/2044,QLD Hot Day,0 +04/12/2044,QLD Hot Day,-1 +05/12/2044,QLD Hot Day,0 +02/01/2045,QLD Hot Day,-1 +03/01/2045,QLD Hot Day,0 +12/01/2045,QLD Hot Day,-1 +14/01/2045,QLD Hot Day,0 +19/01/2045,QLD Hot Day,-1 +20/01/2045,QLD Hot Day,0 +05/12/2045,QLD Hot Day,-1 +06/12/2045,QLD Hot Day,0 +29/12/2045,QLD Hot Day,-1 +30/12/2045,QLD Hot Day,0 +03/01/2046,QLD Hot Day,-1 +05/01/2046,QLD Hot Day,0 +22/01/2046,QLD Hot Day,-1 +23/01/2046,QLD Hot Day,0 +16/11/2046,QLD Hot Day,-1 +17/11/2046,QLD Hot Day,0 +17/12/2046,QLD Hot Day,-1 +18/12/2046,QLD Hot Day,0 +30/12/2046,QLD Hot Day,-1 +31/12/2046,QLD Hot Day,0 +15/01/2047,QLD Hot Day,-1 +16/01/2047,QLD Hot Day,0 +17/01/2047,QLD Hot Day,-1 +19/01/2047,QLD Hot Day,0 +25/01/2047,QLD Hot Day,-1 +26/01/2047,QLD Hot Day,0 +05/03/2047,QLD Hot Day,-1 +06/03/2047,QLD Hot Day,0 +19/03/2047,QLD Hot Day,-1 +20/03/2047,QLD Hot Day,0 +21/11/2047,QLD Hot Day,-1 +22/11/2047,QLD Hot Day,0 +29/01/2048,QLD Hot Day,-1 +30/01/2048,QLD Hot Day,0 +01/02/2048,QLD Hot Day,-1 +03/02/2048,QLD Hot Day,0 +16/02/2048,QLD Hot Day,-1 +17/02/2048,QLD Hot Day,0 +27/02/2048,QLD Hot Day,-1 +28/02/2048,QLD Hot Day,0 +05/11/2048,QLD Hot Day,-1 +06/11/2048,QLD Hot Day,0 +13/11/2048,QLD Hot Day,-1 +14/11/2048,QLD Hot Day,0 +21/12/2048,QLD Hot Day,-1 +22/12/2048,QLD Hot Day,0 +01/01/2049,QLD Hot Day,-1 +02/01/2049,QLD Hot Day,0 +12/01/2049,QLD Hot Day,-1 +13/01/2049,QLD Hot Day,0 +14/01/2049,QLD Hot Day,-1 +15/01/2049,QLD Hot Day,0 +18/01/2049,QLD Hot Day,-1 +19/01/2049,QLD Hot Day,0 +11/02/2049,QLD Hot Day,-1 +13/02/2049,QLD Hot Day,0 +25/12/2049,QLD Hot Day,-1 +26/12/2049,QLD Hot Day,0 +13/01/2050,QLD Hot Day,-1 +15/01/2050,QLD Hot Day,0 +31/01/2050,QLD Hot Day,-1 +01/02/2050,QLD Hot Day,0 +11/02/2050,QLD Hot Day,-1 +12/02/2050,QLD Hot Day,0 +28/11/2050,QLD Hot Day,-1 +29/11/2050,QLD Hot Day,0 +21/12/2050,QLD Hot Day,-1 +22/12/2050,QLD Hot Day,0 +11/03/2051,QLD Hot Day,-1 +13/03/2051,QLD Hot Day,0 +24/03/2051,QLD Hot Day,-1 +25/03/2051,QLD Hot Day,0 +08/11/2051,QLD Hot Day,-1 +09/11/2051,QLD Hot Day,0 +16/11/2051,QLD Hot Day,-1 +17/11/2051,QLD Hot Day,0 +05/12/2051,QLD Hot Day,-1 +08/12/2051,QLD Hot Day,0 +16/12/2051,QLD Hot Day,-1 +17/12/2051,QLD Hot Day,0 +03/02/2052,QLD Hot Day,-1 +04/02/2052,QLD Hot Day,0 +06/12/2052,QLD Hot Day,-1 +08/12/2052,QLD Hot Day,0 +16/01/2053,QLD Hot Day,-1 +17/01/2053,QLD Hot Day,0 +07/02/2053,QLD Hot Day,-1 +08/02/2053,QLD Hot Day,0 +22/02/2053,QLD Hot Day,-1 +23/02/2053,QLD Hot Day,0 +20/12/2053,QLD Hot Day,-1 +21/12/2053,QLD Hot Day,0 +01/02/2054,QLD Hot Day,-1 +03/02/2054,QLD Hot Day,0 +08/03/2054,QLD Hot Day,-1 +10/03/2054,QLD Hot Day,0 +06/12/2054,QLD Hot Day,-1 +07/12/2054,QLD Hot Day,0 +03/02/2055,QLD Hot Day,-1 +04/02/2055,QLD Hot Day,0 +12/02/2055,QLD Hot Day,-1 +14/02/2055,QLD Hot Day,0 +16/03/2055,QLD Hot Day,-1 +18/03/2055,QLD Hot Day,0 +15/12/2055,QLD Hot Day,-1 +16/12/2055,QLD Hot Day,0 +28/12/2055,QLD Hot Day,-1 +30/12/2055,QLD Hot Day,0 +22/01/2056,QLD Hot Day,-1 +23/01/2056,QLD Hot Day,0 +27/01/2056,QLD Hot Day,-1 +28/01/2056,QLD Hot Day,0 +08/12/2056,QLD Hot Day,-1 +09/12/2056,QLD Hot Day,0 +16/01/2057,QLD Hot Day,-1 +17/01/2057,QLD Hot Day,0 +22/01/2057,QLD Hot Day,-1 +23/01/2057,QLD Hot Day,0 +24/01/2057,QLD Hot Day,-1 +25/01/2057,QLD Hot Day,0 +16/02/2057,QLD Hot Day,-1 +17/02/2057,QLD Hot Day,0 +16/11/2057,QLD Hot Day,-1 +17/11/2057,QLD Hot Day,0 +17/12/2057,QLD Hot Day,-1 +18/12/2057,QLD Hot Day,0 +30/12/2057,QLD Hot Day,-1 +31/12/2057,QLD Hot Day,0 +15/01/2058,QLD Hot Day,-1 +16/01/2058,QLD Hot Day,0 +17/01/2058,QLD Hot Day,-1 +19/01/2058,QLD Hot Day,0 +25/01/2058,QLD Hot Day,-1 +26/01/2058,QLD Hot Day,0 +05/03/2058,QLD Hot Day,-1 +06/03/2058,QLD Hot Day,0 +19/03/2058,QLD Hot Day,-1 +20/03/2058,QLD Hot Day,0 +30/06/2021,QLD Typical Summer,0 +01/11/2021,QLD Typical Summer,-1 +20/12/2021,QLD Typical Summer,0 +21/12/2021,QLD Typical Summer,-1 +01/02/2022,QLD Typical Summer,0 +03/02/2022,QLD Typical Summer,-1 +08/03/2022,QLD Typical Summer,0 +10/03/2022,QLD Typical Summer,-1 +01/04/2022,QLD Typical Summer,0 +01/11/2022,QLD Typical Summer,-1 +06/12/2022,QLD Typical Summer,0 +07/12/2022,QLD Typical Summer,-1 +03/02/2023,QLD Typical Summer,0 +04/02/2023,QLD Typical Summer,-1 +12/02/2023,QLD Typical Summer,0 +14/02/2023,QLD Typical Summer,-1 +16/03/2023,QLD Typical Summer,0 +18/03/2023,QLD Typical Summer,-1 +01/04/2023,QLD Typical Summer,0 +01/11/2023,QLD Typical Summer,-1 +15/12/2023,QLD Typical Summer,0 +16/12/2023,QLD Typical Summer,-1 +28/12/2023,QLD Typical Summer,0 +30/12/2023,QLD Typical Summer,-1 +22/01/2024,QLD Typical Summer,0 +23/01/2024,QLD Typical Summer,-1 +27/01/2024,QLD Typical Summer,0 +28/01/2024,QLD Typical Summer,-1 +01/04/2024,QLD Typical Summer,0 +01/11/2024,QLD Typical Summer,-1 +08/12/2024,QLD Typical Summer,0 +09/12/2024,QLD Typical Summer,-1 +16/01/2025,QLD Typical Summer,0 +17/01/2025,QLD Typical Summer,-1 +22/01/2025,QLD Typical Summer,0 +23/01/2025,QLD Typical Summer,-1 +24/01/2025,QLD Typical Summer,0 +25/01/2025,QLD Typical Summer,-1 +16/02/2025,QLD Typical Summer,0 +17/02/2025,QLD Typical Summer,-1 +01/04/2025,QLD Typical Summer,0 +01/11/2025,QLD Typical Summer,-1 +16/11/2025,QLD Typical Summer,0 +17/11/2025,QLD Typical Summer,-1 +17/12/2025,QLD Typical Summer,0 +18/12/2025,QLD Typical Summer,-1 +30/12/2025,QLD Typical Summer,0 +31/12/2025,QLD Typical Summer,-1 +15/01/2026,QLD Typical Summer,0 +16/01/2026,QLD Typical Summer,-1 +17/01/2026,QLD Typical Summer,0 +19/01/2026,QLD Typical Summer,-1 +25/01/2026,QLD Typical Summer,0 +26/01/2026,QLD Typical Summer,-1 +05/03/2026,QLD Typical Summer,0 +06/03/2026,QLD Typical Summer,-1 +19/03/2026,QLD Typical Summer,0 +20/03/2026,QLD Typical Summer,-1 +01/04/2026,QLD Typical Summer,0 +01/11/2026,QLD Typical Summer,-1 +18/01/2027,QLD Typical Summer,0 +19/01/2027,QLD Typical Summer,-1 +20/02/2027,QLD Typical Summer,0 +22/02/2027,QLD Typical Summer,-1 +01/03/2027,QLD Typical Summer,0 +02/03/2027,QLD Typical Summer,-1 +22/03/2027,QLD Typical Summer,0 +23/03/2027,QLD Typical Summer,-1 +01/04/2027,QLD Typical Summer,0 +01/11/2027,QLD Typical Summer,-1 +15/11/2027,QLD Typical Summer,0 +16/11/2027,QLD Typical Summer,-1 +27/11/2027,QLD Typical Summer,0 +28/11/2027,QLD Typical Summer,-1 +09/01/2028,QLD Typical Summer,0 +10/01/2028,QLD Typical Summer,-1 +11/01/2028,QLD Typical Summer,0 +12/01/2028,QLD Typical Summer,-1 +06/02/2028,QLD Typical Summer,0 +07/02/2028,QLD Typical Summer,-1 +01/04/2028,QLD Typical Summer,0 +01/11/2028,QLD Typical Summer,-1 +04/12/2028,QLD Typical Summer,0 +05/12/2028,QLD Typical Summer,-1 +02/01/2029,QLD Typical Summer,0 +03/01/2029,QLD Typical Summer,-1 +12/01/2029,QLD Typical Summer,0 +14/01/2029,QLD Typical Summer,-1 +19/01/2029,QLD Typical Summer,0 +20/01/2029,QLD Typical Summer,-1 +01/04/2029,QLD Typical Summer,0 +01/11/2029,QLD Typical Summer,-1 +05/12/2029,QLD Typical Summer,0 +06/12/2029,QLD Typical Summer,-1 +29/12/2029,QLD Typical Summer,0 +30/12/2029,QLD Typical Summer,-1 +03/01/2030,QLD Typical Summer,0 +05/01/2030,QLD Typical Summer,-1 +22/01/2030,QLD Typical Summer,0 +23/01/2030,QLD Typical Summer,-1 +01/04/2030,QLD Typical Summer,0 +01/11/2030,QLD Typical Summer,-1 +16/11/2030,QLD Typical Summer,0 +17/11/2030,QLD Typical Summer,-1 +17/12/2030,QLD Typical Summer,0 +18/12/2030,QLD Typical Summer,-1 +30/12/2030,QLD Typical Summer,0 +31/12/2030,QLD Typical Summer,-1 +15/01/2031,QLD Typical Summer,0 +16/01/2031,QLD Typical Summer,-1 +17/01/2031,QLD Typical Summer,0 +19/01/2031,QLD Typical Summer,-1 +25/01/2031,QLD Typical Summer,0 +26/01/2031,QLD Typical Summer,-1 +05/03/2031,QLD Typical Summer,0 +06/03/2031,QLD Typical Summer,-1 +19/03/2031,QLD Typical Summer,0 +20/03/2031,QLD Typical Summer,-1 +01/04/2031,QLD Typical Summer,0 +01/11/2031,QLD Typical Summer,-1 +21/11/2031,QLD Typical Summer,0 +22/11/2031,QLD Typical Summer,-1 +29/01/2032,QLD Typical Summer,0 +30/01/2032,QLD Typical Summer,-1 +01/02/2032,QLD Typical Summer,0 +03/02/2032,QLD Typical Summer,-1 +16/02/2032,QLD Typical Summer,0 +17/02/2032,QLD Typical Summer,-1 +27/02/2032,QLD Typical Summer,0 +28/02/2032,QLD Typical Summer,-1 +01/04/2032,QLD Typical Summer,0 +01/11/2032,QLD Typical Summer,-1 +05/11/2032,QLD Typical Summer,0 +06/11/2032,QLD Typical Summer,-1 +13/11/2032,QLD Typical Summer,0 +14/11/2032,QLD Typical Summer,-1 +21/12/2032,QLD Typical Summer,0 +22/12/2032,QLD Typical Summer,-1 +01/01/2033,QLD Typical Summer,0 +02/01/2033,QLD Typical Summer,-1 +12/01/2033,QLD Typical Summer,0 +13/01/2033,QLD Typical Summer,-1 +14/01/2033,QLD Typical Summer,0 +15/01/2033,QLD Typical Summer,-1 +18/01/2033,QLD Typical Summer,0 +19/01/2033,QLD Typical Summer,-1 +11/02/2033,QLD Typical Summer,0 +13/02/2033,QLD Typical Summer,-1 +01/04/2033,QLD Typical Summer,0 +01/11/2033,QLD Typical Summer,-1 +25/12/2033,QLD Typical Summer,0 +26/12/2033,QLD Typical Summer,-1 +13/01/2034,QLD Typical Summer,0 +15/01/2034,QLD Typical Summer,-1 +31/01/2034,QLD Typical Summer,0 +01/02/2034,QLD Typical Summer,-1 +11/02/2034,QLD Typical Summer,0 +12/02/2034,QLD Typical Summer,-1 +01/04/2034,QLD Typical Summer,0 +01/11/2034,QLD Typical Summer,-1 +28/11/2034,QLD Typical Summer,0 +29/11/2034,QLD Typical Summer,-1 +21/12/2034,QLD Typical Summer,0 +22/12/2034,QLD Typical Summer,-1 +11/03/2035,QLD Typical Summer,0 +13/03/2035,QLD Typical Summer,-1 +24/03/2035,QLD Typical Summer,0 +25/03/2035,QLD Typical Summer,-1 +01/04/2035,QLD Typical Summer,0 +01/11/2035,QLD Typical Summer,-1 +08/11/2035,QLD Typical Summer,0 +09/11/2035,QLD Typical Summer,-1 +16/11/2035,QLD Typical Summer,0 +17/11/2035,QLD Typical Summer,-1 +05/12/2035,QLD Typical Summer,0 +08/12/2035,QLD Typical Summer,-1 +16/12/2035,QLD Typical Summer,0 +17/12/2035,QLD Typical Summer,-1 +03/02/2036,QLD Typical Summer,0 +04/02/2036,QLD Typical Summer,-1 +01/04/2036,QLD Typical Summer,0 +01/11/2036,QLD Typical Summer,-1 +06/12/2036,QLD Typical Summer,0 +08/12/2036,QLD Typical Summer,-1 +16/01/2037,QLD Typical Summer,0 +17/01/2037,QLD Typical Summer,-1 +07/02/2037,QLD Typical Summer,0 +08/02/2037,QLD Typical Summer,-1 +22/02/2037,QLD Typical Summer,0 +23/02/2037,QLD Typical Summer,-1 +01/04/2037,QLD Typical Summer,0 +01/11/2037,QLD Typical Summer,-1 +20/12/2037,QLD Typical Summer,0 +21/12/2037,QLD Typical Summer,-1 +01/02/2038,QLD Typical Summer,0 +03/02/2038,QLD Typical Summer,-1 +08/03/2038,QLD Typical Summer,0 +10/03/2038,QLD Typical Summer,-1 +01/04/2038,QLD Typical Summer,0 +01/11/2038,QLD Typical Summer,-1 +06/12/2038,QLD Typical Summer,0 +07/12/2038,QLD Typical Summer,-1 +03/02/2039,QLD Typical Summer,0 +04/02/2039,QLD Typical Summer,-1 +12/02/2039,QLD Typical Summer,0 +14/02/2039,QLD Typical Summer,-1 +16/03/2039,QLD Typical Summer,0 +18/03/2039,QLD Typical Summer,-1 +01/04/2039,QLD Typical Summer,0 +01/11/2039,QLD Typical Summer,-1 +15/12/2039,QLD Typical Summer,0 +16/12/2039,QLD Typical Summer,-1 +28/12/2039,QLD Typical Summer,0 +30/12/2039,QLD Typical Summer,-1 +22/01/2040,QLD Typical Summer,0 +23/01/2040,QLD Typical Summer,-1 +27/01/2040,QLD Typical Summer,0 +28/01/2040,QLD Typical Summer,-1 +01/04/2040,QLD Typical Summer,0 +01/11/2040,QLD Typical Summer,-1 +08/12/2040,QLD Typical Summer,0 +09/12/2040,QLD Typical Summer,-1 +16/01/2041,QLD Typical Summer,0 +17/01/2041,QLD Typical Summer,-1 +22/01/2041,QLD Typical Summer,0 +23/01/2041,QLD Typical Summer,-1 +24/01/2041,QLD Typical Summer,0 +25/01/2041,QLD Typical Summer,-1 +16/02/2041,QLD Typical Summer,0 +17/02/2041,QLD Typical Summer,-1 +01/04/2041,QLD Typical Summer,0 +01/11/2041,QLD Typical Summer,-1 +16/11/2041,QLD Typical Summer,0 +17/11/2041,QLD Typical Summer,-1 +17/12/2041,QLD Typical Summer,0 +18/12/2041,QLD Typical Summer,-1 +30/12/2041,QLD Typical Summer,0 +31/12/2041,QLD Typical Summer,-1 +15/01/2042,QLD Typical Summer,0 +16/01/2042,QLD Typical Summer,-1 +17/01/2042,QLD Typical Summer,0 +19/01/2042,QLD Typical Summer,-1 +25/01/2042,QLD Typical Summer,0 +26/01/2042,QLD Typical Summer,-1 +05/03/2042,QLD Typical Summer,0 +06/03/2042,QLD Typical Summer,-1 +19/03/2042,QLD Typical Summer,0 +20/03/2042,QLD Typical Summer,-1 +01/04/2042,QLD Typical Summer,0 +01/11/2042,QLD Typical Summer,-1 +18/01/2043,QLD Typical Summer,0 +19/01/2043,QLD Typical Summer,-1 +20/02/2043,QLD Typical Summer,0 +22/02/2043,QLD Typical Summer,-1 +01/03/2043,QLD Typical Summer,0 +02/03/2043,QLD Typical Summer,-1 +22/03/2043,QLD Typical Summer,0 +23/03/2043,QLD Typical Summer,-1 +01/04/2043,QLD Typical Summer,0 +01/11/2043,QLD Typical Summer,-1 +15/11/2043,QLD Typical Summer,0 +16/11/2043,QLD Typical Summer,-1 +27/11/2043,QLD Typical Summer,0 +28/11/2043,QLD Typical Summer,-1 +09/01/2044,QLD Typical Summer,0 +10/01/2044,QLD Typical Summer,-1 +11/01/2044,QLD Typical Summer,0 +12/01/2044,QLD Typical Summer,-1 +06/02/2044,QLD Typical Summer,0 +07/02/2044,QLD Typical Summer,-1 +01/04/2044,QLD Typical Summer,0 +01/11/2044,QLD Typical Summer,-1 +04/12/2044,QLD Typical Summer,0 +05/12/2044,QLD Typical Summer,-1 +02/01/2045,QLD Typical Summer,0 +03/01/2045,QLD Typical Summer,-1 +12/01/2045,QLD Typical Summer,0 +14/01/2045,QLD Typical Summer,-1 +19/01/2045,QLD Typical Summer,0 +20/01/2045,QLD Typical Summer,-1 +01/04/2045,QLD Typical Summer,0 +01/11/2045,QLD Typical Summer,-1 +05/12/2045,QLD Typical Summer,0 +06/12/2045,QLD Typical Summer,-1 +29/12/2045,QLD Typical Summer,0 +30/12/2045,QLD Typical Summer,-1 +03/01/2046,QLD Typical Summer,0 +05/01/2046,QLD Typical Summer,-1 +22/01/2046,QLD Typical Summer,0 +23/01/2046,QLD Typical Summer,-1 +01/04/2046,QLD Typical Summer,0 +01/11/2046,QLD Typical Summer,-1 +16/11/2046,QLD Typical Summer,0 +17/11/2046,QLD Typical Summer,-1 +17/12/2046,QLD Typical Summer,0 +18/12/2046,QLD Typical Summer,-1 +30/12/2046,QLD Typical Summer,0 +31/12/2046,QLD Typical Summer,-1 +15/01/2047,QLD Typical Summer,0 +16/01/2047,QLD Typical Summer,-1 +17/01/2047,QLD Typical Summer,0 +19/01/2047,QLD Typical Summer,-1 +25/01/2047,QLD Typical Summer,0 +26/01/2047,QLD Typical Summer,-1 +05/03/2047,QLD Typical Summer,0 +06/03/2047,QLD Typical Summer,-1 +19/03/2047,QLD Typical Summer,0 +20/03/2047,QLD Typical Summer,-1 +01/04/2047,QLD Typical Summer,0 +01/11/2047,QLD Typical Summer,-1 +21/11/2047,QLD Typical Summer,0 +22/11/2047,QLD Typical Summer,-1 +29/01/2048,QLD Typical Summer,0 +30/01/2048,QLD Typical Summer,-1 +01/02/2048,QLD Typical Summer,0 +03/02/2048,QLD Typical Summer,-1 +16/02/2048,QLD Typical Summer,0 +17/02/2048,QLD Typical Summer,-1 +27/02/2048,QLD Typical Summer,0 +28/02/2048,QLD Typical Summer,-1 +01/04/2048,QLD Typical Summer,0 +01/11/2048,QLD Typical Summer,-1 +05/11/2048,QLD Typical Summer,0 +06/11/2048,QLD Typical Summer,-1 +13/11/2048,QLD Typical Summer,0 +14/11/2048,QLD Typical Summer,-1 +21/12/2048,QLD Typical Summer,0 +22/12/2048,QLD Typical Summer,-1 +01/01/2049,QLD Typical Summer,0 +02/01/2049,QLD Typical Summer,-1 +12/01/2049,QLD Typical Summer,0 +13/01/2049,QLD Typical Summer,-1 +14/01/2049,QLD Typical Summer,0 +15/01/2049,QLD Typical Summer,-1 +18/01/2049,QLD Typical Summer,0 +19/01/2049,QLD Typical Summer,-1 +11/02/2049,QLD Typical Summer,0 +13/02/2049,QLD Typical Summer,-1 +01/04/2049,QLD Typical Summer,0 +01/11/2049,QLD Typical Summer,-1 +25/12/2049,QLD Typical Summer,0 +26/12/2049,QLD Typical Summer,-1 +13/01/2050,QLD Typical Summer,0 +15/01/2050,QLD Typical Summer,-1 +31/01/2050,QLD Typical Summer,0 +01/02/2050,QLD Typical Summer,-1 +11/02/2050,QLD Typical Summer,0 +12/02/2050,QLD Typical Summer,-1 +01/04/2050,QLD Typical Summer,0 +01/11/2050,QLD Typical Summer,-1 +28/11/2050,QLD Typical Summer,0 +29/11/2050,QLD Typical Summer,-1 +21/12/2050,QLD Typical Summer,0 +22/12/2050,QLD Typical Summer,-1 +11/03/2051,QLD Typical Summer,0 +13/03/2051,QLD Typical Summer,-1 +24/03/2051,QLD Typical Summer,0 +25/03/2051,QLD Typical Summer,-1 +01/04/2051,QLD Typical Summer,0 +01/11/2051,QLD Typical Summer,-1 +08/11/2051,QLD Typical Summer,0 +09/11/2051,QLD Typical Summer,-1 +16/11/2051,QLD Typical Summer,0 +17/11/2051,QLD Typical Summer,-1 +05/12/2051,QLD Typical Summer,0 +08/12/2051,QLD Typical Summer,-1 +16/12/2051,QLD Typical Summer,0 +17/12/2051,QLD Typical Summer,-1 +03/02/2052,QLD Typical Summer,0 +04/02/2052,QLD Typical Summer,-1 +01/04/2052,QLD Typical Summer,0 +01/11/2052,QLD Typical Summer,-1 +06/12/2052,QLD Typical Summer,0 +08/12/2052,QLD Typical Summer,-1 +16/01/2053,QLD Typical Summer,0 +17/01/2053,QLD Typical Summer,-1 +07/02/2053,QLD Typical Summer,0 +08/02/2053,QLD Typical Summer,-1 +22/02/2053,QLD Typical Summer,0 +23/02/2053,QLD Typical Summer,-1 +01/04/2053,QLD Typical Summer,0 +01/11/2053,QLD Typical Summer,-1 +20/12/2053,QLD Typical Summer,0 +21/12/2053,QLD Typical Summer,-1 +01/02/2054,QLD Typical Summer,0 +03/02/2054,QLD Typical Summer,-1 +08/03/2054,QLD Typical Summer,0 +10/03/2054,QLD Typical Summer,-1 +01/04/2054,QLD Typical Summer,0 +01/11/2054,QLD Typical Summer,-1 +06/12/2054,QLD Typical Summer,0 +07/12/2054,QLD Typical Summer,-1 +03/02/2055,QLD Typical Summer,0 +04/02/2055,QLD Typical Summer,-1 +12/02/2055,QLD Typical Summer,0 +14/02/2055,QLD Typical Summer,-1 +16/03/2055,QLD Typical Summer,0 +18/03/2055,QLD Typical Summer,-1 +01/04/2055,QLD Typical Summer,0 +01/11/2055,QLD Typical Summer,-1 +15/12/2055,QLD Typical Summer,0 +16/12/2055,QLD Typical Summer,-1 +28/12/2055,QLD Typical Summer,0 +30/12/2055,QLD Typical Summer,-1 +22/01/2056,QLD Typical Summer,0 +23/01/2056,QLD Typical Summer,-1 +27/01/2056,QLD Typical Summer,0 +28/01/2056,QLD Typical Summer,-1 +01/04/2056,QLD Typical Summer,0 +01/11/2056,QLD Typical Summer,-1 +08/12/2056,QLD Typical Summer,0 +09/12/2056,QLD Typical Summer,-1 +16/01/2057,QLD Typical Summer,0 +17/01/2057,QLD Typical Summer,-1 +22/01/2057,QLD Typical Summer,0 +23/01/2057,QLD Typical Summer,-1 +24/01/2057,QLD Typical Summer,0 +25/01/2057,QLD Typical Summer,-1 +16/02/2057,QLD Typical Summer,0 +17/02/2057,QLD Typical Summer,-1 +01/04/2057,QLD Typical Summer,0 +01/11/2057,QLD Typical Summer,-1 +16/11/2057,QLD Typical Summer,0 +17/11/2057,QLD Typical Summer,-1 +17/12/2057,QLD Typical Summer,0 +18/12/2057,QLD Typical Summer,-1 +30/12/2057,QLD Typical Summer,0 +31/12/2057,QLD Typical Summer,-1 +15/01/2058,QLD Typical Summer,0 +16/01/2058,QLD Typical Summer,-1 +17/01/2058,QLD Typical Summer,0 +19/01/2058,QLD Typical Summer,-1 +25/01/2058,QLD Typical Summer,0 +26/01/2058,QLD Typical Summer,-1 +05/03/2058,QLD Typical Summer,0 +06/03/2058,QLD Typical Summer,-1 +19/03/2058,QLD Typical Summer,0 +20/03/2058,QLD Typical Summer,-1 +01/04/2058,QLD Typical Summer,0 +30/06/2021,QLD Winter,-1 +01/11/2021,QLD Winter,0 +01/04/2022,QLD Winter,-1 +01/11/2022,QLD Winter,0 +01/04/2023,QLD Winter,-1 +01/11/2023,QLD Winter,0 +01/04/2024,QLD Winter,-1 +01/11/2024,QLD Winter,0 +01/04/2025,QLD Winter,-1 +01/11/2025,QLD Winter,0 +01/04/2026,QLD Winter,-1 +01/11/2026,QLD Winter,0 +01/04/2027,QLD Winter,-1 +01/11/2027,QLD Winter,0 +01/04/2028,QLD Winter,-1 +01/11/2028,QLD Winter,0 +01/04/2029,QLD Winter,-1 +01/11/2029,QLD Winter,0 +01/04/2030,QLD Winter,-1 +01/11/2030,QLD Winter,0 +01/04/2031,QLD Winter,-1 +01/11/2031,QLD Winter,0 +01/04/2032,QLD Winter,-1 +01/11/2032,QLD Winter,0 +01/04/2033,QLD Winter,-1 +01/11/2033,QLD Winter,0 +01/04/2034,QLD Winter,-1 +01/11/2034,QLD Winter,0 +01/04/2035,QLD Winter,-1 +01/11/2035,QLD Winter,0 +01/04/2036,QLD Winter,-1 +01/11/2036,QLD Winter,0 +01/04/2037,QLD Winter,-1 +01/11/2037,QLD Winter,0 +01/04/2038,QLD Winter,-1 +01/11/2038,QLD Winter,0 +01/04/2039,QLD Winter,-1 +01/11/2039,QLD Winter,0 +01/04/2040,QLD Winter,-1 +01/11/2040,QLD Winter,0 +01/04/2041,QLD Winter,-1 +01/11/2041,QLD Winter,0 +01/04/2042,QLD Winter,-1 +01/11/2042,QLD Winter,0 +01/04/2043,QLD Winter,-1 +01/11/2043,QLD Winter,0 +01/04/2044,QLD Winter,-1 +01/11/2044,QLD Winter,0 +01/04/2045,QLD Winter,-1 +01/11/2045,QLD Winter,0 +01/04/2046,QLD Winter,-1 +01/11/2046,QLD Winter,0 +01/04/2047,QLD Winter,-1 +01/11/2047,QLD Winter,0 +01/04/2048,QLD Winter,-1 +01/11/2048,QLD Winter,0 +01/04/2049,QLD Winter,-1 +01/11/2049,QLD Winter,0 +01/04/2050,QLD Winter,-1 +01/11/2050,QLD Winter,0 +01/04/2051,QLD Winter,-1 +01/11/2051,QLD Winter,0 +01/04/2052,QLD Winter,-1 +01/11/2052,QLD Winter,0 +01/04/2053,QLD Winter,-1 +01/11/2053,QLD Winter,0 +01/04/2054,QLD Winter,-1 +01/11/2054,QLD Winter,0 +01/04/2055,QLD Winter,-1 +01/11/2055,QLD Winter,0 +01/04/2056,QLD Winter,-1 +01/11/2056,QLD Winter,0 +01/04/2057,QLD Winter,-1 +01/11/2057,QLD Winter,0 +01/04/2058,QLD Winter,-1 +30/06/2021,SA Hot Day,0 +17/12/2021,SA Hot Day,-1 +18/12/2021,SA Hot Day,0 +30/12/2021,SA Hot Day,-1 +01/01/2022,SA Hot Day,0 +10/01/2022,SA Hot Day,-1 +12/01/2022,SA Hot Day,0 +27/12/2022,SA Hot Day,-1 +28/12/2022,SA Hot Day,0 +14/01/2023,SA Hot Day,-1 +15/01/2023,SA Hot Day,0 +16/02/2023,SA Hot Day,-1 +17/02/2023,SA Hot Day,0 +22/02/2023,SA Hot Day,-1 +24/02/2023,SA Hot Day,0 +10/11/2023,SA Hot Day,-1 +11/11/2023,SA Hot Day,0 +23/01/2024,SA Hot Day,-1 +24/01/2024,SA Hot Day,0 +04/02/2024,SA Hot Day,-1 +05/02/2024,SA Hot Day,0 +09/03/2024,SA Hot Day,-1 +10/03/2024,SA Hot Day,0 +11/03/2024,SA Hot Day,-1 +12/03/2024,SA Hot Day,0 +03/02/2025,SA Hot Day,-1 +04/02/2025,SA Hot Day,0 +12/02/2025,SA Hot Day,-1 +13/02/2025,SA Hot Day,0 +22/02/2025,SA Hot Day,-1 +23/02/2025,SA Hot Day,0 +10/03/2025,SA Hot Day,-1 +11/03/2025,SA Hot Day,0 +15/03/2025,SA Hot Day,-1 +16/03/2025,SA Hot Day,0 +02/01/2026,SA Hot Day,-1 +03/01/2026,SA Hot Day,0 +06/01/2026,SA Hot Day,-1 +08/01/2026,SA Hot Day,0 +14/02/2026,SA Hot Day,-1 +15/02/2026,SA Hot Day,0 +22/02/2026,SA Hot Day,-1 +23/02/2026,SA Hot Day,0 +04/12/2026,SA Hot Day,-1 +05/12/2026,SA Hot Day,0 +30/12/2026,SA Hot Day,-1 +31/12/2026,SA Hot Day,0 +29/01/2027,SA Hot Day,-1 +01/02/2027,SA Hot Day,0 +24/12/2027,SA Hot Day,-1 +25/12/2027,SA Hot Day,0 +01/01/2028,SA Hot Day,-1 +03/01/2028,SA Hot Day,0 +24/02/2028,SA Hot Day,-1 +26/02/2028,SA Hot Day,0 +23/12/2028,SA Hot Day,-1 +24/12/2028,SA Hot Day,0 +03/01/2029,SA Hot Day,-1 +05/01/2029,SA Hot Day,0 +07/01/2029,SA Hot Day,-1 +08/01/2029,SA Hot Day,0 +17/01/2029,SA Hot Day,-1 +18/01/2029,SA Hot Day,0 +19/12/2029,SA Hot Day,-1 +20/12/2029,SA Hot Day,0 +13/01/2030,SA Hot Day,-1 +18/01/2030,SA Hot Day,0 +28/01/2030,SA Hot Day,-1 +29/01/2030,SA Hot Day,0 +01/02/2030,SA Hot Day,-1 +03/02/2030,SA Hot Day,0 +08/02/2030,SA Hot Day,-1 +09/02/2030,SA Hot Day,0 +11/02/2030,SA Hot Day,-1 +13/02/2030,SA Hot Day,0 +02/01/2031,SA Hot Day,-1 +03/01/2031,SA Hot Day,0 +06/01/2031,SA Hot Day,-1 +08/01/2031,SA Hot Day,0 +14/02/2031,SA Hot Day,-1 +15/02/2031,SA Hot Day,0 +22/02/2031,SA Hot Day,-1 +23/02/2031,SA Hot Day,0 +06/12/2031,SA Hot Day,-1 +07/12/2031,SA Hot Day,0 +16/12/2031,SA Hot Day,-1 +18/12/2031,SA Hot Day,0 +19/12/2031,SA Hot Day,-1 +20/12/2031,SA Hot Day,0 +31/12/2031,SA Hot Day,-1 +01/01/2032,SA Hot Day,0 +25/12/2032,SA Hot Day,-1 +26/12/2032,SA Hot Day,0 +07/01/2033,SA Hot Day,-1 +08/01/2033,SA Hot Day,0 +17/01/2033,SA Hot Day,-1 +18/01/2033,SA Hot Day,0 +08/02/2033,SA Hot Day,-1 +10/02/2033,SA Hot Day,0 +06/01/2034,SA Hot Day,-1 +07/01/2034,SA Hot Day,0 +18/01/2034,SA Hot Day,-1 +20/01/2034,SA Hot Day,0 +28/01/2034,SA Hot Day,-1 +29/01/2034,SA Hot Day,0 +07/02/2034,SA Hot Day,-1 +08/02/2034,SA Hot Day,0 +27/12/2034,SA Hot Day,-1 +28/12/2034,SA Hot Day,0 +03/01/2035,SA Hot Day,-1 +04/01/2035,SA Hot Day,0 +15/01/2035,SA Hot Day,-1 +16/01/2035,SA Hot Day,0 +23/01/2035,SA Hot Day,-1 +25/01/2035,SA Hot Day,0 +01/03/2035,SA Hot Day,-1 +02/03/2035,SA Hot Day,0 +20/11/2035,SA Hot Day,-1 +21/11/2035,SA Hot Day,0 +17/12/2035,SA Hot Day,-1 +21/12/2035,SA Hot Day,0 +27/12/2035,SA Hot Day,-1 +28/12/2035,SA Hot Day,0 +03/01/2036,SA Hot Day,-1 +04/01/2036,SA Hot Day,0 +09/01/2036,SA Hot Day,-1 +10/01/2036,SA Hot Day,0 +30/01/2036,SA Hot Day,-1 +31/01/2036,SA Hot Day,0 +21/11/2036,SA Hot Day,-1 +22/11/2036,SA Hot Day,0 +27/11/2036,SA Hot Day,-1 +28/11/2036,SA Hot Day,0 +23/01/2037,SA Hot Day,-1 +25/01/2037,SA Hot Day,0 +18/02/2037,SA Hot Day,-1 +19/02/2037,SA Hot Day,0 +17/12/2037,SA Hot Day,-1 +18/12/2037,SA Hot Day,0 +30/12/2037,SA Hot Day,-1 +01/01/2038,SA Hot Day,0 +10/01/2038,SA Hot Day,-1 +12/01/2038,SA Hot Day,0 +27/12/2038,SA Hot Day,-1 +28/12/2038,SA Hot Day,0 +14/01/2039,SA Hot Day,-1 +15/01/2039,SA Hot Day,0 +16/02/2039,SA Hot Day,-1 +17/02/2039,SA Hot Day,0 +22/02/2039,SA Hot Day,-1 +24/02/2039,SA Hot Day,0 +10/11/2039,SA Hot Day,-1 +11/11/2039,SA Hot Day,0 +23/01/2040,SA Hot Day,-1 +24/01/2040,SA Hot Day,0 +04/02/2040,SA Hot Day,-1 +05/02/2040,SA Hot Day,0 +09/03/2040,SA Hot Day,-1 +10/03/2040,SA Hot Day,0 +11/03/2040,SA Hot Day,-1 +12/03/2040,SA Hot Day,0 +03/02/2041,SA Hot Day,-1 +04/02/2041,SA Hot Day,0 +12/02/2041,SA Hot Day,-1 +13/02/2041,SA Hot Day,0 +22/02/2041,SA Hot Day,-1 +23/02/2041,SA Hot Day,0 +10/03/2041,SA Hot Day,-1 +11/03/2041,SA Hot Day,0 +15/03/2041,SA Hot Day,-1 +16/03/2041,SA Hot Day,0 +02/01/2042,SA Hot Day,-1 +03/01/2042,SA Hot Day,0 +06/01/2042,SA Hot Day,-1 +08/01/2042,SA Hot Day,0 +14/02/2042,SA Hot Day,-1 +15/02/2042,SA Hot Day,0 +22/02/2042,SA Hot Day,-1 +23/02/2042,SA Hot Day,0 +04/12/2042,SA Hot Day,-1 +05/12/2042,SA Hot Day,0 +30/12/2042,SA Hot Day,-1 +31/12/2042,SA Hot Day,0 +29/01/2043,SA Hot Day,-1 +01/02/2043,SA Hot Day,0 +24/12/2043,SA Hot Day,-1 +25/12/2043,SA Hot Day,0 +01/01/2044,SA Hot Day,-1 +03/01/2044,SA Hot Day,0 +24/02/2044,SA Hot Day,-1 +26/02/2044,SA Hot Day,0 +23/12/2044,SA Hot Day,-1 +24/12/2044,SA Hot Day,0 +03/01/2045,SA Hot Day,-1 +05/01/2045,SA Hot Day,0 +07/01/2045,SA Hot Day,-1 +08/01/2045,SA Hot Day,0 +17/01/2045,SA Hot Day,-1 +18/01/2045,SA Hot Day,0 +19/12/2045,SA Hot Day,-1 +20/12/2045,SA Hot Day,0 +13/01/2046,SA Hot Day,-1 +18/01/2046,SA Hot Day,0 +28/01/2046,SA Hot Day,-1 +29/01/2046,SA Hot Day,0 +01/02/2046,SA Hot Day,-1 +03/02/2046,SA Hot Day,0 +08/02/2046,SA Hot Day,-1 +09/02/2046,SA Hot Day,0 +11/02/2046,SA Hot Day,-1 +13/02/2046,SA Hot Day,0 +02/01/2047,SA Hot Day,-1 +03/01/2047,SA Hot Day,0 +06/01/2047,SA Hot Day,-1 +08/01/2047,SA Hot Day,0 +14/02/2047,SA Hot Day,-1 +15/02/2047,SA Hot Day,0 +22/02/2047,SA Hot Day,-1 +23/02/2047,SA Hot Day,0 +06/12/2047,SA Hot Day,-1 +07/12/2047,SA Hot Day,0 +16/12/2047,SA Hot Day,-1 +18/12/2047,SA Hot Day,0 +19/12/2047,SA Hot Day,-1 +20/12/2047,SA Hot Day,0 +31/12/2047,SA Hot Day,-1 +01/01/2048,SA Hot Day,0 +25/12/2048,SA Hot Day,-1 +26/12/2048,SA Hot Day,0 +07/01/2049,SA Hot Day,-1 +08/01/2049,SA Hot Day,0 +17/01/2049,SA Hot Day,-1 +18/01/2049,SA Hot Day,0 +08/02/2049,SA Hot Day,-1 +10/02/2049,SA Hot Day,0 +06/01/2050,SA Hot Day,-1 +07/01/2050,SA Hot Day,0 +18/01/2050,SA Hot Day,-1 +20/01/2050,SA Hot Day,0 +28/01/2050,SA Hot Day,-1 +29/01/2050,SA Hot Day,0 +07/02/2050,SA Hot Day,-1 +08/02/2050,SA Hot Day,0 +27/12/2050,SA Hot Day,-1 +28/12/2050,SA Hot Day,0 +03/01/2051,SA Hot Day,-1 +04/01/2051,SA Hot Day,0 +15/01/2051,SA Hot Day,-1 +16/01/2051,SA Hot Day,0 +23/01/2051,SA Hot Day,-1 +25/01/2051,SA Hot Day,0 +01/03/2051,SA Hot Day,-1 +02/03/2051,SA Hot Day,0 +20/11/2051,SA Hot Day,-1 +21/11/2051,SA Hot Day,0 +17/12/2051,SA Hot Day,-1 +21/12/2051,SA Hot Day,0 +27/12/2051,SA Hot Day,-1 +28/12/2051,SA Hot Day,0 +03/01/2052,SA Hot Day,-1 +04/01/2052,SA Hot Day,0 +09/01/2052,SA Hot Day,-1 +10/01/2052,SA Hot Day,0 +30/01/2052,SA Hot Day,-1 +31/01/2052,SA Hot Day,0 +21/11/2052,SA Hot Day,-1 +22/11/2052,SA Hot Day,0 +27/11/2052,SA Hot Day,-1 +28/11/2052,SA Hot Day,0 +23/01/2053,SA Hot Day,-1 +25/01/2053,SA Hot Day,0 +18/02/2053,SA Hot Day,-1 +19/02/2053,SA Hot Day,0 +17/12/2053,SA Hot Day,-1 +18/12/2053,SA Hot Day,0 +30/12/2053,SA Hot Day,-1 +01/01/2054,SA Hot Day,0 +10/01/2054,SA Hot Day,-1 +12/01/2054,SA Hot Day,0 +27/12/2054,SA Hot Day,-1 +28/12/2054,SA Hot Day,0 +14/01/2055,SA Hot Day,-1 +15/01/2055,SA Hot Day,0 +16/02/2055,SA Hot Day,-1 +17/02/2055,SA Hot Day,0 +22/02/2055,SA Hot Day,-1 +24/02/2055,SA Hot Day,0 +10/11/2055,SA Hot Day,-1 +11/11/2055,SA Hot Day,0 +23/01/2056,SA Hot Day,-1 +24/01/2056,SA Hot Day,0 +04/02/2056,SA Hot Day,-1 +05/02/2056,SA Hot Day,0 +09/03/2056,SA Hot Day,-1 +10/03/2056,SA Hot Day,0 +11/03/2056,SA Hot Day,-1 +12/03/2056,SA Hot Day,0 +03/02/2057,SA Hot Day,-1 +04/02/2057,SA Hot Day,0 +12/02/2057,SA Hot Day,-1 +13/02/2057,SA Hot Day,0 +22/02/2057,SA Hot Day,-1 +23/02/2057,SA Hot Day,0 +10/03/2057,SA Hot Day,-1 +11/03/2057,SA Hot Day,0 +15/03/2057,SA Hot Day,-1 +16/03/2057,SA Hot Day,0 +02/01/2058,SA Hot Day,-1 +03/01/2058,SA Hot Day,0 +06/01/2058,SA Hot Day,-1 +08/01/2058,SA Hot Day,0 +14/02/2058,SA Hot Day,-1 +15/02/2058,SA Hot Day,0 +22/02/2058,SA Hot Day,-1 +23/02/2058,SA Hot Day,0 +30/06/2021,SA Typical Summer,0 +01/11/2021,SA Typical Summer,-1 +17/12/2021,SA Typical Summer,0 +18/12/2021,SA Typical Summer,-1 +30/12/2021,SA Typical Summer,0 +01/01/2022,SA Typical Summer,-1 +10/01/2022,SA Typical Summer,0 +12/01/2022,SA Typical Summer,-1 +01/04/2022,SA Typical Summer,0 +01/11/2022,SA Typical Summer,-1 +27/12/2022,SA Typical Summer,0 +28/12/2022,SA Typical Summer,-1 +14/01/2023,SA Typical Summer,0 +15/01/2023,SA Typical Summer,-1 +16/02/2023,SA Typical Summer,0 +17/02/2023,SA Typical Summer,-1 +22/02/2023,SA Typical Summer,0 +24/02/2023,SA Typical Summer,-1 +01/04/2023,SA Typical Summer,0 +01/11/2023,SA Typical Summer,-1 +10/11/2023,SA Typical Summer,0 +11/11/2023,SA Typical Summer,-1 +23/01/2024,SA Typical Summer,0 +24/01/2024,SA Typical Summer,-1 +04/02/2024,SA Typical Summer,0 +05/02/2024,SA Typical Summer,-1 +09/03/2024,SA Typical Summer,0 +10/03/2024,SA Typical Summer,-1 +11/03/2024,SA Typical Summer,0 +12/03/2024,SA Typical Summer,-1 +01/04/2024,SA Typical Summer,0 +01/11/2024,SA Typical Summer,-1 +03/02/2025,SA Typical Summer,0 +04/02/2025,SA Typical Summer,-1 +12/02/2025,SA Typical Summer,0 +13/02/2025,SA Typical Summer,-1 +22/02/2025,SA Typical Summer,0 +23/02/2025,SA Typical Summer,-1 +10/03/2025,SA Typical Summer,0 +11/03/2025,SA Typical Summer,-1 +15/03/2025,SA Typical Summer,0 +16/03/2025,SA Typical Summer,-1 +01/04/2025,SA Typical Summer,0 +01/11/2025,SA Typical Summer,-1 +02/01/2026,SA Typical Summer,0 +03/01/2026,SA Typical Summer,-1 +06/01/2026,SA Typical Summer,0 +08/01/2026,SA Typical Summer,-1 +14/02/2026,SA Typical Summer,0 +15/02/2026,SA Typical Summer,-1 +22/02/2026,SA Typical Summer,0 +23/02/2026,SA Typical Summer,-1 +01/04/2026,SA Typical Summer,0 +01/11/2026,SA Typical Summer,-1 +04/12/2026,SA Typical Summer,0 +05/12/2026,SA Typical Summer,-1 +30/12/2026,SA Typical Summer,0 +31/12/2026,SA Typical Summer,-1 +29/01/2027,SA Typical Summer,0 +01/02/2027,SA Typical Summer,-1 +01/04/2027,SA Typical Summer,0 +01/11/2027,SA Typical Summer,-1 +24/12/2027,SA Typical Summer,0 +25/12/2027,SA Typical Summer,-1 +01/01/2028,SA Typical Summer,0 +03/01/2028,SA Typical Summer,-1 +24/02/2028,SA Typical Summer,0 +26/02/2028,SA Typical Summer,-1 +01/04/2028,SA Typical Summer,0 +01/11/2028,SA Typical Summer,-1 +23/12/2028,SA Typical Summer,0 +24/12/2028,SA Typical Summer,-1 +03/01/2029,SA Typical Summer,0 +05/01/2029,SA Typical Summer,-1 +07/01/2029,SA Typical Summer,0 +08/01/2029,SA Typical Summer,-1 +17/01/2029,SA Typical Summer,0 +18/01/2029,SA Typical Summer,-1 +01/04/2029,SA Typical Summer,0 +01/11/2029,SA Typical Summer,-1 +19/12/2029,SA Typical Summer,0 +20/12/2029,SA Typical Summer,-1 +13/01/2030,SA Typical Summer,0 +18/01/2030,SA Typical Summer,-1 +28/01/2030,SA Typical Summer,0 +29/01/2030,SA Typical Summer,-1 +01/02/2030,SA Typical Summer,0 +03/02/2030,SA Typical Summer,-1 +08/02/2030,SA Typical Summer,0 +09/02/2030,SA Typical Summer,-1 +11/02/2030,SA Typical Summer,0 +13/02/2030,SA Typical Summer,-1 +01/04/2030,SA Typical Summer,0 +01/11/2030,SA Typical Summer,-1 +02/01/2031,SA Typical Summer,0 +03/01/2031,SA Typical Summer,-1 +06/01/2031,SA Typical Summer,0 +08/01/2031,SA Typical Summer,-1 +14/02/2031,SA Typical Summer,0 +15/02/2031,SA Typical Summer,-1 +22/02/2031,SA Typical Summer,0 +23/02/2031,SA Typical Summer,-1 +01/04/2031,SA Typical Summer,0 +01/11/2031,SA Typical Summer,-1 +06/12/2031,SA Typical Summer,0 +07/12/2031,SA Typical Summer,-1 +16/12/2031,SA Typical Summer,0 +18/12/2031,SA Typical Summer,-1 +19/12/2031,SA Typical Summer,0 +20/12/2031,SA Typical Summer,-1 +31/12/2031,SA Typical Summer,0 +01/01/2032,SA Typical Summer,-1 +01/04/2032,SA Typical Summer,0 +01/11/2032,SA Typical Summer,-1 +25/12/2032,SA Typical Summer,0 +26/12/2032,SA Typical Summer,-1 +07/01/2033,SA Typical Summer,0 +08/01/2033,SA Typical Summer,-1 +17/01/2033,SA Typical Summer,0 +18/01/2033,SA Typical Summer,-1 +08/02/2033,SA Typical Summer,0 +10/02/2033,SA Typical Summer,-1 +01/04/2033,SA Typical Summer,0 +01/11/2033,SA Typical Summer,-1 +06/01/2034,SA Typical Summer,0 +07/01/2034,SA Typical Summer,-1 +18/01/2034,SA Typical Summer,0 +20/01/2034,SA Typical Summer,-1 +28/01/2034,SA Typical Summer,0 +29/01/2034,SA Typical Summer,-1 +07/02/2034,SA Typical Summer,0 +08/02/2034,SA Typical Summer,-1 +01/04/2034,SA Typical Summer,0 +01/11/2034,SA Typical Summer,-1 +27/12/2034,SA Typical Summer,0 +28/12/2034,SA Typical Summer,-1 +03/01/2035,SA Typical Summer,0 +04/01/2035,SA Typical Summer,-1 +15/01/2035,SA Typical Summer,0 +16/01/2035,SA Typical Summer,-1 +23/01/2035,SA Typical Summer,0 +25/01/2035,SA Typical Summer,-1 +01/03/2035,SA Typical Summer,0 +02/03/2035,SA Typical Summer,-1 +01/04/2035,SA Typical Summer,0 +01/11/2035,SA Typical Summer,-1 +20/11/2035,SA Typical Summer,0 +21/11/2035,SA Typical Summer,-1 +17/12/2035,SA Typical Summer,0 +21/12/2035,SA Typical Summer,-1 +27/12/2035,SA Typical Summer,0 +28/12/2035,SA Typical Summer,-1 +03/01/2036,SA Typical Summer,0 +04/01/2036,SA Typical Summer,-1 +09/01/2036,SA Typical Summer,0 +10/01/2036,SA Typical Summer,-1 +30/01/2036,SA Typical Summer,0 +31/01/2036,SA Typical Summer,-1 +01/04/2036,SA Typical Summer,0 +01/11/2036,SA Typical Summer,-1 +21/11/2036,SA Typical Summer,0 +22/11/2036,SA Typical Summer,-1 +27/11/2036,SA Typical Summer,0 +28/11/2036,SA Typical Summer,-1 +23/01/2037,SA Typical Summer,0 +25/01/2037,SA Typical Summer,-1 +18/02/2037,SA Typical Summer,0 +19/02/2037,SA Typical Summer,-1 +01/04/2037,SA Typical Summer,0 +01/11/2037,SA Typical Summer,-1 +17/12/2037,SA Typical Summer,0 +18/12/2037,SA Typical Summer,-1 +30/12/2037,SA Typical Summer,0 +01/01/2038,SA Typical Summer,-1 +10/01/2038,SA Typical Summer,0 +12/01/2038,SA Typical Summer,-1 +01/04/2038,SA Typical Summer,0 +01/11/2038,SA Typical Summer,-1 +27/12/2038,SA Typical Summer,0 +28/12/2038,SA Typical Summer,-1 +14/01/2039,SA Typical Summer,0 +15/01/2039,SA Typical Summer,-1 +16/02/2039,SA Typical Summer,0 +17/02/2039,SA Typical Summer,-1 +22/02/2039,SA Typical Summer,0 +24/02/2039,SA Typical Summer,-1 +01/04/2039,SA Typical Summer,0 +01/11/2039,SA Typical Summer,-1 +10/11/2039,SA Typical Summer,0 +11/11/2039,SA Typical Summer,-1 +23/01/2040,SA Typical Summer,0 +24/01/2040,SA Typical Summer,-1 +04/02/2040,SA Typical Summer,0 +05/02/2040,SA Typical Summer,-1 +09/03/2040,SA Typical Summer,0 +10/03/2040,SA Typical Summer,-1 +11/03/2040,SA Typical Summer,0 +12/03/2040,SA Typical Summer,-1 +01/04/2040,SA Typical Summer,0 +01/11/2040,SA Typical Summer,-1 +03/02/2041,SA Typical Summer,0 +04/02/2041,SA Typical Summer,-1 +12/02/2041,SA Typical Summer,0 +13/02/2041,SA Typical Summer,-1 +22/02/2041,SA Typical Summer,0 +23/02/2041,SA Typical Summer,-1 +10/03/2041,SA Typical Summer,0 +11/03/2041,SA Typical Summer,-1 +15/03/2041,SA Typical Summer,0 +16/03/2041,SA Typical Summer,-1 +01/04/2041,SA Typical Summer,0 +01/11/2041,SA Typical Summer,-1 +02/01/2042,SA Typical Summer,0 +03/01/2042,SA Typical Summer,-1 +06/01/2042,SA Typical Summer,0 +08/01/2042,SA Typical Summer,-1 +14/02/2042,SA Typical Summer,0 +15/02/2042,SA Typical Summer,-1 +22/02/2042,SA Typical Summer,0 +23/02/2042,SA Typical Summer,-1 +01/04/2042,SA Typical Summer,0 +01/11/2042,SA Typical Summer,-1 +04/12/2042,SA Typical Summer,0 +05/12/2042,SA Typical Summer,-1 +30/12/2042,SA Typical Summer,0 +31/12/2042,SA Typical Summer,-1 +29/01/2043,SA Typical Summer,0 +01/02/2043,SA Typical Summer,-1 +01/04/2043,SA Typical Summer,0 +01/11/2043,SA Typical Summer,-1 +24/12/2043,SA Typical Summer,0 +25/12/2043,SA Typical Summer,-1 +01/01/2044,SA Typical Summer,0 +03/01/2044,SA Typical Summer,-1 +24/02/2044,SA Typical Summer,0 +26/02/2044,SA Typical Summer,-1 +01/04/2044,SA Typical Summer,0 +01/11/2044,SA Typical Summer,-1 +23/12/2044,SA Typical Summer,0 +24/12/2044,SA Typical Summer,-1 +03/01/2045,SA Typical Summer,0 +05/01/2045,SA Typical Summer,-1 +07/01/2045,SA Typical Summer,0 +08/01/2045,SA Typical Summer,-1 +17/01/2045,SA Typical Summer,0 +18/01/2045,SA Typical Summer,-1 +01/04/2045,SA Typical Summer,0 +01/11/2045,SA Typical Summer,-1 +19/12/2045,SA Typical Summer,0 +20/12/2045,SA Typical Summer,-1 +13/01/2046,SA Typical Summer,0 +18/01/2046,SA Typical Summer,-1 +28/01/2046,SA Typical Summer,0 +29/01/2046,SA Typical Summer,-1 +01/02/2046,SA Typical Summer,0 +03/02/2046,SA Typical Summer,-1 +08/02/2046,SA Typical Summer,0 +09/02/2046,SA Typical Summer,-1 +11/02/2046,SA Typical Summer,0 +13/02/2046,SA Typical Summer,-1 +01/04/2046,SA Typical Summer,0 +01/11/2046,SA Typical Summer,-1 +02/01/2047,SA Typical Summer,0 +03/01/2047,SA Typical Summer,-1 +06/01/2047,SA Typical Summer,0 +08/01/2047,SA Typical Summer,-1 +14/02/2047,SA Typical Summer,0 +15/02/2047,SA Typical Summer,-1 +22/02/2047,SA Typical Summer,0 +23/02/2047,SA Typical Summer,-1 +01/04/2047,SA Typical Summer,0 +01/11/2047,SA Typical Summer,-1 +06/12/2047,SA Typical Summer,0 +07/12/2047,SA Typical Summer,-1 +16/12/2047,SA Typical Summer,0 +18/12/2047,SA Typical Summer,-1 +19/12/2047,SA Typical Summer,0 +20/12/2047,SA Typical Summer,-1 +31/12/2047,SA Typical Summer,0 +01/01/2048,SA Typical Summer,-1 +01/04/2048,SA Typical Summer,0 +01/11/2048,SA Typical Summer,-1 +25/12/2048,SA Typical Summer,0 +26/12/2048,SA Typical Summer,-1 +07/01/2049,SA Typical Summer,0 +08/01/2049,SA Typical Summer,-1 +17/01/2049,SA Typical Summer,0 +18/01/2049,SA Typical Summer,-1 +08/02/2049,SA Typical Summer,0 +10/02/2049,SA Typical Summer,-1 +01/04/2049,SA Typical Summer,0 +01/11/2049,SA Typical Summer,-1 +06/01/2050,SA Typical Summer,0 +07/01/2050,SA Typical Summer,-1 +18/01/2050,SA Typical Summer,0 +20/01/2050,SA Typical Summer,-1 +28/01/2050,SA Typical Summer,0 +29/01/2050,SA Typical Summer,-1 +07/02/2050,SA Typical Summer,0 +08/02/2050,SA Typical Summer,-1 +01/04/2050,SA Typical Summer,0 +01/11/2050,SA Typical Summer,-1 +27/12/2050,SA Typical Summer,0 +28/12/2050,SA Typical Summer,-1 +03/01/2051,SA Typical Summer,0 +04/01/2051,SA Typical Summer,-1 +15/01/2051,SA Typical Summer,0 +16/01/2051,SA Typical Summer,-1 +23/01/2051,SA Typical Summer,0 +25/01/2051,SA Typical Summer,-1 +01/03/2051,SA Typical Summer,0 +02/03/2051,SA Typical Summer,-1 +01/04/2051,SA Typical Summer,0 +01/11/2051,SA Typical Summer,-1 +20/11/2051,SA Typical Summer,0 +21/11/2051,SA Typical Summer,-1 +17/12/2051,SA Typical Summer,0 +21/12/2051,SA Typical Summer,-1 +27/12/2051,SA Typical Summer,0 +28/12/2051,SA Typical Summer,-1 +03/01/2052,SA Typical Summer,0 +04/01/2052,SA Typical Summer,-1 +09/01/2052,SA Typical Summer,0 +10/01/2052,SA Typical Summer,-1 +30/01/2052,SA Typical Summer,0 +31/01/2052,SA Typical Summer,-1 +01/04/2052,SA Typical Summer,0 +01/11/2052,SA Typical Summer,-1 +21/11/2052,SA Typical Summer,0 +22/11/2052,SA Typical Summer,-1 +27/11/2052,SA Typical Summer,0 +28/11/2052,SA Typical Summer,-1 +23/01/2053,SA Typical Summer,0 +25/01/2053,SA Typical Summer,-1 +18/02/2053,SA Typical Summer,0 +19/02/2053,SA Typical Summer,-1 +01/04/2053,SA Typical Summer,0 +01/11/2053,SA Typical Summer,-1 +17/12/2053,SA Typical Summer,0 +18/12/2053,SA Typical Summer,-1 +30/12/2053,SA Typical Summer,0 +01/01/2054,SA Typical Summer,-1 +10/01/2054,SA Typical Summer,0 +12/01/2054,SA Typical Summer,-1 +01/04/2054,SA Typical Summer,0 +01/11/2054,SA Typical Summer,-1 +27/12/2054,SA Typical Summer,0 +28/12/2054,SA Typical Summer,-1 +14/01/2055,SA Typical Summer,0 +15/01/2055,SA Typical Summer,-1 +16/02/2055,SA Typical Summer,0 +17/02/2055,SA Typical Summer,-1 +22/02/2055,SA Typical Summer,0 +24/02/2055,SA Typical Summer,-1 +01/04/2055,SA Typical Summer,0 +01/11/2055,SA Typical Summer,-1 +10/11/2055,SA Typical Summer,0 +11/11/2055,SA Typical Summer,-1 +23/01/2056,SA Typical Summer,0 +24/01/2056,SA Typical Summer,-1 +04/02/2056,SA Typical Summer,0 +05/02/2056,SA Typical Summer,-1 +09/03/2056,SA Typical Summer,0 +10/03/2056,SA Typical Summer,-1 +11/03/2056,SA Typical Summer,0 +12/03/2056,SA Typical Summer,-1 +01/04/2056,SA Typical Summer,0 +01/11/2056,SA Typical Summer,-1 +03/02/2057,SA Typical Summer,0 +04/02/2057,SA Typical Summer,-1 +12/02/2057,SA Typical Summer,0 +13/02/2057,SA Typical Summer,-1 +22/02/2057,SA Typical Summer,0 +23/02/2057,SA Typical Summer,-1 +10/03/2057,SA Typical Summer,0 +11/03/2057,SA Typical Summer,-1 +15/03/2057,SA Typical Summer,0 +16/03/2057,SA Typical Summer,-1 +01/04/2057,SA Typical Summer,0 +01/11/2057,SA Typical Summer,-1 +02/01/2058,SA Typical Summer,0 +03/01/2058,SA Typical Summer,-1 +06/01/2058,SA Typical Summer,0 +08/01/2058,SA Typical Summer,-1 +14/02/2058,SA Typical Summer,0 +15/02/2058,SA Typical Summer,-1 +22/02/2058,SA Typical Summer,0 +23/02/2058,SA Typical Summer,-1 +01/04/2058,SA Typical Summer,0 +30/06/2021,SA Winter,-1 +01/11/2021,SA Winter,0 +01/04/2022,SA Winter,-1 +01/11/2022,SA Winter,0 +01/04/2023,SA Winter,-1 +01/11/2023,SA Winter,0 +01/04/2024,SA Winter,-1 +01/11/2024,SA Winter,0 +01/04/2025,SA Winter,-1 +01/11/2025,SA Winter,0 +01/04/2026,SA Winter,-1 +01/11/2026,SA Winter,0 +01/04/2027,SA Winter,-1 +01/11/2027,SA Winter,0 +01/04/2028,SA Winter,-1 +01/11/2028,SA Winter,0 +01/04/2029,SA Winter,-1 +01/11/2029,SA Winter,0 +01/04/2030,SA Winter,-1 +01/11/2030,SA Winter,0 +01/04/2031,SA Winter,-1 +01/11/2031,SA Winter,0 +01/04/2032,SA Winter,-1 +01/11/2032,SA Winter,0 +01/04/2033,SA Winter,-1 +01/11/2033,SA Winter,0 +01/04/2034,SA Winter,-1 +01/11/2034,SA Winter,0 +01/04/2035,SA Winter,-1 +01/11/2035,SA Winter,0 +01/04/2036,SA Winter,-1 +01/11/2036,SA Winter,0 +01/04/2037,SA Winter,-1 +01/11/2037,SA Winter,0 +01/04/2038,SA Winter,-1 +01/11/2038,SA Winter,0 +01/04/2039,SA Winter,-1 +01/11/2039,SA Winter,0 +01/04/2040,SA Winter,-1 +01/11/2040,SA Winter,0 +01/04/2041,SA Winter,-1 +01/11/2041,SA Winter,0 +01/04/2042,SA Winter,-1 +01/11/2042,SA Winter,0 +01/04/2043,SA Winter,-1 +01/11/2043,SA Winter,0 +01/04/2044,SA Winter,-1 +01/11/2044,SA Winter,0 +01/04/2045,SA Winter,-1 +01/11/2045,SA Winter,0 +01/04/2046,SA Winter,-1 +01/11/2046,SA Winter,0 +01/04/2047,SA Winter,-1 +01/11/2047,SA Winter,0 +01/04/2048,SA Winter,-1 +01/11/2048,SA Winter,0 +01/04/2049,SA Winter,-1 +01/11/2049,SA Winter,0 +01/04/2050,SA Winter,-1 +01/11/2050,SA Winter,0 +01/04/2051,SA Winter,-1 +01/11/2051,SA Winter,0 +01/04/2052,SA Winter,-1 +01/11/2052,SA Winter,0 +01/04/2053,SA Winter,-1 +01/11/2053,SA Winter,0 +01/04/2054,SA Winter,-1 +01/11/2054,SA Winter,0 +01/04/2055,SA Winter,-1 +01/11/2055,SA Winter,0 +01/04/2056,SA Winter,-1 +01/11/2056,SA Winter,0 +01/04/2057,SA Winter,-1 +01/11/2057,SA Winter,0 +01/04/2058,SA Winter,-1 +30/06/2021,TAS Hot Day,0 +30/06/2021,TAS Typical Summer,0 +01/12/2021,TAS Typical Summer,-1 +01/03/2022,TAS Typical Summer,0 +01/12/2022,TAS Typical Summer,-1 +01/03/2023,TAS Typical Summer,0 +01/12/2023,TAS Typical Summer,-1 +01/03/2024,TAS Typical Summer,0 +01/12/2024,TAS Typical Summer,-1 +01/03/2025,TAS Typical Summer,0 +01/12/2025,TAS Typical Summer,-1 +01/03/2026,TAS Typical Summer,0 +01/12/2026,TAS Typical Summer,-1 +01/03/2027,TAS Typical Summer,0 +01/12/2027,TAS Typical Summer,-1 +01/03/2028,TAS Typical Summer,0 +01/12/2028,TAS Typical Summer,-1 +01/03/2029,TAS Typical Summer,0 +01/12/2029,TAS Typical Summer,-1 +01/03/2030,TAS Typical Summer,0 +01/12/2030,TAS Typical Summer,-1 +01/03/2031,TAS Typical Summer,0 +01/12/2031,TAS Typical Summer,-1 +01/03/2032,TAS Typical Summer,0 +01/12/2032,TAS Typical Summer,-1 +01/03/2033,TAS Typical Summer,0 +01/12/2033,TAS Typical Summer,-1 +01/03/2034,TAS Typical Summer,0 +01/12/2034,TAS Typical Summer,-1 +01/03/2035,TAS Typical Summer,0 +01/12/2035,TAS Typical Summer,-1 +01/03/2036,TAS Typical Summer,0 +01/12/2036,TAS Typical Summer,-1 +01/03/2037,TAS Typical Summer,0 +01/12/2037,TAS Typical Summer,-1 +01/03/2038,TAS Typical Summer,0 +01/12/2038,TAS Typical Summer,-1 +01/03/2039,TAS Typical Summer,0 +01/12/2039,TAS Typical Summer,-1 +01/03/2040,TAS Typical Summer,0 +01/12/2040,TAS Typical Summer,-1 +01/03/2041,TAS Typical Summer,0 +01/12/2041,TAS Typical Summer,-1 +01/03/2042,TAS Typical Summer,0 +01/12/2042,TAS Typical Summer,-1 +01/03/2043,TAS Typical Summer,0 +01/12/2043,TAS Typical Summer,-1 +01/03/2044,TAS Typical Summer,0 +01/12/2044,TAS Typical Summer,-1 +01/03/2045,TAS Typical Summer,0 +01/12/2045,TAS Typical Summer,-1 +01/03/2046,TAS Typical Summer,0 +01/12/2046,TAS Typical Summer,-1 +01/03/2047,TAS Typical Summer,0 +01/12/2047,TAS Typical Summer,-1 +01/03/2048,TAS Typical Summer,0 +01/12/2048,TAS Typical Summer,-1 +01/03/2049,TAS Typical Summer,0 +01/12/2049,TAS Typical Summer,-1 +01/03/2050,TAS Typical Summer,0 +01/12/2050,TAS Typical Summer,-1 +01/03/2051,TAS Typical Summer,0 +01/12/2051,TAS Typical Summer,-1 +01/03/2052,TAS Typical Summer,0 +01/12/2052,TAS Typical Summer,-1 +01/03/2053,TAS Typical Summer,0 +01/12/2053,TAS Typical Summer,-1 +01/03/2054,TAS Typical Summer,0 +01/12/2054,TAS Typical Summer,-1 +01/03/2055,TAS Typical Summer,0 +01/12/2055,TAS Typical Summer,-1 +01/03/2056,TAS Typical Summer,0 +01/12/2056,TAS Typical Summer,-1 +01/03/2057,TAS Typical Summer,0 +01/12/2057,TAS Typical Summer,-1 +01/03/2058,TAS Typical Summer,0 +30/06/2021,TAS Winter,-1 +01/12/2021,TAS Winter,0 +01/03/2022,TAS Winter,-1 +01/12/2022,TAS Winter,0 +01/03/2023,TAS Winter,-1 +01/12/2023,TAS Winter,0 +01/03/2024,TAS Winter,-1 +01/12/2024,TAS Winter,0 +01/03/2025,TAS Winter,-1 +01/12/2025,TAS Winter,0 +01/03/2026,TAS Winter,-1 +01/12/2026,TAS Winter,0 +01/03/2027,TAS Winter,-1 +01/12/2027,TAS Winter,0 +01/03/2028,TAS Winter,-1 +01/12/2028,TAS Winter,0 +01/03/2029,TAS Winter,-1 +01/12/2029,TAS Winter,0 +01/03/2030,TAS Winter,-1 +01/12/2030,TAS Winter,0 +01/03/2031,TAS Winter,-1 +01/12/2031,TAS Winter,0 +01/03/2032,TAS Winter,-1 +01/12/2032,TAS Winter,0 +01/03/2033,TAS Winter,-1 +01/12/2033,TAS Winter,0 +01/03/2034,TAS Winter,-1 +01/12/2034,TAS Winter,0 +01/03/2035,TAS Winter,-1 +01/12/2035,TAS Winter,0 +01/03/2036,TAS Winter,-1 +01/12/2036,TAS Winter,0 +01/03/2037,TAS Winter,-1 +01/12/2037,TAS Winter,0 +01/03/2038,TAS Winter,-1 +01/12/2038,TAS Winter,0 +01/03/2039,TAS Winter,-1 +01/12/2039,TAS Winter,0 +01/03/2040,TAS Winter,-1 +01/12/2040,TAS Winter,0 +01/03/2041,TAS Winter,-1 +01/12/2041,TAS Winter,0 +01/03/2042,TAS Winter,-1 +01/12/2042,TAS Winter,0 +01/03/2043,TAS Winter,-1 +01/12/2043,TAS Winter,0 +01/03/2044,TAS Winter,-1 +01/12/2044,TAS Winter,0 +01/03/2045,TAS Winter,-1 +01/12/2045,TAS Winter,0 +01/03/2046,TAS Winter,-1 +01/12/2046,TAS Winter,0 +01/03/2047,TAS Winter,-1 +01/12/2047,TAS Winter,0 +01/03/2048,TAS Winter,-1 +01/12/2048,TAS Winter,0 +01/03/2049,TAS Winter,-1 +01/12/2049,TAS Winter,0 +01/03/2050,TAS Winter,-1 +01/12/2050,TAS Winter,0 +01/03/2051,TAS Winter,-1 +01/12/2051,TAS Winter,0 +01/03/2052,TAS Winter,-1 +01/12/2052,TAS Winter,0 +01/03/2053,TAS Winter,-1 +01/12/2053,TAS Winter,0 +01/03/2054,TAS Winter,-1 +01/12/2054,TAS Winter,0 +01/03/2055,TAS Winter,-1 +01/12/2055,TAS Winter,0 +01/03/2056,TAS Winter,-1 +01/12/2056,TAS Winter,0 +01/03/2057,TAS Winter,-1 +01/12/2057,TAS Winter,0 +01/03/2058,TAS Winter,-1 +30/06/2021,VIC Hot Day,0 +30/12/2021,VIC Hot Day,-1 +02/01/2022,VIC Hot Day,0 +13/01/2022,VIC Hot Day,-1 +14/01/2022,VIC Hot Day,0 +26/01/2022,VIC Hot Day,-1 +27/01/2022,VIC Hot Day,0 +27/12/2022,VIC Hot Day,-1 +28/12/2022,VIC Hot Day,0 +14/01/2023,VIC Hot Day,-1 +15/01/2023,VIC Hot Day,0 +17/01/2023,VIC Hot Day,-1 +18/01/2023,VIC Hot Day,0 +16/02/2023,VIC Hot Day,-1 +18/02/2023,VIC Hot Day,0 +04/02/2024,VIC Hot Day,-1 +05/02/2024,VIC Hot Day,0 +13/02/2024,VIC Hot Day,-1 +14/02/2024,VIC Hot Day,0 +28/02/2024,VIC Hot Day,-1 +29/02/2024,VIC Hot Day,0 +09/03/2024,VIC Hot Day,-1 +11/03/2024,VIC Hot Day,0 +16/12/2024,VIC Hot Day,-1 +17/12/2024,VIC Hot Day,0 +05/01/2025,VIC Hot Day,-1 +06/01/2025,VIC Hot Day,0 +27/01/2025,VIC Hot Day,-1 +28/01/2025,VIC Hot Day,0 +02/02/2025,VIC Hot Day,-1 +04/02/2025,VIC Hot Day,0 +02/01/2026,VIC Hot Day,-1 +04/01/2026,VIC Hot Day,0 +07/01/2026,VIC Hot Day,-1 +08/01/2026,VIC Hot Day,0 +06/02/2026,VIC Hot Day,-1 +07/02/2026,VIC Hot Day,0 +21/02/2026,VIC Hot Day,-1 +22/02/2026,VIC Hot Day,0 +31/12/2026,VIC Hot Day,-1 +01/01/2027,VIC Hot Day,0 +07/01/2027,VIC Hot Day,-1 +09/01/2027,VIC Hot Day,0 +30/01/2027,VIC Hot Day,-1 +31/01/2027,VIC Hot Day,0 +01/02/2027,VIC Hot Day,-1 +02/02/2027,VIC Hot Day,0 +18/11/2027,VIC Hot Day,-1 +19/11/2027,VIC Hot Day,0 +02/01/2028,VIC Hot Day,-1 +03/01/2028,VIC Hot Day,0 +17/01/2028,VIC Hot Day,-1 +18/01/2028,VIC Hot Day,0 +23/01/2028,VIC Hot Day,-1 +24/01/2028,VIC Hot Day,0 +25/02/2028,VIC Hot Day,-1 +26/02/2028,VIC Hot Day,0 +29/11/2028,VIC Hot Day,-1 +30/11/2028,VIC Hot Day,0 +23/12/2028,VIC Hot Day,-1 +24/12/2028,VIC Hot Day,0 +04/01/2029,VIC Hot Day,-1 +05/01/2029,VIC Hot Day,0 +17/01/2029,VIC Hot Day,-1 +18/01/2029,VIC Hot Day,0 +06/02/2029,VIC Hot Day,-1 +07/02/2029,VIC Hot Day,0 +14/01/2030,VIC Hot Day,-1 +18/01/2030,VIC Hot Day,0 +28/01/2030,VIC Hot Day,-1 +29/01/2030,VIC Hot Day,0 +08/02/2030,VIC Hot Day,-1 +10/02/2030,VIC Hot Day,0 +02/01/2031,VIC Hot Day,-1 +04/01/2031,VIC Hot Day,0 +07/01/2031,VIC Hot Day,-1 +08/01/2031,VIC Hot Day,0 +06/02/2031,VIC Hot Day,-1 +07/02/2031,VIC Hot Day,0 +21/02/2031,VIC Hot Day,-1 +22/02/2031,VIC Hot Day,0 +19/12/2031,VIC Hot Day,-1 +20/12/2031,VIC Hot Day,0 +31/12/2031,VIC Hot Day,-1 +01/01/2032,VIC Hot Day,0 +13/01/2032,VIC Hot Day,-1 +14/01/2032,VIC Hot Day,0 +23/02/2032,VIC Hot Day,-1 +24/02/2032,VIC Hot Day,0 +08/03/2032,VIC Hot Day,-1 +09/03/2032,VIC Hot Day,0 +13/12/2032,VIC Hot Day,-1 +14/12/2032,VIC Hot Day,0 +25/12/2032,VIC Hot Day,-1 +26/12/2032,VIC Hot Day,0 +28/12/2032,VIC Hot Day,-1 +29/12/2032,VIC Hot Day,0 +17/01/2033,VIC Hot Day,-1 +18/01/2033,VIC Hot Day,0 +23/01/2033,VIC Hot Day,-1 +24/01/2033,VIC Hot Day,0 +06/01/2034,VIC Hot Day,-1 +07/01/2034,VIC Hot Day,0 +18/01/2034,VIC Hot Day,-1 +20/01/2034,VIC Hot Day,0 +28/01/2034,VIC Hot Day,-1 +29/01/2034,VIC Hot Day,0 +07/02/2034,VIC Hot Day,-1 +08/02/2034,VIC Hot Day,0 +07/12/2034,VIC Hot Day,-1 +08/12/2034,VIC Hot Day,0 +04/01/2035,VIC Hot Day,-1 +05/01/2035,VIC Hot Day,0 +24/01/2035,VIC Hot Day,-1 +26/01/2035,VIC Hot Day,0 +01/03/2035,VIC Hot Day,-1 +02/03/2035,VIC Hot Day,0 +21/11/2035,VIC Hot Day,-1 +22/11/2035,VIC Hot Day,0 +18/12/2035,VIC Hot Day,-1 +19/12/2035,VIC Hot Day,0 +20/12/2035,VIC Hot Day,-1 +21/12/2035,VIC Hot Day,0 +30/12/2035,VIC Hot Day,-1 +31/12/2035,VIC Hot Day,0 +30/01/2036,VIC Hot Day,-1 +01/02/2036,VIC Hot Day,0 +19/11/2036,VIC Hot Day,-1 +20/11/2036,VIC Hot Day,0 +27/11/2036,VIC Hot Day,-1 +28/11/2036,VIC Hot Day,0 +11/01/2037,VIC Hot Day,-1 +12/01/2037,VIC Hot Day,0 +24/01/2037,VIC Hot Day,-1 +26/01/2037,VIC Hot Day,0 +30/12/2037,VIC Hot Day,-1 +02/01/2038,VIC Hot Day,0 +13/01/2038,VIC Hot Day,-1 +14/01/2038,VIC Hot Day,0 +26/01/2038,VIC Hot Day,-1 +27/01/2038,VIC Hot Day,0 +27/12/2038,VIC Hot Day,-1 +28/12/2038,VIC Hot Day,0 +14/01/2039,VIC Hot Day,-1 +15/01/2039,VIC Hot Day,0 +17/01/2039,VIC Hot Day,-1 +18/01/2039,VIC Hot Day,0 +16/02/2039,VIC Hot Day,-1 +18/02/2039,VIC Hot Day,0 +04/02/2040,VIC Hot Day,-1 +05/02/2040,VIC Hot Day,0 +13/02/2040,VIC Hot Day,-1 +14/02/2040,VIC Hot Day,0 +28/02/2040,VIC Hot Day,-1 +29/02/2040,VIC Hot Day,0 +09/03/2040,VIC Hot Day,-1 +11/03/2040,VIC Hot Day,0 +16/12/2040,VIC Hot Day,-1 +17/12/2040,VIC Hot Day,0 +05/01/2041,VIC Hot Day,-1 +06/01/2041,VIC Hot Day,0 +27/01/2041,VIC Hot Day,-1 +28/01/2041,VIC Hot Day,0 +02/02/2041,VIC Hot Day,-1 +04/02/2041,VIC Hot Day,0 +02/01/2042,VIC Hot Day,-1 +04/01/2042,VIC Hot Day,0 +07/01/2042,VIC Hot Day,-1 +08/01/2042,VIC Hot Day,0 +06/02/2042,VIC Hot Day,-1 +07/02/2042,VIC Hot Day,0 +21/02/2042,VIC Hot Day,-1 +22/02/2042,VIC Hot Day,0 +31/12/2042,VIC Hot Day,-1 +01/01/2043,VIC Hot Day,0 +07/01/2043,VIC Hot Day,-1 +09/01/2043,VIC Hot Day,0 +30/01/2043,VIC Hot Day,-1 +31/01/2043,VIC Hot Day,0 +01/02/2043,VIC Hot Day,-1 +02/02/2043,VIC Hot Day,0 +18/11/2043,VIC Hot Day,-1 +19/11/2043,VIC Hot Day,0 +02/01/2044,VIC Hot Day,-1 +03/01/2044,VIC Hot Day,0 +17/01/2044,VIC Hot Day,-1 +18/01/2044,VIC Hot Day,0 +23/01/2044,VIC Hot Day,-1 +24/01/2044,VIC Hot Day,0 +25/02/2044,VIC Hot Day,-1 +26/02/2044,VIC Hot Day,0 +29/11/2044,VIC Hot Day,-1 +30/11/2044,VIC Hot Day,0 +23/12/2044,VIC Hot Day,-1 +24/12/2044,VIC Hot Day,0 +04/01/2045,VIC Hot Day,-1 +05/01/2045,VIC Hot Day,0 +17/01/2045,VIC Hot Day,-1 +18/01/2045,VIC Hot Day,0 +06/02/2045,VIC Hot Day,-1 +07/02/2045,VIC Hot Day,0 +14/01/2046,VIC Hot Day,-1 +18/01/2046,VIC Hot Day,0 +28/01/2046,VIC Hot Day,-1 +29/01/2046,VIC Hot Day,0 +08/02/2046,VIC Hot Day,-1 +10/02/2046,VIC Hot Day,0 +02/01/2047,VIC Hot Day,-1 +04/01/2047,VIC Hot Day,0 +07/01/2047,VIC Hot Day,-1 +08/01/2047,VIC Hot Day,0 +06/02/2047,VIC Hot Day,-1 +07/02/2047,VIC Hot Day,0 +21/02/2047,VIC Hot Day,-1 +22/02/2047,VIC Hot Day,0 +19/12/2047,VIC Hot Day,-1 +20/12/2047,VIC Hot Day,0 +31/12/2047,VIC Hot Day,-1 +01/01/2048,VIC Hot Day,0 +13/01/2048,VIC Hot Day,-1 +14/01/2048,VIC Hot Day,0 +23/02/2048,VIC Hot Day,-1 +24/02/2048,VIC Hot Day,0 +08/03/2048,VIC Hot Day,-1 +09/03/2048,VIC Hot Day,0 +13/12/2048,VIC Hot Day,-1 +14/12/2048,VIC Hot Day,0 +25/12/2048,VIC Hot Day,-1 +26/12/2048,VIC Hot Day,0 +28/12/2048,VIC Hot Day,-1 +29/12/2048,VIC Hot Day,0 +17/01/2049,VIC Hot Day,-1 +18/01/2049,VIC Hot Day,0 +23/01/2049,VIC Hot Day,-1 +24/01/2049,VIC Hot Day,0 +06/01/2050,VIC Hot Day,-1 +07/01/2050,VIC Hot Day,0 +18/01/2050,VIC Hot Day,-1 +20/01/2050,VIC Hot Day,0 +28/01/2050,VIC Hot Day,-1 +29/01/2050,VIC Hot Day,0 +07/02/2050,VIC Hot Day,-1 +08/02/2050,VIC Hot Day,0 +07/12/2050,VIC Hot Day,-1 +08/12/2050,VIC Hot Day,0 +04/01/2051,VIC Hot Day,-1 +05/01/2051,VIC Hot Day,0 +24/01/2051,VIC Hot Day,-1 +26/01/2051,VIC Hot Day,0 +01/03/2051,VIC Hot Day,-1 +02/03/2051,VIC Hot Day,0 +21/11/2051,VIC Hot Day,-1 +22/11/2051,VIC Hot Day,0 +18/12/2051,VIC Hot Day,-1 +19/12/2051,VIC Hot Day,0 +20/12/2051,VIC Hot Day,-1 +21/12/2051,VIC Hot Day,0 +30/12/2051,VIC Hot Day,-1 +31/12/2051,VIC Hot Day,0 +30/01/2052,VIC Hot Day,-1 +01/02/2052,VIC Hot Day,0 +19/11/2052,VIC Hot Day,-1 +20/11/2052,VIC Hot Day,0 +27/11/2052,VIC Hot Day,-1 +28/11/2052,VIC Hot Day,0 +11/01/2053,VIC Hot Day,-1 +12/01/2053,VIC Hot Day,0 +24/01/2053,VIC Hot Day,-1 +26/01/2053,VIC Hot Day,0 +30/12/2053,VIC Hot Day,-1 +02/01/2054,VIC Hot Day,0 +13/01/2054,VIC Hot Day,-1 +14/01/2054,VIC Hot Day,0 +26/01/2054,VIC Hot Day,-1 +27/01/2054,VIC Hot Day,0 +27/12/2054,VIC Hot Day,-1 +28/12/2054,VIC Hot Day,0 +14/01/2055,VIC Hot Day,-1 +15/01/2055,VIC Hot Day,0 +17/01/2055,VIC Hot Day,-1 +18/01/2055,VIC Hot Day,0 +16/02/2055,VIC Hot Day,-1 +18/02/2055,VIC Hot Day,0 +04/02/2056,VIC Hot Day,-1 +05/02/2056,VIC Hot Day,0 +13/02/2056,VIC Hot Day,-1 +14/02/2056,VIC Hot Day,0 +28/02/2056,VIC Hot Day,-1 +29/02/2056,VIC Hot Day,0 +09/03/2056,VIC Hot Day,-1 +11/03/2056,VIC Hot Day,0 +16/12/2056,VIC Hot Day,-1 +17/12/2056,VIC Hot Day,0 +05/01/2057,VIC Hot Day,-1 +06/01/2057,VIC Hot Day,0 +27/01/2057,VIC Hot Day,-1 +28/01/2057,VIC Hot Day,0 +02/02/2057,VIC Hot Day,-1 +04/02/2057,VIC Hot Day,0 +02/01/2058,VIC Hot Day,-1 +04/01/2058,VIC Hot Day,0 +07/01/2058,VIC Hot Day,-1 +08/01/2058,VIC Hot Day,0 +06/02/2058,VIC Hot Day,-1 +07/02/2058,VIC Hot Day,0 +21/02/2058,VIC Hot Day,-1 +22/02/2058,VIC Hot Day,0 +30/06/2021,VIC Typical Summer,0 +01/11/2021,VIC Typical Summer,-1 +30/12/2021,VIC Typical Summer,0 +02/01/2022,VIC Typical Summer,-1 +13/01/2022,VIC Typical Summer,0 +14/01/2022,VIC Typical Summer,-1 +26/01/2022,VIC Typical Summer,0 +27/01/2022,VIC Typical Summer,-1 +01/04/2022,VIC Typical Summer,0 +01/11/2022,VIC Typical Summer,-1 +27/12/2022,VIC Typical Summer,0 +28/12/2022,VIC Typical Summer,-1 +14/01/2023,VIC Typical Summer,0 +15/01/2023,VIC Typical Summer,-1 +17/01/2023,VIC Typical Summer,0 +18/01/2023,VIC Typical Summer,-1 +16/02/2023,VIC Typical Summer,0 +18/02/2023,VIC Typical Summer,-1 +01/04/2023,VIC Typical Summer,0 +01/11/2023,VIC Typical Summer,-1 +04/02/2024,VIC Typical Summer,0 +05/02/2024,VIC Typical Summer,-1 +13/02/2024,VIC Typical Summer,0 +14/02/2024,VIC Typical Summer,-1 +28/02/2024,VIC Typical Summer,0 +29/02/2024,VIC Typical Summer,-1 +09/03/2024,VIC Typical Summer,0 +11/03/2024,VIC Typical Summer,-1 +01/04/2024,VIC Typical Summer,0 +01/11/2024,VIC Typical Summer,-1 +16/12/2024,VIC Typical Summer,0 +17/12/2024,VIC Typical Summer,-1 +05/01/2025,VIC Typical Summer,0 +06/01/2025,VIC Typical Summer,-1 +27/01/2025,VIC Typical Summer,0 +28/01/2025,VIC Typical Summer,-1 +02/02/2025,VIC Typical Summer,0 +04/02/2025,VIC Typical Summer,-1 +01/04/2025,VIC Typical Summer,0 +01/11/2025,VIC Typical Summer,-1 +02/01/2026,VIC Typical Summer,0 +04/01/2026,VIC Typical Summer,-1 +07/01/2026,VIC Typical Summer,0 +08/01/2026,VIC Typical Summer,-1 +06/02/2026,VIC Typical Summer,0 +07/02/2026,VIC Typical Summer,-1 +21/02/2026,VIC Typical Summer,0 +22/02/2026,VIC Typical Summer,-1 +01/04/2026,VIC Typical Summer,0 +01/11/2026,VIC Typical Summer,-1 +31/12/2026,VIC Typical Summer,0 +01/01/2027,VIC Typical Summer,-1 +07/01/2027,VIC Typical Summer,0 +09/01/2027,VIC Typical Summer,-1 +30/01/2027,VIC Typical Summer,0 +31/01/2027,VIC Typical Summer,-1 +01/02/2027,VIC Typical Summer,0 +02/02/2027,VIC Typical Summer,-1 +01/04/2027,VIC Typical Summer,0 +01/11/2027,VIC Typical Summer,-1 +18/11/2027,VIC Typical Summer,0 +19/11/2027,VIC Typical Summer,-1 +02/01/2028,VIC Typical Summer,0 +03/01/2028,VIC Typical Summer,-1 +17/01/2028,VIC Typical Summer,0 +18/01/2028,VIC Typical Summer,-1 +23/01/2028,VIC Typical Summer,0 +24/01/2028,VIC Typical Summer,-1 +25/02/2028,VIC Typical Summer,0 +26/02/2028,VIC Typical Summer,-1 +01/04/2028,VIC Typical Summer,0 +01/11/2028,VIC Typical Summer,-1 +29/11/2028,VIC Typical Summer,0 +30/11/2028,VIC Typical Summer,-1 +23/12/2028,VIC Typical Summer,0 +24/12/2028,VIC Typical Summer,-1 +04/01/2029,VIC Typical Summer,0 +05/01/2029,VIC Typical Summer,-1 +17/01/2029,VIC Typical Summer,0 +18/01/2029,VIC Typical Summer,-1 +06/02/2029,VIC Typical Summer,0 +07/02/2029,VIC Typical Summer,-1 +01/04/2029,VIC Typical Summer,0 +01/11/2029,VIC Typical Summer,-1 +14/01/2030,VIC Typical Summer,0 +18/01/2030,VIC Typical Summer,-1 +28/01/2030,VIC Typical Summer,0 +29/01/2030,VIC Typical Summer,-1 +08/02/2030,VIC Typical Summer,0 +10/02/2030,VIC Typical Summer,-1 +01/04/2030,VIC Typical Summer,0 +01/11/2030,VIC Typical Summer,-1 +02/01/2031,VIC Typical Summer,0 +04/01/2031,VIC Typical Summer,-1 +07/01/2031,VIC Typical Summer,0 +08/01/2031,VIC Typical Summer,-1 +06/02/2031,VIC Typical Summer,0 +07/02/2031,VIC Typical Summer,-1 +21/02/2031,VIC Typical Summer,0 +22/02/2031,VIC Typical Summer,-1 +01/04/2031,VIC Typical Summer,0 +01/11/2031,VIC Typical Summer,-1 +19/12/2031,VIC Typical Summer,0 +20/12/2031,VIC Typical Summer,-1 +31/12/2031,VIC Typical Summer,0 +01/01/2032,VIC Typical Summer,-1 +13/01/2032,VIC Typical Summer,0 +14/01/2032,VIC Typical Summer,-1 +23/02/2032,VIC Typical Summer,0 +24/02/2032,VIC Typical Summer,-1 +08/03/2032,VIC Typical Summer,0 +09/03/2032,VIC Typical Summer,-1 +01/04/2032,VIC Typical Summer,0 +01/11/2032,VIC Typical Summer,-1 +13/12/2032,VIC Typical Summer,0 +14/12/2032,VIC Typical Summer,-1 +25/12/2032,VIC Typical Summer,0 +26/12/2032,VIC Typical Summer,-1 +28/12/2032,VIC Typical Summer,0 +29/12/2032,VIC Typical Summer,-1 +17/01/2033,VIC Typical Summer,0 +18/01/2033,VIC Typical Summer,-1 +23/01/2033,VIC Typical Summer,0 +24/01/2033,VIC Typical Summer,-1 +01/04/2033,VIC Typical Summer,0 +01/11/2033,VIC Typical Summer,-1 +06/01/2034,VIC Typical Summer,0 +07/01/2034,VIC Typical Summer,-1 +18/01/2034,VIC Typical Summer,0 +20/01/2034,VIC Typical Summer,-1 +28/01/2034,VIC Typical Summer,0 +29/01/2034,VIC Typical Summer,-1 +07/02/2034,VIC Typical Summer,0 +08/02/2034,VIC Typical Summer,-1 +01/04/2034,VIC Typical Summer,0 +01/11/2034,VIC Typical Summer,-1 +07/12/2034,VIC Typical Summer,0 +08/12/2034,VIC Typical Summer,-1 +04/01/2035,VIC Typical Summer,0 +05/01/2035,VIC Typical Summer,-1 +24/01/2035,VIC Typical Summer,0 +26/01/2035,VIC Typical Summer,-1 +01/03/2035,VIC Typical Summer,0 +02/03/2035,VIC Typical Summer,-1 +01/04/2035,VIC Typical Summer,0 +01/11/2035,VIC Typical Summer,-1 +21/11/2035,VIC Typical Summer,0 +22/11/2035,VIC Typical Summer,-1 +18/12/2035,VIC Typical Summer,0 +19/12/2035,VIC Typical Summer,-1 +20/12/2035,VIC Typical Summer,0 +21/12/2035,VIC Typical Summer,-1 +30/12/2035,VIC Typical Summer,0 +31/12/2035,VIC Typical Summer,-1 +30/01/2036,VIC Typical Summer,0 +01/02/2036,VIC Typical Summer,-1 +01/04/2036,VIC Typical Summer,0 +01/11/2036,VIC Typical Summer,-1 +19/11/2036,VIC Typical Summer,0 +20/11/2036,VIC Typical Summer,-1 +27/11/2036,VIC Typical Summer,0 +28/11/2036,VIC Typical Summer,-1 +11/01/2037,VIC Typical Summer,0 +12/01/2037,VIC Typical Summer,-1 +24/01/2037,VIC Typical Summer,0 +26/01/2037,VIC Typical Summer,-1 +01/04/2037,VIC Typical Summer,0 +01/11/2037,VIC Typical Summer,-1 +30/12/2037,VIC Typical Summer,0 +02/01/2038,VIC Typical Summer,-1 +13/01/2038,VIC Typical Summer,0 +14/01/2038,VIC Typical Summer,-1 +26/01/2038,VIC Typical Summer,0 +27/01/2038,VIC Typical Summer,-1 +01/04/2038,VIC Typical Summer,0 +01/11/2038,VIC Typical Summer,-1 +27/12/2038,VIC Typical Summer,0 +28/12/2038,VIC Typical Summer,-1 +14/01/2039,VIC Typical Summer,0 +15/01/2039,VIC Typical Summer,-1 +17/01/2039,VIC Typical Summer,0 +18/01/2039,VIC Typical Summer,-1 +16/02/2039,VIC Typical Summer,0 +18/02/2039,VIC Typical Summer,-1 +01/04/2039,VIC Typical Summer,0 +01/11/2039,VIC Typical Summer,-1 +04/02/2040,VIC Typical Summer,0 +05/02/2040,VIC Typical Summer,-1 +13/02/2040,VIC Typical Summer,0 +14/02/2040,VIC Typical Summer,-1 +28/02/2040,VIC Typical Summer,0 +29/02/2040,VIC Typical Summer,-1 +09/03/2040,VIC Typical Summer,0 +11/03/2040,VIC Typical Summer,-1 +01/04/2040,VIC Typical Summer,0 +01/11/2040,VIC Typical Summer,-1 +16/12/2040,VIC Typical Summer,0 +17/12/2040,VIC Typical Summer,-1 +05/01/2041,VIC Typical Summer,0 +06/01/2041,VIC Typical Summer,-1 +27/01/2041,VIC Typical Summer,0 +28/01/2041,VIC Typical Summer,-1 +02/02/2041,VIC Typical Summer,0 +04/02/2041,VIC Typical Summer,-1 +01/04/2041,VIC Typical Summer,0 +01/11/2041,VIC Typical Summer,-1 +02/01/2042,VIC Typical Summer,0 +04/01/2042,VIC Typical Summer,-1 +07/01/2042,VIC Typical Summer,0 +08/01/2042,VIC Typical Summer,-1 +06/02/2042,VIC Typical Summer,0 +07/02/2042,VIC Typical Summer,-1 +21/02/2042,VIC Typical Summer,0 +22/02/2042,VIC Typical Summer,-1 +01/04/2042,VIC Typical Summer,0 +01/11/2042,VIC Typical Summer,-1 +31/12/2042,VIC Typical Summer,0 +01/01/2043,VIC Typical Summer,-1 +07/01/2043,VIC Typical Summer,0 +09/01/2043,VIC Typical Summer,-1 +30/01/2043,VIC Typical Summer,0 +31/01/2043,VIC Typical Summer,-1 +01/02/2043,VIC Typical Summer,0 +02/02/2043,VIC Typical Summer,-1 +01/04/2043,VIC Typical Summer,0 +01/11/2043,VIC Typical Summer,-1 +18/11/2043,VIC Typical Summer,0 +19/11/2043,VIC Typical Summer,-1 +02/01/2044,VIC Typical Summer,0 +03/01/2044,VIC Typical Summer,-1 +17/01/2044,VIC Typical Summer,0 +18/01/2044,VIC Typical Summer,-1 +23/01/2044,VIC Typical Summer,0 +24/01/2044,VIC Typical Summer,-1 +25/02/2044,VIC Typical Summer,0 +26/02/2044,VIC Typical Summer,-1 +01/04/2044,VIC Typical Summer,0 +01/11/2044,VIC Typical Summer,-1 +29/11/2044,VIC Typical Summer,0 +30/11/2044,VIC Typical Summer,-1 +23/12/2044,VIC Typical Summer,0 +24/12/2044,VIC Typical Summer,-1 +04/01/2045,VIC Typical Summer,0 +05/01/2045,VIC Typical Summer,-1 +17/01/2045,VIC Typical Summer,0 +18/01/2045,VIC Typical Summer,-1 +06/02/2045,VIC Typical Summer,0 +07/02/2045,VIC Typical Summer,-1 +01/04/2045,VIC Typical Summer,0 +01/11/2045,VIC Typical Summer,-1 +14/01/2046,VIC Typical Summer,0 +18/01/2046,VIC Typical Summer,-1 +28/01/2046,VIC Typical Summer,0 +29/01/2046,VIC Typical Summer,-1 +08/02/2046,VIC Typical Summer,0 +10/02/2046,VIC Typical Summer,-1 +01/04/2046,VIC Typical Summer,0 +01/11/2046,VIC Typical Summer,-1 +02/01/2047,VIC Typical Summer,0 +04/01/2047,VIC Typical Summer,-1 +07/01/2047,VIC Typical Summer,0 +08/01/2047,VIC Typical Summer,-1 +06/02/2047,VIC Typical Summer,0 +07/02/2047,VIC Typical Summer,-1 +21/02/2047,VIC Typical Summer,0 +22/02/2047,VIC Typical Summer,-1 +01/04/2047,VIC Typical Summer,0 +01/11/2047,VIC Typical Summer,-1 +19/12/2047,VIC Typical Summer,0 +20/12/2047,VIC Typical Summer,-1 +31/12/2047,VIC Typical Summer,0 +01/01/2048,VIC Typical Summer,-1 +13/01/2048,VIC Typical Summer,0 +14/01/2048,VIC Typical Summer,-1 +23/02/2048,VIC Typical Summer,0 +24/02/2048,VIC Typical Summer,-1 +08/03/2048,VIC Typical Summer,0 +09/03/2048,VIC Typical Summer,-1 +01/04/2048,VIC Typical Summer,0 +01/11/2048,VIC Typical Summer,-1 +13/12/2048,VIC Typical Summer,0 +14/12/2048,VIC Typical Summer,-1 +25/12/2048,VIC Typical Summer,0 +26/12/2048,VIC Typical Summer,-1 +28/12/2048,VIC Typical Summer,0 +29/12/2048,VIC Typical Summer,-1 +17/01/2049,VIC Typical Summer,0 +18/01/2049,VIC Typical Summer,-1 +23/01/2049,VIC Typical Summer,0 +24/01/2049,VIC Typical Summer,-1 +01/04/2049,VIC Typical Summer,0 +01/11/2049,VIC Typical Summer,-1 +06/01/2050,VIC Typical Summer,0 +07/01/2050,VIC Typical Summer,-1 +18/01/2050,VIC Typical Summer,0 +20/01/2050,VIC Typical Summer,-1 +28/01/2050,VIC Typical Summer,0 +29/01/2050,VIC Typical Summer,-1 +07/02/2050,VIC Typical Summer,0 +08/02/2050,VIC Typical Summer,-1 +01/04/2050,VIC Typical Summer,0 +01/11/2050,VIC Typical Summer,-1 +07/12/2050,VIC Typical Summer,0 +08/12/2050,VIC Typical Summer,-1 +04/01/2051,VIC Typical Summer,0 +05/01/2051,VIC Typical Summer,-1 +24/01/2051,VIC Typical Summer,0 +26/01/2051,VIC Typical Summer,-1 +01/03/2051,VIC Typical Summer,0 +02/03/2051,VIC Typical Summer,-1 +01/04/2051,VIC Typical Summer,0 +01/11/2051,VIC Typical Summer,-1 +21/11/2051,VIC Typical Summer,0 +22/11/2051,VIC Typical Summer,-1 +18/12/2051,VIC Typical Summer,0 +19/12/2051,VIC Typical Summer,-1 +20/12/2051,VIC Typical Summer,0 +21/12/2051,VIC Typical Summer,-1 +30/12/2051,VIC Typical Summer,0 +31/12/2051,VIC Typical Summer,-1 +30/01/2052,VIC Typical Summer,0 +01/02/2052,VIC Typical Summer,-1 +01/04/2052,VIC Typical Summer,0 +01/11/2052,VIC Typical Summer,-1 +19/11/2052,VIC Typical Summer,0 +20/11/2052,VIC Typical Summer,-1 +27/11/2052,VIC Typical Summer,0 +28/11/2052,VIC Typical Summer,-1 +11/01/2053,VIC Typical Summer,0 +12/01/2053,VIC Typical Summer,-1 +24/01/2053,VIC Typical Summer,0 +26/01/2053,VIC Typical Summer,-1 +01/04/2053,VIC Typical Summer,0 +01/11/2053,VIC Typical Summer,-1 +30/12/2053,VIC Typical Summer,0 +02/01/2054,VIC Typical Summer,-1 +13/01/2054,VIC Typical Summer,0 +14/01/2054,VIC Typical Summer,-1 +26/01/2054,VIC Typical Summer,0 +27/01/2054,VIC Typical Summer,-1 +01/04/2054,VIC Typical Summer,0 +01/11/2054,VIC Typical Summer,-1 +27/12/2054,VIC Typical Summer,0 +28/12/2054,VIC Typical Summer,-1 +14/01/2055,VIC Typical Summer,0 +15/01/2055,VIC Typical Summer,-1 +17/01/2055,VIC Typical Summer,0 +18/01/2055,VIC Typical Summer,-1 +16/02/2055,VIC Typical Summer,0 +18/02/2055,VIC Typical Summer,-1 +01/04/2055,VIC Typical Summer,0 +01/11/2055,VIC Typical Summer,-1 +04/02/2056,VIC Typical Summer,0 +05/02/2056,VIC Typical Summer,-1 +13/02/2056,VIC Typical Summer,0 +14/02/2056,VIC Typical Summer,-1 +28/02/2056,VIC Typical Summer,0 +29/02/2056,VIC Typical Summer,-1 +09/03/2056,VIC Typical Summer,0 +11/03/2056,VIC Typical Summer,-1 +01/04/2056,VIC Typical Summer,0 +01/11/2056,VIC Typical Summer,-1 +16/12/2056,VIC Typical Summer,0 +17/12/2056,VIC Typical Summer,-1 +05/01/2057,VIC Typical Summer,0 +06/01/2057,VIC Typical Summer,-1 +27/01/2057,VIC Typical Summer,0 +28/01/2057,VIC Typical Summer,-1 +02/02/2057,VIC Typical Summer,0 +04/02/2057,VIC Typical Summer,-1 +01/04/2057,VIC Typical Summer,0 +01/11/2057,VIC Typical Summer,-1 +02/01/2058,VIC Typical Summer,0 +04/01/2058,VIC Typical Summer,-1 +07/01/2058,VIC Typical Summer,0 +08/01/2058,VIC Typical Summer,-1 +06/02/2058,VIC Typical Summer,0 +07/02/2058,VIC Typical Summer,-1 +21/02/2058,VIC Typical Summer,0 +22/02/2058,VIC Typical Summer,-1 +01/04/2058,VIC Typical Summer,0 +30/06/2021,VIC Winter,-1 +01/11/2021,VIC Winter,0 +01/04/2022,VIC Winter,-1 +01/11/2022,VIC Winter,0 +01/04/2023,VIC Winter,-1 +01/11/2023,VIC Winter,0 +01/04/2024,VIC Winter,-1 +01/11/2024,VIC Winter,0 +01/04/2025,VIC Winter,-1 +01/11/2025,VIC Winter,0 +01/04/2026,VIC Winter,-1 +01/11/2026,VIC Winter,0 +01/04/2027,VIC Winter,-1 +01/11/2027,VIC Winter,0 +01/04/2028,VIC Winter,-1 +01/11/2028,VIC Winter,0 +01/04/2029,VIC Winter,-1 +01/11/2029,VIC Winter,0 +01/04/2030,VIC Winter,-1 +01/11/2030,VIC Winter,0 +01/04/2031,VIC Winter,-1 +01/11/2031,VIC Winter,0 +01/04/2032,VIC Winter,-1 +01/11/2032,VIC Winter,0 +01/04/2033,VIC Winter,-1 +01/11/2033,VIC Winter,0 +01/04/2034,VIC Winter,-1 +01/11/2034,VIC Winter,0 +01/04/2035,VIC Winter,-1 +01/11/2035,VIC Winter,0 +01/04/2036,VIC Winter,-1 +01/11/2036,VIC Winter,0 +01/04/2037,VIC Winter,-1 +01/11/2037,VIC Winter,0 +01/04/2038,VIC Winter,-1 +01/11/2038,VIC Winter,0 +01/04/2039,VIC Winter,-1 +01/11/2039,VIC Winter,0 +01/04/2040,VIC Winter,-1 +01/11/2040,VIC Winter,0 +01/04/2041,VIC Winter,-1 +01/11/2041,VIC Winter,0 +01/04/2042,VIC Winter,-1 +01/11/2042,VIC Winter,0 +01/04/2043,VIC Winter,-1 +01/11/2043,VIC Winter,0 +01/04/2044,VIC Winter,-1 +01/11/2044,VIC Winter,0 +01/04/2045,VIC Winter,-1 +01/11/2045,VIC Winter,0 +01/04/2046,VIC Winter,-1 +01/11/2046,VIC Winter,0 +01/04/2047,VIC Winter,-1 +01/11/2047,VIC Winter,0 +01/04/2048,VIC Winter,-1 +01/11/2048,VIC Winter,0 +01/04/2049,VIC Winter,-1 +01/11/2049,VIC Winter,0 +01/04/2050,VIC Winter,-1 +01/11/2050,VIC Winter,0 +01/04/2051,VIC Winter,-1 +01/11/2051,VIC Winter,0 +01/04/2052,VIC Winter,-1 +01/11/2052,VIC Winter,0 +01/04/2053,VIC Winter,-1 +01/11/2053,VIC Winter,0 +01/04/2054,VIC Winter,-1 +01/11/2054,VIC Winter,0 +01/04/2055,VIC Winter,-1 +01/11/2055,VIC Winter,0 +01/04/2056,VIC Winter,-1 +01/11/2056,VIC Winter,0 +01/04/2057,VIC Winter,-1 +01/11/2057,VIC Winter,0 +01/04/2058,VIC Winter,-1 diff --git a/src/ispypsa/templater/timeslices.py b/src/ispypsa/templater/timeslices.py new file mode 100644 index 00000000..ab999d71 --- /dev/null +++ b/src/ispypsa/templater/timeslices.py @@ -0,0 +1,296 @@ +"""Templates the per-reference-year timeslice window patterns. + +AEMO's PLEXOS data package ships a timeslice calendar (e.g. +``timeslice_RefYear5000.csv``) of on/off events on absolute dates across the +model horizon. The dates follow AEMO's rolling reference-year sequence: each +planning financial year's windows are derived from the weather of the +reference year assigned to it by Table 1 of the Draft 2026 ISP Market Model +Instructions, with the 16-year sequence repeating until the end of the +horizon. The templater inverts this: it assigns each calendar window to its +planning year, joins on the manually extracted sequence table, checks every +occurrence of a reference year carries an identical month-day pattern, and +emits one window pattern per reference year. The translator re-sequences the +patterns to match the user-configured reference_year_cycle, keeping +timeslices consistent with the demand and VRE traces. +""" + +from importlib.resources import files + +import pandas as pd + +from ispypsa.templater.custom_constraints_from_plexos import _tag_to_timeslice + +_TIMESLICE_COLUMNS = [ + "timeslice_id", + "reference_year", + "start_month_day", + "end_month_day", +] + +# The PLEXOS timeslice calendar shipped for each supported workbook version. +# The "RefYearNNNN" suffix is AEMO's identifier for the reference-year +# sequence the calendar was built with. +_TIMESLICE_CALENDAR_FILENAMES = {"7.5": "timeslice_RefYear5000.csv"} + + +def load_timeslice_calendar(iasr_workbook_version: str) -> pd.DataFrame: + """Loads the PLEXOS timeslice calendar shipped with ISPyPSA for the + given IASR workbook version (from ``src/ispypsa/templater/plexos/``).""" + extract_dir = files("ispypsa.templater") / "plexos" / iasr_workbook_version + return pd.read_csv( + extract_dir / _TIMESLICE_CALENDAR_FILENAMES[iasr_workbook_version] + ) + + +def _template_timeslices( + timeslice_calendar: pd.DataFrame, reference_year_sequence: pd.DataFrame +) -> pd.DataFrame: + """Decodes the PLEXOS on/off timeslice calendar into one month-day window + pattern per reference year. + + The raw calendar has one row per on/off event: TIMESLICE == -1 turns the + named timeslice on at DATETIME, TIMESLICE == 0 turns it off. Each on + event is paired with the next event for the same timeslice to form one + active window. Windows are grouped into the planning financial year they + start in and labelled with that year's reference year from + reference_year_sequence (extended cyclically past its last row, matching + AEMO's repeating sequence). Every occurrence of a reference year must + carry an identical pattern; the first occurrence is kept. + + Windows starting before the sequence's first planning year are dropped + (the early calendar years precede AEMO's documented sequence), as are + windows still open when the calendar ends (a horizon artifact). + + I/O Example: + timeslice_calendar: + DATETIME NAME TIMESLICE + 30/06/2025 NSW Hot Day 0 # off with no preceding on: ignored + 18/11/2025 NSW Hot Day -1 + 20/11/2025 NSW Hot Day 0 + 18/11/2041 NSW Hot Day -1 # 2041-42: sequence repeats from 2026 + 20/11/2041 NSW Hot Day 0 + 01/04/2058 NSW Winter -1 # never turned off: dropped + + reference_year_sequence: + planning_year reference_year + 2026 2015 + + returns: + timeslice_id reference_year start_month_day end_month_day + nsw_peak_demand 2015 11-18 11-20 # end exclusive + """ + events = _parse_calendar_events(timeslice_calendar) + events = _add_next_event_columns(events) + _raise_on_consecutive_on_events(events) + windows = _assign_windows_to_planning_years(_extract_windows(events)) + windows = _drop_horizon_truncated_planning_years(windows) + if windows.empty or reference_year_sequence.empty: + return pd.DataFrame(columns=_TIMESLICE_COLUMNS) + sequence = _extend_sequence_to_horizon(reference_year_sequence, windows) + patterns = _convert_windows_to_month_days( + windows.merge(sequence, on="planning_year") + ) + _raise_on_inconsistent_reference_year_patterns(patterns) + return _keep_first_occurrence_per_reference_year(patterns) + + +def _parse_calendar_events(calendar: pd.DataFrame) -> pd.DataFrame: + """Maps calendar names to canonical timeslice ids and orders the events. + + I/O Example: + DATETIME=18/11/2021, NAME="NSW Hot Day", TIMESLICE=-1 + -> DATETIME=2021-11-18, timeslice_id="nsw_peak_demand", TIMESLICE=-1 + """ + events = calendar.copy() + events["DATETIME"] = pd.to_datetime(events["DATETIME"], dayfirst=True) + events["timeslice_id"] = events["NAME"].map(_tag_to_timeslice) + return events.sort_values(["timeslice_id", "DATETIME"]) + + +def _add_next_event_columns(events: pd.DataFrame) -> pd.DataFrame: + """Annotates each event with the date and state of the next event for the + same timeslice (NaN/NaT on each timeslice's last event). + + I/O Example: + timeslice_id DATETIME TIMESLICE + nsw_peak_demand 2021-11-18 -1 + nsw_peak_demand 2021-11-20 0 + + -> + timeslice_id DATETIME TIMESLICE next_date next_state + nsw_peak_demand 2021-11-18 -1 2021-11-20 0 + nsw_peak_demand 2021-11-20 0 NaT NaN + """ + grouped = events.groupby("timeslice_id") + events["next_date"] = grouped["DATETIME"].shift(-1) + events["next_state"] = grouped["TIMESLICE"].shift(-1) + return events + + +def _raise_on_consecutive_on_events(events: pd.DataFrame) -> None: + """Raise if any on event is directly followed by another on event for the + same timeslice — pairing on events with the next event would silently + produce wrong windows otherwise. An on event with no following event is + fine: the calendar legitimately ends with windows still open (e.g. winter + turning on at the horizon's end).""" + on_events = events[events["TIMESLICE"] == -1] + doubled = on_events[on_events["next_state"] == -1] + if not doubled.empty: + dates = sorted(doubled["DATETIME"].dt.strftime("%Y-%m-%d")) + raise ValueError( + f"Timeslice calendar has on events directly followed by another " + f"on event for the same timeslice, starting at: {dates}" + ) + + +def _extract_windows(events: pd.DataFrame) -> pd.DataFrame: + """Turns each on event into a window row ending at the paired off event. + + I/O Example: + timeslice_id DATETIME TIMESLICE next_date next_state + nsw_peak_demand 2021-11-18 -1 2021-11-20 0 + nsw_peak_demand 2021-11-20 0 NaT NaN + + returns: + timeslice_id start_date end_date + nsw_peak_demand 2021-11-18 2021-11-20 + """ + windows = events[events["TIMESLICE"] == -1] + windows = windows.rename( + columns={"DATETIME": "start_date", "next_date": "end_date"} + ) + return windows[["timeslice_id", "start_date", "end_date"]].reset_index(drop=True) + + +def _drop_horizon_truncated_planning_years(windows: pd.DataFrame) -> pd.DataFrame: + """Drops every window in planning years where the calendar ends with a + window still open (e.g. winter turning on just before the horizon's end + and never turning off). Keeping the year's other windows would make its + pattern incomplete and fail the consistency check against earlier, fully + covered occurrences of the same reference year — which is also why + nothing is lost by dropping the year entirely. + + I/O Example: + timeslice_id start_date end_date planning_year + nsw_peak_demand 2057-11-18 2057-11-20 2058 # dropped: shares + nsw_winter_reference 2058-04-01 NaT 2058 # the truncated year + nsw_peak_demand 2056-11-18 2056-11-20 2057 # kept + + returns the 2057 row only. + """ + truncated_years = set(windows.loc[windows["end_date"].isna(), "planning_year"]) + keep = ~windows["planning_year"].isin(truncated_years) + return windows[keep].reset_index(drop=True) + + +def _assign_windows_to_planning_years(windows: pd.DataFrame) -> pd.DataFrame: + """Tags each window with the planning financial year it starts in + (year-ending convention: FY2026 spans July 2025 to June 2026). + + I/O Example: + start_date 2025-11-16 -> planning_year 2026 + start_date 2026-04-01 -> planning_year 2026 + """ + starts = windows["start_date"] + windows["planning_year"] = starts.dt.year + (starts.dt.month >= 7).astype(int) + return windows + + +def _extend_sequence_to_horizon( + sequence: pd.DataFrame, windows: pd.DataFrame +) -> pd.DataFrame: + """Cyclically repeats the documented reference-year sequence to cover + every planning year in the calendar — AEMO: "the 16-year sequence + repeating in the same order until the end of the outlook period". Only + the windows' latest planning_year is used; if the windows end before the + sequence does, the sequence is returned unshortened. + + I/O Example: + sequence: + planning_year reference_year + 2026 2015 + 2027 2011 + + windows (only planning_year is read): + timeslice_id start_date end_date planning_year + nsw_peak_demand 2028-11-18 2028-11-20 2029 + + returns: + planning_year reference_year + 2026 2015 + 2027 2011 + 2028 2015 # cycle repeats + 2029 2011 + """ + sequence = sequence.sort_values("planning_year").reset_index(drop=True) + first = sequence["planning_year"].iloc[0] + last = max(windows["planning_year"].max(), sequence["planning_year"].max()) + years = range(first, last + 1) + reference_years = [ + sequence["reference_year"].iloc[(year - first) % len(sequence)] + for year in years + ] + return pd.DataFrame({"planning_year": years, "reference_year": reference_years}) + + +def _convert_windows_to_month_days(windows: pd.DataFrame) -> pd.DataFrame: + """Expresses each window's dates as month-day strings. The end is + exclusive and, when re-expanded into a financial year, is interpreted as + its first occurrence after the start (so 11-18 -> 03-20 wraps into the + next calendar year, and winter's 04-01 -> 10-01 extends past 30 June). + + I/O Example: + timeslice_id start_date end_date planning_year reference_year + nsw_peak_demand 2025-11-18 2025-11-20 2026 2015 + + -> + timeslice_id reference_year planning_year start_month_day end_month_day + nsw_peak_demand 2015 2026 11-18 11-20 + """ + windows["start_month_day"] = windows["start_date"].dt.strftime("%m-%d") + windows["end_month_day"] = windows["end_date"].dt.strftime("%m-%d") + return windows[ + ["timeslice_id", "reference_year", "planning_year"] + + ["start_month_day", "end_month_day"] + ] + + +def _raise_on_inconsistent_reference_year_patterns(patterns: pd.DataFrame) -> None: + """Raise if two planning years assigned the same reference year carry + different window patterns — that would mean the sequence table (or its + cyclic extension) doesn't match how the calendar was actually built, and + decoding one pattern per reference year would silently lose windows.""" + occurrences = patterns.groupby(["reference_year", "planning_year"]).apply( + lambda x: frozenset( + zip(x["timeslice_id"], x["start_month_day"], x["end_month_day"]) + ), + include_groups=False, + ) + distinct_patterns = occurrences.groupby("reference_year").nunique() + inconsistent = sorted(distinct_patterns[distinct_patterns > 1].index) + if inconsistent: + raise ValueError( + f"Reference years whose timeslice window patterns differ between " + f"planning years in the calendar: {inconsistent}" + ) + + +def _keep_first_occurrence_per_reference_year(patterns: pd.DataFrame) -> pd.DataFrame: + """Keeps each reference year's pattern from its first planning year (all + occurrences are identical — validated before this is called). + + I/O Example: + timeslice_id reference_year planning_year start_month_day end_month_day + nsw_peak_demand 2015 2026 11-18 11-20 + nsw_peak_demand 2015 2031 11-18 11-20 + + returns: + timeslice_id reference_year start_month_day end_month_day + nsw_peak_demand 2015 11-18 11-20 + """ + first_occurrence = patterns.groupby("reference_year")["planning_year"].transform( + "min" + ) + deduped = patterns[patterns["planning_year"] == first_occurrence] + deduped = deduped.drop(columns="planning_year") + return deduped.sort_values(_TIMESLICE_COLUMNS).reset_index(drop=True) diff --git a/src/ispypsa/validation/schemas/timeslices.yaml b/src/ispypsa/validation/schemas/timeslices.yaml new file mode 100644 index 00000000..bae3325e --- /dev/null +++ b/src/ispypsa/validation/schemas/timeslices.yaml @@ -0,0 +1,75 @@ +table: timeslices +required: false +unique: + - [timeslice_id, reference_year, start_month_day] +description: > + Month-day windows during which each demand-condition timeslice is active, + one pattern per reference (weather) year. + + One row per active window. The translator re-sequences the patterns to the + configured reference_year_cycle — each model financial year gets the + windows of the reference year assigned to it, the same assignment used for + demand and VRE traces — to build time-varying transmission path limits and + to restrict custom constraints to the snapshots their RHS values apply to. + + Source tables: + - `timeslice_RefYear5000` (PLEXOS data package extract) + - `reference_year_sequence` (manually extracted) + + Source notes: + The calendar is AEMO's Draft 2026 ISP timeslice trace + (timeslice_RefYear5000.csv), which marks windows on absolute dates across + the model horizon following AEMO's rolling reference-year sequence. The + templater decodes it into one pattern per reference year using the + sequence documented in Table 1 of the Draft 2026 ISP Market Model + Instructions (transcribed as the manually extracted + reference_year_sequence table), validating that every occurrence of a + reference year carries an identical pattern. A timeslice in the canonical + vocabulary may have no windows at all (e.g. tas_peak_demand never + activates in the Draft 2026 ISP calendar), in which case limits or RHS + values tagged with it are never active. + + If absent: + No timeslice is ever active: timeslice-tagged transmission path limits and + custom-constraint RHS values never apply to any snapshot. +columns: + timeslice_id: + type: string + required: true + allowed_values: [ + qld_peak_demand, qld_summer_typical, qld_winter_reference, + nsw_peak_demand, nsw_summer_typical, nsw_winter_reference, + vic_peak_demand, vic_summer_typical, vic_winter_reference, + sa_peak_demand, sa_summer_typical, sa_winter_reference, + tas_peak_demand, tas_summer_typical, tas_winter_reference, + ] + description: > + Region-prefixed canonical timeslice the window belongs to. Within a + region and reference year, windows of the three timeslices never + overlap. + reference_year: + type: int + required: true + description: > + Reference (weather) year the window pattern belongs to, in financial + year-ending convention (2015 means FY2014-15) — the same convention as + the reference_year_cycle model configuration and the trace data parsed + by isp-trace-parser. + start_month_day: + type: string + required: true + format: "%m-%d" + description: > + First day of the window (inclusive), e.g. "11-18". Windows belong to + the financial year they start in: months July-December fall in the + financial year's first calendar year, January-June in its second. + end_month_day: + type: string + required: true + format: "%m-%d" + description: > + Day the window ends (exclusive), interpreted as its first occurrence + after the start — "11-18" to "03-20" wraps into the next calendar + year, and winter's "04-01" to "10-01" extends past 30 June into the + next financial year. "02-29" boundaries (from leap reference years) + are clamped to "02-28" when expanded into non-leap model years. diff --git a/tests/test_templater/test_timeslices.py b/tests/test_templater/test_timeslices.py new file mode 100644 index 00000000..2688aa57 --- /dev/null +++ b/tests/test_templater/test_timeslices.py @@ -0,0 +1,216 @@ +import pandas as pd +import pytest + +from ispypsa.templater.timeslices import _template_timeslices + + +def test_template_timeslices_decodes_one_pattern_per_reference_year(csv_str_to_df): + timeslice_calendar = csv_str_to_df(""" + DATETIME, NAME, TIMESLICE + 30/06/2025, NSW Hot Day, 0 + 18/11/2025, NSW Hot Day, -1 + 20/11/2025, NSW Hot Day, 0 + 20/11/2025, NSW Typical Summer, -1 + 20/03/2026, NSW Typical Summer, 0 + 01/04/2026, QLD Winter, -1 + 01/10/2026, QLD Winter, 0 + 10/12/2026, NSW Hot Day, -1 + 12/12/2026, NSW Hot Day, 0 + """) + reference_year_sequence = csv_str_to_df(""" + planning_year, reference_year + 2026, 2015 + 2027, 2011 + """) + + result = _template_timeslices(timeslice_calendar, reference_year_sequence) + + # The QLD winter window starts in FY2026 and ends past 30 June; it + # belongs to FY2026's reference year. The typical summer end wraps past + # the new year. + expected = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_peak_demand, 2011, 12-10, 12-12 + nsw_peak_demand, 2015, 11-18, 11-20 + nsw_summer_typical, 2015, 11-20, 03-20 + qld_winter_reference, 2015, 04-01, 10-01 + """) + pd.testing.assert_frame_equal(result, expected) + + +def test_template_timeslices_deduplicates_repeated_reference_year(csv_str_to_df): + timeslice_calendar = csv_str_to_df(""" + DATETIME, NAME, TIMESLICE + 18/11/2025, NSW Hot Day, -1 + 20/11/2025, NSW Hot Day, 0 + 18/11/2030, NSW Hot Day, -1 + 20/11/2030, NSW Hot Day, 0 + """) + reference_year_sequence = csv_str_to_df(""" + planning_year, reference_year + 2026, 2015 + 2027, 2011 + 2028, 2012 + 2029, 2013 + 2030, 2014 + 2031, 2015 + """) + + result = _template_timeslices(timeslice_calendar, reference_year_sequence) + + expected = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_peak_demand, 2015, 11-18, 11-20 + """) + pd.testing.assert_frame_equal(result, expected) + + +def test_template_timeslices_extends_sequence_cyclically(csv_str_to_df): + # FY2028 is past the sequence's last row, so the cycle repeats: 2028 gets + # 2026's reference year and must carry the same pattern. + timeslice_calendar = csv_str_to_df(""" + DATETIME, NAME, TIMESLICE + 18/11/2025, NSW Hot Day, -1 + 20/11/2025, NSW Hot Day, 0 + 10/12/2026, NSW Hot Day, -1 + 12/12/2026, NSW Hot Day, 0 + 18/11/2027, NSW Hot Day, -1 + 20/11/2027, NSW Hot Day, 0 + """) + reference_year_sequence = csv_str_to_df(""" + planning_year, reference_year + 2026, 2015 + 2027, 2011 + """) + + result = _template_timeslices(timeslice_calendar, reference_year_sequence) + + expected = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_peak_demand, 2011, 12-10, 12-12 + nsw_peak_demand, 2015, 11-18, 11-20 + """) + pd.testing.assert_frame_equal(result, expected) + + +def test_template_timeslices_raises_on_inconsistent_reference_year_patterns( + csv_str_to_df, +): + timeslice_calendar = csv_str_to_df(""" + DATETIME, NAME, TIMESLICE + 18/11/2025, NSW Hot Day, -1 + 20/11/2025, NSW Hot Day, 0 + 10/12/2027, NSW Hot Day, -1 + 12/12/2027, NSW Hot Day, 0 + """) + reference_year_sequence = csv_str_to_df(""" + planning_year, reference_year + 2026, 2015 + 2027, 2011 + """) + + with pytest.raises(ValueError, match=r"timeslice window patterns differ.*\[2015\]"): + _template_timeslices(timeslice_calendar, reference_year_sequence) + + +def test_template_timeslices_raises_on_consecutive_on_events(csv_str_to_df): + timeslice_calendar = csv_str_to_df(""" + DATETIME, NAME, TIMESLICE + 18/11/2025, NSW Hot Day, -1 + 20/11/2025, NSW Hot Day, -1 + 22/11/2025, NSW Hot Day, 0 + """) + reference_year_sequence = csv_str_to_df(""" + planning_year, reference_year + 2026, 2015 + """) + + with pytest.raises( + ValueError, match=r"directly followed by another on event.*2025-11-18" + ): + _template_timeslices(timeslice_calendar, reference_year_sequence) + + +def test_template_timeslices_drops_horizon_truncated_planning_year(csv_str_to_df): + # FY2027 ends with winter still on (no off event before the calendar + # ends), so all of FY2027's windows are dropped, not just the open one — + # its reference year already has a complete pattern from FY2026. + timeslice_calendar = csv_str_to_df(""" + DATETIME, NAME, TIMESLICE + 18/11/2025, NSW Hot Day, -1 + 20/11/2025, NSW Hot Day, 0 + 01/04/2026, NSW Winter, -1 + 01/10/2026, NSW Winter, 0 + 18/11/2026, NSW Hot Day, -1 + 20/11/2026, NSW Hot Day, 0 + 01/04/2027, NSW Winter, -1 + """) + reference_year_sequence = csv_str_to_df(""" + planning_year, reference_year + 2026, 2015 + 2027, 2015 + """) + + result = _template_timeslices(timeslice_calendar, reference_year_sequence) + + expected = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_peak_demand, 2015, 11-18, 11-20 + nsw_winter_reference, 2015, 04-01, 10-01 + """) + pd.testing.assert_frame_equal(result, expected) + + +def test_template_timeslices_drops_windows_before_sequence_start(csv_str_to_df): + # The real calendar starts several planning years before AEMO's + # documented sequence; those years' windows are dropped. + timeslice_calendar = csv_str_to_df(""" + DATETIME, NAME, TIMESLICE + 18/11/2021, NSW Hot Day, -1 + 20/11/2021, NSW Hot Day, 0 + 10/12/2025, NSW Hot Day, -1 + 12/12/2025, NSW Hot Day, 0 + """) + reference_year_sequence = csv_str_to_df(""" + planning_year, reference_year + 2026, 2015 + """) + + result = _template_timeslices(timeslice_calendar, reference_year_sequence) + + expected = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_peak_demand, 2015, 12-10, 12-12 + """) + pd.testing.assert_frame_equal(result, expected) + + +def test_template_timeslices_empty_calendar(csv_str_to_df): + timeslice_calendar = pd.DataFrame(columns=["DATETIME", "NAME", "TIMESLICE"]) + reference_year_sequence = csv_str_to_df(""" + planning_year, reference_year + 2026, 2015 + """) + + result = _template_timeslices(timeslice_calendar, reference_year_sequence) + + expected = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + """) + pd.testing.assert_frame_equal(result, expected, check_dtype=False) + + +def test_template_timeslices_empty_sequence(csv_str_to_df): + timeslice_calendar = csv_str_to_df(""" + DATETIME, NAME, TIMESLICE + 18/11/2025, NSW Hot Day, -1 + 20/11/2025, NSW Hot Day, 0 + """) + reference_year_sequence = pd.DataFrame(columns=["planning_year", "reference_year"]) + + result = _template_timeslices(timeslice_calendar, reference_year_sequence) + + expected = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + """) + pd.testing.assert_frame_equal(result, expected, check_dtype=False) From ecb25b08ef1b46ecbd0ed2e04941ccdb4262606e Mon Sep 17 00:00:00 2001 From: nick-gorman Date: Fri, 19 Jun 2026 16:12:22 +1000 Subject: [PATCH 2/2] Guard timeslice decode invariants and cover them with tests The templater attributes each calendar window to a reference year by its start date and emits one month-day pattern per reference year. That is only sound while a few structural invariants of AEMO's calendar hold, which were previously assumed silently. Make them fail loud: - partition: each reference year's windows must tile the year exactly (checked inline in _template_timeslices; boundary-based, so leap-safe) - attribution: only winter may cross the 1 July financial-year boundary, and winter must be identical across reference years, so a boundary-crossing window cannot blur reference years (standalone guards, run on the shipped calendar) Also declare the no-overlap and full-coverage rules in the timeslices schema for the future validation layer, and add tests: a shipped-calendar smoke test, focused guard tests, and a leap-day case pinning that the templater preserves 02-29 (clamping to 02-28 in non-leap model years is the translator's job). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/ispypsa/templater/timeslices.py | 126 ++++++++- .../validation/schemas/timeslices.yaml | 19 ++ tests/test_templater/test_timeslices.py | 252 ++++++++++++++++-- 3 files changed, 370 insertions(+), 27 deletions(-) diff --git a/src/ispypsa/templater/timeslices.py b/src/ispypsa/templater/timeslices.py index ab999d71..b7275568 100644 --- a/src/ispypsa/templater/timeslices.py +++ b/src/ispypsa/templater/timeslices.py @@ -55,12 +55,26 @@ def _template_timeslices( start in and labelled with that year's reference year from reference_year_sequence (extended cyclically past its last row, matching AEMO's repeating sequence). Every occurrence of a reference year must - carry an identical pattern; the first occurrence is kept. + carry an identical pattern; the first occurrence is kept. The retained + patterns must partition each reference year's calendar exactly — no day + left uncovered, none covered twice. Windows starting before the sequence's first planning year are dropped (the early calendar years precede AEMO's documented sequence), as are windows still open when the calendar ends (a horizon artifact). + Each window is labelled by the financial year it starts in, so a window + crossing the 1 July boundary keeps its start year's reference year even + though its end falls in the next. That stays sound only because the + weather-varying timeslices (peak, summer) never cross the boundary, so they + sit wholly within one reference year, while the one that does — winter — is + a fixed seasonal frame identical across reference years, so which reference + year "owns" its end never changes the decoded pattern. Both facts are + checked by _raise_unless_only_winter_crosses_financial_year and + _raise_unless_winter_is_constant_per_region (run on the templated table; see + test_shipped_calendar_decodes), not here, so the focused decoder tests can + use minimal data. + I/O Example: timeslice_calendar: DATETIME NAME TIMESLICE @@ -91,7 +105,9 @@ def _template_timeslices( windows.merge(sequence, on="planning_year") ) _raise_on_inconsistent_reference_year_patterns(patterns) - return _keep_first_occurrence_per_reference_year(patterns) + timeslices = _keep_first_occurrence_per_reference_year(patterns) + _raise_unless_windows_tile_the_year(timeslices) + return timeslices def _parse_calendar_events(calendar: pd.DataFrame) -> pd.DataFrame: @@ -294,3 +310,109 @@ def _keep_first_occurrence_per_reference_year(patterns: pd.DataFrame) -> pd.Data deduped = patterns[patterns["planning_year"] == first_occurrence] deduped = deduped.drop(columns="planning_year") return deduped.sort_values(_TIMESLICE_COLUMNS).reset_index(drop=True) + + +def _raise_unless_windows_tile_the_year(timeslices: pd.DataFrame) -> None: + """Raise unless, within every region and reference year, the windows tile + the year exactly — no day left uncovered and none covered twice. A gap there + would let a snapshot fall in no timeslice (silently taking a base limit); an + overlap would let it fall in two. The region is the timeslice_id prefix + before the first underscore. + """ + # add a region column from the timeslice_id prefix (nsw_peak_demand -> nsw) + # to group by, so each region's windows are checked for tiling independently + tagged = timeslices.assign(region=timeslices["timeslice_id"].str.split("_").str[0]) + not_tiling = sorted( + (region, int(year)) + for (region, year), windows in tagged.groupby(["region", "reference_year"]) + if not _windows_tile_the_year(windows) + ) + if not_tiling: + raise ValueError( + f"Timeslice windows must tile each region and reference year's " + f"calendar exactly (no gaps, no overlaps). Offending " + f"region/reference-year pairs: {not_tiling}" + ) + + +def _windows_tile_the_year(windows: pd.DataFrame) -> bool: + """True if the [start_month_day, end_month_day) windows form a gap-free, + overlap-free cycle: sorted by start, each window ends where the next begins, + and the last ends where the first begins. No day arithmetic needed — a gap + or an overlap shows up as an end that does not meet the following start. + + I/O Example: + starts 04-01, 11-01 / ends 11-01, 04-01 -> True # two halves meet and wrap + starts 04-01, 11-01 / ends 10-01, 04-01 -> False # gap from 10-01 to 11-01 + starts 04-01, 11-01 / ends 12-01, 04-01 -> False # overlap from 11-01 to 12-01 + """ + ordered = windows.sort_values("start_month_day") + starts = list(ordered["start_month_day"]) + ends = list(ordered["end_month_day"]) + # rotate starts left by one so each window's end lines up with the next + # window's start; the last window's "next" wraps round to the first + next_starts = starts[1:] + starts[:1] + return ends == next_starts + + +def _raise_unless_only_winter_crosses_financial_year(timeslices: pd.DataFrame) -> None: + """Raise if any non-winter window spans 1 July (the financial-year boundary). + + The decode labels each window by the financial year it starts in, so a + window crossing the boundary keeps its start year's reference year even + though its end falls in the next. That only stays sound if the + weather-varying timeslices (peak, summer) never cross — they must sit wholly + within one reference year. Winter, the fixed seasonal frame, may cross; this + is the assumption documented on _template_timeslices. + """ + spans_july = timeslices.apply( + lambda row: _window_spans_july_first( + row["start_month_day"], row["end_month_day"] + ), + axis=1, + ) + is_winter = timeslices["timeslice_id"].str.endswith("_winter_reference") + crossing = sorted(timeslices.loc[spans_july & ~is_winter, "timeslice_id"].unique()) + if crossing: + raise ValueError( + f"Only winter_reference windows may cross the 1 July financial-year " + f"boundary (weather-varying timeslices must stay within one reference " + f"year); these cross it: {crossing}" + ) + + +def _window_spans_july_first(start_month_day: str, end_month_day: str) -> bool: + """True if the [start, end) month-day window is active across 1 July. The + month-day strings compare chronologically. + + I/O Example: + '04-01', '11-01' -> True # April to November spans 1 July + '11-20', '03-20' -> False # November to March (wraps) does not + """ + if end_month_day > start_month_day: # window does not wrap past year-end + return start_month_day <= "07-01" < end_month_day + return "07-01" >= start_month_day or "07-01" < end_month_day # wraps past year-end + + +def _raise_unless_winter_is_constant_per_region(timeslices: pd.DataFrame) -> None: + """Raise if winter_reference is not the same window in every reference year + of a region. + + Winter is the seasonal frame that crosses the financial-year boundary; the + decode is only blur-free because that crossing window is identical across + reference years, so which reference year owns its end never changes its + value. This is the assumption documented on _template_timeslices. + """ + winter = timeslices[timeslices["timeslice_id"].str.endswith("_winter_reference")] + winter = winter.assign(region=winter["timeslice_id"].str.split("_").str[0]) + varying = sorted( + region + for region, group in winter.groupby("region") + if group[["start_month_day", "end_month_day"]].drop_duplicates().shape[0] > 1 + ) + if varying: + raise ValueError( + f"winter_reference must be the same window in every reference year " + f"(it is the fixed frame the per-reference-year decode relies on); it " + f"varies in regions: {varying}" + ) diff --git a/src/ispypsa/validation/schemas/timeslices.yaml b/src/ispypsa/validation/schemas/timeslices.yaml index bae3325e..e0c1ab96 100644 --- a/src/ispypsa/validation/schemas/timeslices.yaml +++ b/src/ispypsa/validation/schemas/timeslices.yaml @@ -2,6 +2,25 @@ table: timeslices required: false unique: - [timeslice_id, reference_year, start_month_day] +custom_validation: + - name: no_overlapping_windows_per_region_and_reference_year + description: > + Within a region (the timeslice_id prefix before the first underscore) + and reference_year, no two windows may cover the same day. Windows are + compared as expanded [start, end) day ranges, not raw month-day strings: + an end_month_day at or before its start wraps into the following calendar + year (e.g. 11-20 to 03-20), and winter windows run past 30 June into the + next financial year (04-01 to 10-01). + - name: windows_cover_full_year_per_region_and_reference_year + description: > + Within a region (the timeslice_id prefix before the first underscore) + and reference_year, the windows must cover every day of the year, leaving + no day with no active timeslice. Together with + no_overlapping_windows_per_region_and_reference_year this makes the + windows an exact partition of the year: sorted by start, each window ends + where the next begins and the last wraps to the first. A region need not + use all three timeslice types (e.g. tas has no peak_demand) as long as the + windows it does have tile the year. description: > Month-day windows during which each demand-condition timeslice is active, one pattern per reference (weather) year. diff --git a/tests/test_templater/test_timeslices.py b/tests/test_templater/test_timeslices.py index 2688aa57..76386757 100644 --- a/tests/test_templater/test_timeslices.py +++ b/tests/test_templater/test_timeslices.py @@ -1,10 +1,26 @@ import pandas as pd import pytest -from ispypsa.templater.timeslices import _template_timeslices +from ispypsa.templater.manual_tables import load_manually_extracted_tables +from ispypsa.templater.timeslices import ( + _TIMESLICE_COLUMNS, + _convert_windows_to_month_days, + _raise_unless_only_winter_crosses_financial_year, + _raise_unless_windows_tile_the_year, + _raise_unless_winter_is_constant_per_region, + _template_timeslices, + load_timeslice_calendar, +) def test_template_timeslices_decodes_one_pattern_per_reference_year(csv_str_to_df): + # Rows are grouped by region (NSW then QLD), each in date order, so each + # region's year reads top to bottom. + # + # The data is minimal, not realistic: NSW's FY2026 winter ends (18/11/2026) + # before its FY2027 peak begins (10/12/2026). That gap is between two + # reference years, which the templater decodes and checks independently, so + # gaps between reference years are never examined — only each year tiles. timeslice_calendar = csv_str_to_df(""" DATETIME, NAME, TIMESLICE 30/06/2025, NSW Hot Day, 0 @@ -12,10 +28,16 @@ def test_template_timeslices_decodes_one_pattern_per_reference_year(csv_str_to_d 20/11/2025, NSW Hot Day, 0 20/11/2025, NSW Typical Summer, -1 20/03/2026, NSW Typical Summer, 0 - 01/04/2026, QLD Winter, -1 - 01/10/2026, QLD Winter, 0 + 20/03/2026, NSW Winter, -1 + 18/11/2026, NSW Winter, 0 10/12/2026, NSW Hot Day, -1 12/12/2026, NSW Hot Day, 0 + 12/12/2026, NSW Winter, -1 + 10/12/2027, NSW Winter, 0 + 01/10/2025, QLD Typical Summer, -1 + 01/04/2026, QLD Typical Summer, 0 + 01/04/2026, QLD Winter, -1 + 01/10/2026, QLD Winter, 0 """) reference_year_sequence = csv_str_to_df(""" planning_year, reference_year @@ -31,11 +53,20 @@ def test_template_timeslices_decodes_one_pattern_per_reference_year(csv_str_to_d expected = csv_str_to_df(""" timeslice_id, reference_year, start_month_day, end_month_day nsw_peak_demand, 2011, 12-10, 12-12 + nsw_winter_reference, 2011, 12-12, 12-10 nsw_peak_demand, 2015, 11-18, 11-20 nsw_summer_typical, 2015, 11-20, 03-20 + nsw_winter_reference, 2015, 03-20, 11-18 + qld_summer_typical, 2015, 10-01, 04-01 qld_winter_reference, 2015, 04-01, 10-01 """) - pd.testing.assert_frame_equal(result, expected) + # expected rows are grouped by reference year for readability; the templater + # returns them in timeslice_id order, so compare on a shared sort key + sort_key = ["reference_year", "timeslice_id", "start_month_day"] + pd.testing.assert_frame_equal( + result.sort_values(sort_key).reset_index(drop=True), + expected.sort_values(sort_key).reset_index(drop=True), + ) def test_template_timeslices_deduplicates_repeated_reference_year(csv_str_to_df): @@ -43,8 +74,12 @@ def test_template_timeslices_deduplicates_repeated_reference_year(csv_str_to_df) DATETIME, NAME, TIMESLICE 18/11/2025, NSW Hot Day, -1 20/11/2025, NSW Hot Day, 0 + 20/11/2025, NSW Winter, -1 + 18/11/2026, NSW Winter, 0 18/11/2030, NSW Hot Day, -1 20/11/2030, NSW Hot Day, 0 + 20/11/2030, NSW Winter, -1 + 18/11/2031, NSW Winter, 0 """) reference_year_sequence = csv_str_to_df(""" planning_year, reference_year @@ -59,23 +94,30 @@ def test_template_timeslices_deduplicates_repeated_reference_year(csv_str_to_df) result = _template_timeslices(timeslice_calendar, reference_year_sequence) expected = csv_str_to_df(""" - timeslice_id, reference_year, start_month_day, end_month_day - nsw_peak_demand, 2015, 11-18, 11-20 + timeslice_id, reference_year, start_month_day, end_month_day + nsw_peak_demand, 2015, 11-18, 11-20 + nsw_winter_reference, 2015, 11-20, 11-18 """) pd.testing.assert_frame_equal(result, expected) def test_template_timeslices_extends_sequence_cyclically(csv_str_to_df): - # FY2028 is past the sequence's last row, so the cycle repeats: 2028 gets - # 2026's reference year and must carry the same pattern. + # FY2030 is past the sequence's last row, so the cycle repeats: 2030 gets + # 2026's reference year (2015) and must carry the same pattern. timeslice_calendar = csv_str_to_df(""" DATETIME, NAME, TIMESLICE 18/11/2025, NSW Hot Day, -1 20/11/2025, NSW Hot Day, 0 + 20/11/2025, NSW Winter, -1 + 18/11/2026, NSW Winter, 0 10/12/2026, NSW Hot Day, -1 12/12/2026, NSW Hot Day, 0 - 18/11/2027, NSW Hot Day, -1 - 20/11/2027, NSW Hot Day, 0 + 12/12/2026, NSW Winter, -1 + 10/12/2027, NSW Winter, 0 + 18/11/2029, NSW Hot Day, -1 + 20/11/2029, NSW Hot Day, 0 + 20/11/2029, NSW Winter, -1 + 18/11/2030, NSW Winter, 0 """) reference_year_sequence = csv_str_to_df(""" planning_year, reference_year @@ -86,9 +128,11 @@ def test_template_timeslices_extends_sequence_cyclically(csv_str_to_df): result = _template_timeslices(timeslice_calendar, reference_year_sequence) expected = csv_str_to_df(""" - timeslice_id, reference_year, start_month_day, end_month_day - nsw_peak_demand, 2011, 12-10, 12-12 - nsw_peak_demand, 2015, 11-18, 11-20 + timeslice_id, reference_year, start_month_day, end_month_day + nsw_peak_demand, 2011, 12-10, 12-12 + nsw_peak_demand, 2015, 11-18, 11-20 + nsw_winter_reference, 2011, 12-12, 12-10 + nsw_winter_reference, 2015, 11-20, 11-18 """) pd.testing.assert_frame_equal(result, expected) @@ -96,6 +140,10 @@ def test_template_timeslices_extends_sequence_cyclically(csv_str_to_df): def test_template_timeslices_raises_on_inconsistent_reference_year_patterns( csv_str_to_df, ): + # The second window falls in planning year 2028 (its December start rolls to + # the next FY), which is past the two-row sequence; cyclic extension maps it + # back to 2026's reference year, 2015. So 2015 ends up with two different + # patterns, which is what trips the guard. timeslice_calendar = csv_str_to_df(""" DATETIME, NAME, TIMESLICE 18/11/2025, NSW Hot Day, -1 @@ -136,14 +184,18 @@ def test_template_timeslices_drops_horizon_truncated_planning_year(csv_str_to_df # ends), so all of FY2027's windows are dropped, not just the open one — # its reference year already has a complete pattern from FY2026. timeslice_calendar = csv_str_to_df(""" - DATETIME, NAME, TIMESLICE - 18/11/2025, NSW Hot Day, -1 - 20/11/2025, NSW Hot Day, 0 - 01/04/2026, NSW Winter, -1 - 01/10/2026, NSW Winter, 0 - 18/11/2026, NSW Hot Day, -1 - 20/11/2026, NSW Hot Day, 0 - 01/04/2027, NSW Winter, -1 + DATETIME, NAME, TIMESLICE + 01/10/2025, NSW Typical Summer, -1 + 18/11/2025, NSW Typical Summer, 0 + 18/11/2025, NSW Hot Day, -1 + 20/11/2025, NSW Hot Day, 0 + 20/11/2025, NSW Typical Summer, -1 + 01/04/2026, NSW Typical Summer, 0 + 01/04/2026, NSW Winter, -1 + 01/10/2026, NSW Winter, 0 + 18/11/2026, NSW Hot Day, -1 + 20/11/2026, NSW Hot Day, 0 + 01/04/2027, NSW Winter, -1 """) reference_year_sequence = csv_str_to_df(""" planning_year, reference_year @@ -156,20 +208,24 @@ def test_template_timeslices_drops_horizon_truncated_planning_year(csv_str_to_df expected = csv_str_to_df(""" timeslice_id, reference_year, start_month_day, end_month_day nsw_peak_demand, 2015, 11-18, 11-20 + nsw_summer_typical, 2015, 10-01, 11-18 + nsw_summer_typical, 2015, 11-20, 04-01 nsw_winter_reference, 2015, 04-01, 10-01 """) pd.testing.assert_frame_equal(result, expected) def test_template_timeslices_drops_windows_before_sequence_start(csv_str_to_df): - # The real calendar starts several planning years before AEMO's - # documented sequence; those years' windows are dropped. + # The real calendar starts several planning years before AEMO's documented + # sequence; those years' windows are dropped. timeslice_calendar = csv_str_to_df(""" DATETIME, NAME, TIMESLICE 18/11/2021, NSW Hot Day, -1 20/11/2021, NSW Hot Day, 0 10/12/2025, NSW Hot Day, -1 12/12/2025, NSW Hot Day, 0 + 12/12/2025, NSW Winter, -1 + 10/12/2026, NSW Winter, 0 """) reference_year_sequence = csv_str_to_df(""" planning_year, reference_year @@ -179,8 +235,9 @@ def test_template_timeslices_drops_windows_before_sequence_start(csv_str_to_df): result = _template_timeslices(timeslice_calendar, reference_year_sequence) expected = csv_str_to_df(""" - timeslice_id, reference_year, start_month_day, end_month_day - nsw_peak_demand, 2015, 12-10, 12-12 + timeslice_id, reference_year, start_month_day, end_month_day + nsw_peak_demand, 2015, 12-10, 12-12 + nsw_winter_reference, 2015, 12-12, 12-10 """) pd.testing.assert_frame_equal(result, expected) @@ -200,6 +257,31 @@ def test_template_timeslices_empty_calendar(csv_str_to_df): pd.testing.assert_frame_equal(result, expected, check_dtype=False) +def test_shipped_calendar_decodes(): + # The shipped v7.5 calendar must decode without tripping the consecutive-on + # or inconsistent-pattern guards: those encode invariants of AEMO's data, so + # this also catches a future calendar or sequence refresh that breaks them. + # Decoding behaviour itself is covered by the synthetic tests above. + calendar = load_timeslice_calendar("7.5") + sequence = load_manually_extracted_tables("7.5")["reference_year_sequence"] + + result = _template_timeslices(calendar, sequence) + + assert list(result.columns) == _TIMESLICE_COLUMNS + # The calendar spans AEMO's 2011-2025 reference (weather) years. + assert sorted(result["reference_year"].unique()) == list(range(2011, 2026)) + # tas_peak_demand never activates in the Draft 2026 ISP calendar; the other + # 14 region-prefixed timeslices all do. + assert "tas_peak_demand" not in set(result["timeslice_id"]) + assert result["timeslice_id"].nunique() == 14 + # Reaching here means the inline partition guard passed: the shipped + # calendar's windows tile each reference year exactly. The reference-year + # attribution also relies on only winter crossing 1 July and winter being + # constant per region; the shipped calendar must satisfy both. + _raise_unless_only_winter_crosses_financial_year(result) + _raise_unless_winter_is_constant_per_region(result) + + def test_template_timeslices_empty_sequence(csv_str_to_df): timeslice_calendar = csv_str_to_df(""" DATETIME, NAME, TIMESLICE @@ -214,3 +296,123 @@ def test_template_timeslices_empty_sequence(csv_str_to_df): timeslice_id, reference_year, start_month_day, end_month_day """) pd.testing.assert_frame_equal(result, expected, check_dtype=False) + + +def test_coverage_guard_passes_on_full_partition(csv_str_to_df): + # peak carved out of summer, winter filling the cool half: tiles the year. + timeslices = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_peak_demand, 2015, 01-25, 01-26 + nsw_summer_typical, 2015, 01-26, 04-01 + nsw_winter_reference, 2015, 04-01, 11-01 + nsw_summer_typical, 2015, 11-01, 01-25 + """) + + _raise_unless_windows_tile_the_year(timeslices) # must not raise + + +def test_coverage_guard_passes_without_peak_timeslice(csv_str_to_df): + # tas has no peak_demand; summer + winter alone still tile the year. + timeslices = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + tas_summer_typical, 2015, 01-01, 07-01 + tas_winter_reference, 2015, 07-01, 01-01 + """) + + _raise_unless_windows_tile_the_year(timeslices) # must not raise + + +def test_coverage_guard_raises_on_gap(csv_str_to_df): + # June (06-01 to 07-01) is covered by no window. + timeslices = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_summer_typical, 2015, 01-01, 06-01 + nsw_winter_reference, 2015, 07-01, 01-01 + """) + + with pytest.raises( + ValueError, match=r"Offending region/reference-year pairs: \[\('nsw', 2015\)\]" + ): + _raise_unless_windows_tile_the_year(timeslices) + + +def test_coverage_guard_raises_on_overlap(csv_str_to_df): + # July (07-01 to 08-01) is covered by both summer and winter. + timeslices = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_summer_typical, 2015, 01-01, 08-01 + nsw_winter_reference, 2015, 07-01, 01-01 + """) + + with pytest.raises( + ValueError, match=r"Offending region/reference-year pairs: \[\('nsw', 2015\)\]" + ): + _raise_unless_windows_tile_the_year(timeslices) + + +def test_only_winter_may_cross_financial_year_boundary_raises(csv_str_to_df): + # A summer window spanning 1 July is weather-varying AND boundary-crossing: + # exactly the case that could blur reference years. + timeslices = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_summer_typical, 2015, 06-01, 08-01 + """) + + with pytest.raises(ValueError, match=r"these cross it: \['nsw_summer_typical'\]"): + _raise_unless_only_winter_crosses_financial_year(timeslices) + + +def test_only_winter_may_cross_financial_year_boundary_passes(csv_str_to_df): + # Winter spans 1 July (allowed); the wrapping summer covers Nov-Apr, not July. + timeslices = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_winter_reference, 2015, 04-01, 11-01 + nsw_summer_typical, 2015, 11-01, 04-01 + """) + + _raise_unless_only_winter_crosses_financial_year(timeslices) # must not raise + + +def test_winter_must_be_constant_per_region_raises(csv_str_to_df): + # NSW winter differs between its two reference years. + timeslices = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_winter_reference, 2015, 04-01, 11-01 + nsw_winter_reference, 2011, 04-01, 10-15 + """) + + with pytest.raises(ValueError, match=r"varies in regions: \['nsw'\]"): + _raise_unless_winter_is_constant_per_region(timeslices) + + +def test_winter_constant_per_region_passes(csv_str_to_df): + # NSW winter is identical across reference years; TAS may differ from NSW. + timeslices = csv_str_to_df(""" + timeslice_id, reference_year, start_month_day, end_month_day + nsw_winter_reference, 2015, 04-01, 11-01 + nsw_winter_reference, 2011, 04-01, 11-01 + tas_winter_reference, 2015, 03-01, 12-01 + """) + + _raise_unless_winter_is_constant_per_region(timeslices) # must not raise + + +def test_convert_windows_to_month_days_preserves_leap_day(csv_str_to_df): + # Reference year 2024 is a leap year with a 29 February hot day in the + # shipped calendar. The templater must keep "02-29" — clamping it to 02-28 + # in non-leap model years is the translator's job, not the templater's. + windows = csv_str_to_df(""" + timeslice_id, reference_year, planning_year, start_date, end_date + nsw_peak_demand, 2024, 2040, 2040-02-29, 2040-03-01 + """) + # _convert_windows_to_month_days strftimes these, so they must be datetimes + windows["start_date"] = pd.to_datetime(windows["start_date"]) + windows["end_date"] = pd.to_datetime(windows["end_date"]) + + result = _convert_windows_to_month_days(windows) + + expected = csv_str_to_df(""" + timeslice_id, reference_year, planning_year, start_month_day, end_month_day + nsw_peak_demand, 2024, 2040, 02-29, 03-01 + """) + pd.testing.assert_frame_equal(result, expected)