While working on assigning dates to pages in the ANU Archives' Stock Exchange records, I needed information about holidays in NSW. So here we go...
import datetime
import calendar
import arrow
import pandas as pd
from IPython.display import display, FileLink
What days was the Stock Market closed? I'm assuming it will be for the standard bank holidays. These are set out in legislation. See AustLII:
Of course, the legislation also allowed the government to proclaim other holidays as required, so there could be ones that I'm missing...
If any of the above fall on Sunday, there's a holiday on the following Monday. If 26 December is a Monday, holiday is on the Tuesday.
If any of the above are not on a Monday, the holiday will be on the following Monday.
If any of the above fall on Sunday, there's a holiday on the following Monday. If 26 December is a Monday, holiday is on the Tuesday.
If any of the above are not on a Monday, the holiday will be on the following Monday.
If 1 Jan or 25 Dec fall on Sunday, there's a holiday on the following Monday. If 26 December is a Monday, holiday is on the Tuesday. This seems to indicate that if Boxing Day is on a Sunday, there's no holiday on Monday, but in 1915 when this happened there was a holiday on Monday. So it seems Boxing Day was in practice treated like NY Day and Christmas Day. Same goes for Australia (Anniversary) Day, in 1913 and 1919 ther was a holiday Monday.
If any of the above are not on a Monday, the holiday will be on the following Monday.
If 1 or 26 Jan or 25 or 26 Dec fall on Sunday, there's a holiday on the following Monday. If 26 December is a Monday, holiday is on the Tuesday.
If any of the above are not on a Monday, the holiday will be on the following Monday.
If any of the above fall on Sunday, there's a holiday on the following Monday. If 26 December is a Monday, holiday is on the Tuesday.
If any of the above are not on a Monday, the holiday will be on the following Monday.
It seems that from 1935 it was decided that if Australia (Anniversary) Day didn't fall on a Monday, the holiday would be on the following Monday. See: https://trove.nla.gov.au/newspaper/article/17128813
But in 1938 it was held on the actual day because of the 150th celebtrations.
Despite what the legislation seems to indicate, it appears that if any of 1 Jan, 26 Jan, 25 April, 25 Dec, 26 Dec fell on a Sunday, there was a holiday on the Monday. In any case, that's what I'll assume unless proven otherwise.
1901: Anniversary Day was cancelled
Although it's not in the legislation, there was also a Labour Day holiday on the first Monday in October.
See https://www.assa.org.au/edm.
Victoria was born on 24 May 1819. She died on 22 January 1901.
Edward VII was born on 9 November 1841. He died on 6 May 1910.
George V was born on 3 June 1865. He died on 20 January 1936.
Edward VIII was born on 23 June 1894. He abdicated on 11 December 1936.
George VI was born on 14 December 1895. He died on 6 February 1952.
Albert Edward: born 9 November 1841, became King 22 January 1901
George Frederick Ernest Albert: born 3 June 1865, became king 6 May 1910
Edward Albert Christian George Andrew Patrick David: born 23 June 1894, became king 20 January 1936
This holiday was replaced by Anzac Day in 1925.
# Dates from https://www.assa.org.au/edm
e_dates = """
15th April 1900 12th April 1925 9th April 1950 30th March 1975
7th April 1901 4th April 1926 25th March 1951 18th April 1976
30th March 1902 17th April 1927 13th April 1952 10th April 1977
12th April 1903 8th April 1928 5th April 1953 26th March 1978
3rd April 1904 31st March 1929 18th April 1954 15th April 1979
23rd April 1905 20th April 1930 10th April 1955 6th April 1980
15th April 1906 5th April 1931 1st April 1956 19th April 1981
31st March 1907 27th March 1932 21st April 1957 11th April 1982
19th April 1908 16th April 1933 6th April 1958 3rd April 1983
11th April 1909 1st April 1934 29th March 1959 22nd April 1984
27th March 1910 21st April 1935 17th April 1960 7th April 1985
16th April 1911 12th April 1936 2nd April 1961 30th March 1986
7th April 1912 28th March 1937 22nd April 1962 19th April 1987
23rd March 1913 17th April 1938 14th April 1963 3rd April 1988
12th April 1914 9th April 1939 29th March 1964 26th March 1989
4th April 1915 24th March 1940 18th April 1965 15th April 1990
23rd April 1916 13th April 1941 10th April 1966 31st March 1991
8th April 1917 5th April 1942 26th March 1967 19th April 1992
31st March 1918 25th April 1943 14th April 1968 11th April 1993
20th April 1919 9th April 1944 6th April 1969 3rd April 1994
4th April 1920 1st April 1945 29th March 1970 16th April 1995
27th March 1921 21st April 1946 11th April 1971 7th April 1996
16th April 1922 6th April 1947 2nd April 1972 30th March 1997
1st April 1923 28th March 1948 22nd April 1973 12th April 1998
20th April 1924 17th April 1949 14th April 1974 4th April 1999
"""
easter_exceptions = {
datetime.date(1942, 4, 6)
}
def check_exceptions(date):
if date in easter_exceptions:
return True
# Create a list of easter dates indexed by year.
e_dates = e_dates.split(' ')
e_dates = [d.strip() for d in e_dates]
easter_dates = {}
for e in e_dates:
edate = arrow.get(e, 'Do MMMM YYYY')
good_friday = edate.shift(days=-2)
easter_saturday = edate.shift(days=-1)
easter_monday = edate.shift(days=+1)
easter_dates[edate.year] = []
if not check_exceptions(good_friday.date()):
easter_dates[edate.year].append((good_friday.date(), 'Good Friday'))
if not check_exceptions(easter_saturday.date()):
easter_dates[edate.year].append((easter_saturday.date(), 'Easter Saturday'))
if not check_exceptions(easter_monday.date()):
easter_dates[edate.year].append((easter_monday.date(), 'Easter Monday'))
# Get Easter dates for 1930
easter_dates[1943]
Holidays were proclaimed for a variety of reasons. Here are some that I have found so far:
Below is the information summarised above converted into a machine-readable form. The four values for each holiday are:
0
– holiday is on the given date1
– holiday is on the given date unless it falls on a Sunday, then it's on a Monday. (And Boxing Day gets shifted to Tuesday if on a Monday.)2
– if the given date is not on a Monday then the holiday is on the next Mondaygeneral_holidays = {
'1900': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 1, 'Anniversary Day'), # Australia Day
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1901': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
# (26, 1, 1, 'Anniversary Day'), Cancelled in 1901!
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1902_1904': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 1, 'Anniversary Day'), # Australia Day
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1905': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 2, 'Anniversary Day'), # Australia Day
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1906_1921': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 1, 'Anniversary Day'), # Australia Day
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1922_1934': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 1, 'Anniversary Day'), # Australia Day,
(25, 4, 1, 'Anzac Day'), # Anzac Day - included in legislation from 1925, but proclaimed in 1922-4
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1935_1937': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 2, 'Anniversary Day'), # Australia Day,
(25, 4, 1, 'Anzac Day'), # Anzac Day
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1938': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 0, 'Anniversary Day'), # Australia Day,
(25, 4, 1, 'Anzac Day'), # Anzac Day
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1939': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 2, 'Anniversary Day'), # Australia Day,
(25, 4, 1, 'Anzac Day'), # Anzac Day
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1940': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 2, 'Anniversary Day'), # Australia Day,
(25, 4, 1, 'Anzac Day'), # Anzac Day
# Bank holiday cancelled because of war
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1941': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 2, 'Anniversary Day'), # Australia Day,
(25, 4, 1, 'Anzac Day'), # Anzac Day
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1942': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(28, 12, 1, 'In place of New Year''s Day'),
(26, 1, 2, 'Anniversary Day'), # Australia Day,
(25, 4, 1, 'Anzac Day'), # Anzac Day
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1943': [
# (1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 0, 'Anniversary Day'), # Australia Day,
(25, 4, 1, 'Anzac Day'), # Anzac Day
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
],
'1944_1950': [
(1, 1, 1, 'New Year''s day'),
(25, 12, 1, 'Christmas Day'),
(26, 12, 1, 'Boxing Day'),
(26, 1, 2, 'Anniversary Day'), # Australia Day,
(25, 4, 1, 'Anzac Day'), # Anzac Day
(1, 8, 2, 'Bank Holiday'), # Bank holiday
(1, 10, 2, 'Labour Day'), # Labour Day
]
}
royal_holidays = {
'1900': [
(25, 5, 0, 'Queen\'s Birthday'),
(9, 11, 2, 'Prince of Wales\'s Birthday')
],
'1901': [
(2, 2, 0, 'Day of Mourning for Queen'), # Mourning
(9, 11, 2, 'King\'s Birthday'),
(3, 6, 2, 'Prince of Wales\'s Birthday')
],
'1902_1909': [
(9, 11, 2, 'King\'s Birthday'),
(3, 6, 2, 'Prince of Wales\'s Birthday')
],
'1910': [
(20, 5, 0, 'Day of Mourning for King'), # Mourning
(3, 6, 2, 'King\'s Birthday'),
(27, 6, 0, 'Prince of Wales\'s Birthday')
],
'1911': [
(3, 6, 1, 'King\'s Birthday'),
(22, 6, 0, 'Coronation'), # Coronation
(22, 8, 0, 'Prince of Wales\'s Birthday')
],
'1912_1919': [
(3, 6, 2, 'King\'s Birthday'),
(23, 6, 2, 'Prince of Wales\'s Birthday')
],
'1920': [
(16, 6, 0, 'Prince of Wales\'s Visit'), # Prince of Wlaes visit
(17, 6, 0, 'Prince of Wales\'s Visit')
],
'1921_1924': [
(3, 6, 2, 'King\'s Birthday'),
(23, 6, 2, 'Prince of Wales\'s Birthday')
],
'1925_1935': [
(3, 6, 2, 'King\'s Birthday')
],
'1936': [
# (20, 5, 0, 'King\'s funeral'), # King's funeral
(23, 6, 2, 'King\'s Birthday')
],
'1937': [
(12, 5, 0, 'Coronation') # Coronation
],
'1938_1939': [
(9, 6, 2, 'King\'s Birthday') # 2nd monday in June
],
'1940': [
(17, 6, 2, 'King\'s Birthday') # For some reasons this was held a week later than usual in 1940
],
'1941': [
(16, 6, 2, 'King\'s Birthday') # For some reasons this was held a week later than usual in 1940
],
'1942': [
(9, 6, 2, 'King\'s Birthday')
],
'1943': [
(7, 6, 2, 'King\'s Birthday') # For some reasons this was held earlier than usual
],
'1944': [
(9, 6, 2, 'King\'s Birthday')
],
'1945': [
(18, 6, 2, 'King\'s Birthday')
],
'1946': [
(17, 6, 2, 'King\'s Birthday')
],
'1947': [
(16, 6, 2, 'King\'s Birthday') # 2nd monday in June
],
'1948_1950': [
(9, 6, 2, 'King\'s Birthday') # 2nd monday in June
]
}
other_holidays = {
'1901': [
(27, 5, 0, 'Visit of the Duke of Cornwall'),
(28, 5, 0, 'Visit of the Duke of Cornwall'),
(3, 7, 0, 'Polling day')
],
'1908': [
(20, 8, 0, 'Visit of the American Fleet'),
(24, 8, 0, 'Visit of the American Fleet'),
],
'1915': [
(24, 5, 0, 'Empire Day')
],
'1916': [
(28, 10, 0, 'Conscription referendum'),
(18, 11, 0, 'Postponed 8-hour-day procession')
],
'1945': [
(9, 5, 0, 'VE Day')
],
'1946': [
(10, 6, 0, 'Victory Day')
]
}
def not_on_sunday(day, month, year):
'''
If these holidays fall on a Sunday the holiday is the following Monday.
Additionally if Boxing Day is a Monday the holiday is Tuesday.
'''
date = datetime.date(year, month, day)
#print(f'Was {days[date.weekday()]}, {date}')
if date.weekday() == 6:
date = date.replace(day=day+1)
elif day == 26 and month == 12 and date.weekday() == 0:
date = date.replace(day=day+1)
#print(f'Now {days[date.weekday()]}, {date}')
return date
def always_on_monday(day, month, year):
'''
If these days are not a Monday, the holiday is the following Monday
'''
days = list(calendar.day_name)
date = arrow.get(year, month, day)
#print(f'Was {days[date.weekday()]}, {date}')
if date.weekday() != 0:
add = 7 - date.weekday()
date = date.shift(days=+add)
#print(f'Now {days[date.weekday()]}, {date}')
return date.date()
def get_dates(holiday_list, year):
'''
Get holiday dates for the specified year from one of the lists above.
'''
for key, dates in holiday_list.items():
years = key.split('_')
years = [int(y) for y in years]
if len(years) == 2:
years = list(range(years[0], years[1] + 1))
if year in years:
return dates
return []
def get_holidays(year):
'''
Get all holiday dates for the specified year, combining the lists above and Easter,
and shifting the dates as required.
'''
general = get_dates(general_holidays, year)
royal = get_dates(royal_holidays, year)
other = get_dates(other_holidays, year)
holiday_dates = [*general, *royal, *other]
holidays = []
for day, month, htype, hname in holiday_dates:
if htype == 0:
hdate = datetime.date(year, month, day)
elif htype == 1:
hdate = not_on_sunday(day, month, year)
elif htype == 2:
hdate = always_on_monday(day, month, year)
holidays.append((hdate, hname))
holidays += easter_dates[year]
return holidays
# Get all holidays for 1929
get_holidays(1929)
for year in list(range(1938, 1951)):
date = always_on_monday(9, 6, year)
print(date)
for year in range(1900, 1951):
holidays = sorted(get_holidays(year))
print(f'\n{year}')
for d, h in holidays:
print(f'\t{arrow.get(d).format("D MMMM YYYY")} ({h})')
holidays_1900_1950 = []
# Loop through years collecting holidays
for year in range(1900, 1951):
holidays = sorted(get_holidays(year))
for d, h in holidays:
holidays_1900_1950.append({'year': year, 'date': d, 'holiday': h})
# Convert to a dataframe
df_holidays = pd.DataFrame(holidays_1900_1950)
df_holidays.head()
# Save as CSV
df_holidays.to_csv('nsw_holidays_1900_1950.csv', index=False)
display(FileLink('nsw_holidays_1900_1950.csv'))