Tempo.Holidays.SchoolTerms.NSW (Tempo.Holidays v0.1.0)

Copy Markdown View Source

New South Wales public school terms, school holidays and school development days, from the rules the Department of Education's calendars follow.

The Department publishes each year's calendar a few years ahead, and publishes it as dates, not rules. These rules reproduce every calendar it has published, 2016 to 2030, in both divisions, and project the years after:

  • Term 1 ends before Easter or in the week of 7–13 April — on the day before Good Friday when Good Friday falls 31 March–13 April, so Easter opens the autumn holidays, and otherwise on the Friday that falls 7–13 April.

  • The autumn, winter and spring holidays are two weeks — each runs from the Monday after a term's last day, and the next term starts on the Monday two weeks later, or on the next school day when that Monday is a public holiday.

  • Term 3 is ten weeks — Monday of its first week to Friday of its tenth.

  • Term 2 runs to Term 3 — up to 2025 Term 2 is ten weeks. From 2026 Term 3 starts on the Monday on or after 18 July, so Term 2 is ten weeks or eleven.

  • Term 4 ends in the week before Christmas — up to 2025 on the Friday that falls 17–23 December, or on that week's Tuesday when the Friday is the 22nd or 23rd; from 2026 on the Thursday that falls 17–23 December, or on that week's Monday when the Thursday is the 22nd or 23rd.

  • Term 1 starts after Australia Day — up to 2021 on the school day after Australia Day; from 2022 six weeks after the previous Term 4 ended, on the same weekday, unless the year would then have fewer than 199 school days, when it starts on the school day after Australia Day.

  • The Western division starts a week later — its Term 1 starts seven days after the Eastern division's.

A school day is a weekday that is not one of New South Wales' public holidays, as Tempo.Holidays.holidays/2 gives them, and school development days are school days. terms/2, holidays/2 and development_days/2 return interval sets, so they compose with the rest of Tempo.

Example

{:ok, terms} = NSW.terms(~o"2027")
{:ok, holidays} = NSW.holidays(~o"2027")
{:ok, next_holidays} = Tempo.members_overlapping(holidays, ~o"2027-07")

"The NSW school terms of 2027, the holidays between them, and the holidays that fall in July."

Summary

Types

A school division: :eastern, most of the state, or :western, the schools in the far west, whose Term 1 starts a week later.

A school year: a year from 2016, as an integer or a Tempo value naming it.

Functions

Returns a year's school development days.

Returns a year's four school holidays.

Returns a year's four school terms.

Types

division()

@type division() :: :eastern | :western

A school division: :eastern, most of the state, or :western, the schools in the far west, whose Term 1 starts a week later.

year()

@type year() :: pos_integer() | Tempo.t()

A school year: a year from 2016, as an integer or a Tempo value naming it.

Functions

development_days(year, options \\ [])

@spec development_days(year(), keyword()) ::
  {:ok, Tempo.t()} | {:error, {atom(), term()}}

Returns a year's school development days.

Staff attend on a school development day and students do not. The Department has published them since 2023: the first two school days of Term 1, the first of Terms 2 and 3, and the last two of Term 4 in 2023 and 2024; from 2025 the first four school days of Term 1, the first two of Term 2, and the first of Terms 3 and 4. Each day is tagged with its term's number.

Arguments

  • year is a year from 2023, as an integer or a Tempo.t/0 naming it.

Options

  • :division is :eastern or :western, as for terms/2: the Western division's Term 1 development days are the first days of its own Term 1.

Returns

  • {:ok, development_days}, a set (a Tempo.t/0) of the days.

  • {:error, reason} as for terms/2, or {:unpublished_development_days, year} for a year before 2023.

Examples

iex> {:ok, days} = Tempo.Holidays.SchoolTerms.NSW.development_days(~o"2027")
iex> days |> Tempo.IntervalSet.members() |> Enum.map(&Tempo.to_iso8601!/1)
["2027Y1M28D", "2027Y1M29D", "2027Y2M1D", "2027Y2M2D", "2027Y4M27D", "2027Y4M28D",
 "2027Y7M19D", "2027Y10M11D"]

holidays(year, options \\ [])

@spec holidays(year(), keyword()) :: {:ok, Tempo.t()} | {:error, {atom(), term()}}

Returns a year's four school holidays.

The holidays are the days between the terms: the autumn, winter and spring holidays after Terms 1, 2 and 3, and the summer holidays after Term 4, which run into the next year until its Term 1 starts. Each holiday takes in the weekends either side, and is tagged %{holiday: :autumn}, :winter, :spring or :summer.

Arguments

  • year is a year from 2016, as for terms/2.

Options

  • :division is :eastern or :western, as for terms/2: the Western division's summer holidays run a week longer.

Returns

  • {:ok, holidays}, a set (a Tempo.t/0) of the four holidays.

  • {:error, reason} as for terms/2.

Examples

iex> {:ok, holidays} = Tempo.Holidays.SchoolTerms.NSW.holidays(~o"2027")
iex> holidays |> Tempo.IntervalSet.members() |> Enum.map(&Tempo.to_iso8601!/1)
["2027Y4M10D/26D", "2027Y7M3D/18D", "2027Y9M25D/10M10D", "2027Y12M21D/2028Y1M30D"]

terms(year, options \\ [])

@spec terms(year(), keyword()) :: {:ok, Tempo.t()} | {:error, {atom(), term()}}

Returns a year's four school terms.

Each term runs from its first day to its last, school development days included, and is tagged with its number: %{term: 1} to %{term: 4}.

Arguments

  • year is a year from 2016, the first the rules were checked against: an integer or a Tempo.t/0 naming the year, ~o"2027".

Options

  • :division is :eastern, the default, or :western for the schools in the far west, whose Term 1 starts a week later.

Returns

  • {:ok, terms}, a set (a Tempo.t/0) of the four terms.

  • {:error, reason} — {:invalid_year, year}, {:invalid_division, division} or {:invalid_option, options}.

Examples

iex> {:ok, terms} = Tempo.Holidays.SchoolTerms.NSW.terms(~o"2027")
iex> terms |> Tempo.IntervalSet.members() |> Enum.map(&Tempo.to_iso8601!/1)
["2027Y1M28D/4M9D", "2027Y4M27D/7M2D", "2027Y7M19D/9M24D", "2027Y10M11D/12M20D"]

iex> {:ok, terms} = Tempo.Holidays.SchoolTerms.NSW.terms(2027, division: :western)
iex> terms |> Tempo.IntervalSet.first() |> Tempo.to_iso8601!()
"2027Y2M4D/4M9D"