-
The Government occassinally changes the date of the May Bank Holidays. Although this does not
happen often, there is no reliable method of predicting future date changes! Historic date changes include
- 2002 - Extra Bank Holiday 3 Jun (Linked to Queen's Golden Jubilee)
- 2011 - Extra Bank Holiday Fri 5 May (Linked to William and Catherine Wedding)
- 2012 - Bank Holiday moved from Mon 28 May to Mon 4 Jun (Linked to Queen's Diamond Jubilee)
- 2012 - Extra Bank Holiday Tue 5 Jun (Linked to Queen's Diamond Jubilee)
- 2022 - Bank Holiday moved from Mon 30 May to Mon 2 Jun (Linked to Queen's Platinum Jubilee)
- 2022 - Extra Bank Holiday Tue 3 Jun (Linked to Queen's Platinum Jubilee)
- A UK bank holiday cannot fall on a weekend. This will be avoided by moving the holiday to the following Monday
- You cannot have 2 UK bank holidays on the same date. This will be avoiding by moving one of the holidays to the next available weekday.
- England and Wales use the same set of Bank Holiday rules. Scotland and Northern Ireland share most of the English and Welsh Bank Holidays but some of their holidays are different
These functions return a list of all Bank Holidays (with dates) for England&Wales, Scotland and Northen Ireland. At the time of writing, they are accurate for all dates this centuary, however, the Government could change future Bank Holiday dates.
These functions were originally intended to demonstrate how code from other pages in this section could be used in real-life programming situations. The routines were moved to a separate page due to unavoidable complexity, (a common problem with Calendrical computations.)
In order to compile this code, you will need to copy the following functions into your project...
- WeekDay_OnOrAfter_Date ... Available from "Before/After" page of this site
- Easter ... Available from "Easter" page of this site
- DayOfWeek_In_Month ... Available from "Week of Month" page of this site
Public Structure BankHoliday
Dim Date1 As Date
Dim Name1 As String
End Structure
Find all Bank Holidays in England or Wales for a Year
Public Shared Function EngWal_Bank_Holidays(yyyy As Integer) As List(Of BankHoliday)
Dim ret As New List(Of BankHoliday)
Dim bh As BankHoliday
bh.Name1 = "New Year's Day"
' New Years Day always first weekday on-or-after January 1
bh.Date1 = WeekDay_OnOrAfter_Date(New Date(yyyy, 1, 1, 12, 0, 0, 0, 0))
ret.Add(bh)
Dim easterSunday As Date = Easter(yyyy)
' Good Friday always 2 days before Easter
bh.Name1 = "Good Friday"
bh.Date1 = easterSunday.AddDays(-2)
ret.Add(bh)
' Easter Monday always 1 day after Easter.
bh.Name1 = "Easter Monday"
bh.Date1 = easterSunday.AddDays(1)
ret.Add(bh)
' Early May is normally first Monday in May
' However - in 2020, it was replaced by a VE Anniversary Holiday
bh.Name1 = "Early May Bank Holiday"
If yyyy <> 2020 Then
bh.Date1 = DayOfWeek_In_Month(Week_Of_Month.First, DayOfWeek.Monday, yyyy, 5)
ret.Add(bh)
End If
' Spring bank holiday is normally last monday in May
' However date was changed in 2002, 2012 and 2022
bh.Name1 = "Spring Bank Holiday"
Select Case yyyy
Case 2002
bh.Date1 = New Date(2002, 6, 3, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2012
bh.Date1 = New Date(2012, 6, 4, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2022
bh.Date1 = New Date(2022, 6, 2, 12, 0, 0, 0, 0)
ret.Add(bh)
Case Else
bh.Date1 = DayOfWeek_In_Month(Week_Of_Month.Last, DayOfWeek.Monday, yyyy, 5)
ret.Add(bh)
End Select
' August bank holiday is always last Monday of August
bh.Name1 = "Summer Bank Holiday"
bh.Date1 = DayOfWeek_In_Month(Week_Of_Month.Last, DayOfWeek.Monday, yyyy, 8)
ret.Add(bh)
' Christmas and Boxing will swap if Christmas day must move but boxing could remain on 26 Dec
Dim xmas As New Date(yyyy, 12, 25, 12, 0, 0, 0, 0)
Select Case xmas.DayOfWeek
Case DayOfWeek.Friday
bh.Name1 = "Christmas Day"
bh.Date1 = xmas
ret.Add(bh)
bh.Name1 = "Boxing Day"
bh.Date1 = xmas.AddDays(3)
ret.Add(bh)
Case DayOfWeek.Saturday
bh.Name1 = "Christmas Day"
bh.Date1 = xmas.AddDays(2)
ret.Add(bh)
bh.Name1 = "Boxing Day"
bh.Date1 = xmas.AddDays(3)
ret.Add(bh)
Case DayOfWeek.Sunday
bh.Name1 = "Christmas Day"
bh.Date1 = xmas.AddDays(2)
ret.Add(bh)
bh.Name1 = "Boxing Day" ' Don't move boxing day unless you have to
bh.Date1 = xmas.AddDays(1)
ret.Add(bh)
Case Else
bh.Name1 = "Christmas Day"
bh.Date1 = xmas
ret.Add(bh)
bh.Name1 = "Boxing Day"
bh.Date1 = xmas.AddDays(1)
ret.Add(bh)
End Select
' One-Off Bank Holidays
Select Case yyyy
Case 2002
bh.Name1 = "Queen's Golden Jubilee"
bh.Date1 = New Date(2002, 6, 3, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2011
bh.Name1 = "William and Catherine Wedding"
bh.Date1 = New Date(2011, 4, 29, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2012
bh.Name1 = "Queen's Diamond Jubilee"
bh.Date1 = New Date(2012, 6, 5, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2020
bh.Name1 = "VE Day Anniversary"
bh.Date1 = New Date(2020, 5, 8, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2022
bh.Name1 = "Platinum Jubilee Bank Holiday"
bh.Date1 = New Date(2022, 6, 3, 12, 0, 0, 0, 0)
ret.Add(bh)
bh.Name1 = "Queen Elizabeth II State Funeral"
bh.Date1 = New Date(2022, 9, 19, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2023
bh.Name1 = "King Charles III Coronation"
bh.Date1 = New Date(2023, 5, 8, 12, 0, 0, 0)
ret.Add(bh)
End Select
ret.Sort(Function(x, y) x.Date1.CompareTo(y.Date1))
Return ret
End Function
Find all Bank Holidays in Scotland for a Year
Public Shared Function Scotland_Bank_Holidays(yyyy As Integer) As List(Of BankHoliday)
Dim ret As New List(Of BankHoliday)
Dim bh As BankHoliday
bh.Name1 = "New Year's Day"
' New Years Day always first weekday on-or-after January 1
bh.Date1 = WeekDay_OnOrAfter_Date(New Date(yyyy, 1, 1, 12, 0, 0, 0, 0))
ret.Add(bh)
' January 2 is always first weekday after new year bank holiday (we have just set bh.Date1 to new year bank hol)
bh.Name1 = "2nd January"
bh.Date1 = WeekDay_OnOrAfter_Date(bh.Date1.AddDays(1))
ret.Add(bh)
Dim easterSunday As Date = Easter(yyyy)
' Good Friday always 2 days before Easter
bh.Name1 = "Good Friday"
bh.Date1 = easterSunday.AddDays(-2)
ret.Add(bh)
' Early May is normally first Monday in May
' However - in 2020, it was replaced by a VE Anniversary Holiday
bh.Name1 = "Early May Bank Holiday"
If yyyy <> 2020 Then
bh.Date1 = DayOfWeek_In_Month(Week_Of_Month.First, DayOfWeek.Monday, yyyy, 5)
ret.Add(bh)
End If
' Spring bank holiday is normally last monday in May
' However date was changed in 2002, 2012 and 2022
bh.Name1 = "Spring Bank Holiday"
Select Case yyyy
Case 2002
bh.Date1 = New Date(2002, 6, 3, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2012
bh.Date1 = New Date(2012, 6, 4, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2022
bh.Date1 = New Date(2022, 6, 2, 12, 0, 0, 0, 0)
ret.Add(bh)
Case Else
bh.Date1 = DayOfWeek_In_Month(Week_Of_Month.Last, DayOfWeek.Monday, yyyy, 5)
ret.Add(bh)
End Select
' August bank holiday for Scotland is always First Monday of August
bh.Name1 = "Summer Bank Holiday"
bh.Date1 = DayOfWeek_In_Month(Week_Of_Month.First, DayOfWeek.Monday, yyyy, 8)
ret.Add(bh)
' Saint Andrew is always first weekday on-or-after 30 Nov
bh.Name1 = "St Andrew's Day"
bh.Date1 = WeekDay_OnOrAfter_Date(New Date(yyyy, 11, 30, 12, 0, 0, 0))
ret.Add(bh)
' Christmas Boxing can swap if Christmas day must move but boxing could remain on 26 Dec
Dim xmas As New Date(yyyy, 12, 25, 12, 0, 0, 0, 0)
Select Case xmas.DayOfWeek
Case DayOfWeek.Friday
bh.Name1 = "Christmas Day"
bh.Date1 = xmas
ret.Add(bh)
bh.Name1 = "Boxing Day"
bh.Date1 = xmas.AddDays(3)
ret.Add(bh)
Case DayOfWeek.Saturday
bh.Name1 = "Christmas Day"
bh.Date1 = xmas.AddDays(2)
ret.Add(bh)
bh.Name1 = "Boxing Day"
bh.Date1 = xmas.AddDays(3)
ret.Add(bh)
Case DayOfWeek.Sunday
bh.Name1 = "Christmas Day"
bh.Date1 = xmas.AddDays(2)
ret.Add(bh)
bh.Name1 = "Boxing Day" ' Don't move boxing day unless you have to
bh.Date1 = xmas.AddDays(1)
ret.Add(bh)
Case Else
bh.Name1 = "Christmas Day"
bh.Date1 = xmas
ret.Add(bh)
bh.Name1 = "Boxing Day"
bh.Date1 = xmas.AddDays(1)
ret.Add(bh)
End Select
' One-Off Bank Holidays
Select Case yyyy
Case 2002
bh.Name1 = "Golden Jubilee Bank Holiday"
bh.Date1 = New Date(2002, 6, 3, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2011
bh.Name1 = "William and Catherine Wedding"
bh.Date1 = New Date(2011, 4, 29, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2012
bh.Name1 = "Diamond Jubilee Bank Holiday"
bh.Date1 = New Date(2012, 6, 5, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2020
bh.Name1 = "VE Day Anniversary"
bh.Date1 = New Date(2020, 5, 8, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2022
bh.Name1 = "Platinum Jubilee Bank Holiday"
bh.Date1 = New Date(2022, 6, 3, 12, 0, 0, 0, 0)
ret.Add(bh)
bh.Name1 = "Bank Holiday for the State Funeral of Queen Elizabeth II"
bh.Date1 = New Date(2022, 9, 19, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2023
bh.Name1 = "Bank Holiday for the coronation of King Charles III"
bh.Date1 = New Date(2023, 5, 8, 12, 0, 0, 0)
ret.Add(bh)
End Select
ret.Sort(Function(x, y) x.Date1.CompareTo(y.Date1))
Return ret
End Function
Find all Bank Holidays in Northern Ireland for a Year
Public Shared Function NorthernIreland_Bank_Holidays(yyyy As Integer) As List(Of BankHoliday)
Dim ret As New List(Of BankHoliday)
Dim bh As BankHoliday
bh.Name1 = "New Year's Day"
' New Years Day always first weekday on-or-after January 1
bh.Date1 = WeekDay_OnOrAfter_Date(New Date(yyyy, 1, 1, 12, 0, 0, 0, 0))
ret.Add(bh)
Dim easterSunday As Date = Easter(yyyy)
' Good Friday always 2 days before Easter
bh.Name1 = "Good Friday"
Dim GoodFriday As Date = easterSunday.AddDays(-2)
bh.Date1 = GoodFriday
ret.Add(bh)
' Easter Monday always 1 day after Easter.
bh.Name1 = "Easter Monday"
Dim EasterMonday As Date = easterSunday.AddDays(1)
bh.Date1 = easterMonday
ret.Add(bh)
' Saint Patricks Day is First weekday on-or-after 17 March
' but when it lands on Good Fri or Easter Monday it moves again to Tuesday
bh.Name1 = "St Patrick's Day"
Dim patrick As Date = WeekDay_OnOrAfter_Date(New Date(yyyy, 3, 17, 12, 0, 0, 0, 0))
Select Case patrick
Case GoodFriday, eastermonday : bh.Date1 = eastermonday.AddDays(1)
Case Else : bh.Date1 = patrick
End Select
ret.Add(bh)
' Early May is normally first Monday in May
' However - in 2020, it was replaced by a VE Anniversary Holiday
bh.Name1 = "Early May Bank Holiday"
If yyyy <> 2020 Then
bh.Date1 = DayOfWeek_In_Month(Week_Of_Month.First, DayOfWeek.Monday, yyyy, 5)
ret.Add(bh)
End If
' Spring bank holiday is normally last monday in May
' However date was changed in 2002, 2012 and 2022
bh.Name1 = "Spring Bank Holiday"
Select Case yyyy
Case 2002
bh.Date1 = New Date(2002, 6, 3, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2012
bh.Date1 = New Date(2012, 6, 4, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2022
bh.Date1 = New Date(2022, 6, 2, 12, 0, 0, 0, 0)
ret.Add(bh)
Case Else
bh.Date1 = DayOfWeek_In_Month(Week_Of_Month.Last, DayOfWeek.Monday, yyyy, 5)
ret.Add(bh)
End Select
' Battle of Boyne is First weekday on-or-after 12 July
bh.Name1 = "Battle of the Boyne"
bh.Date1 = WeekDay_OnOrAfter_Date(New Date(yyyy, 7, 12, 12, 0, 0, 0, 0))
ret.Add(bh)
' August bank holiday is always last Monday of August
bh.Name1 = "Summer Bank Holiday"
bh.Date1 = DayOfWeek_In_Month(Week_Of_Month.Last, DayOfWeek.Monday, yyyy, 8)
ret.Add(bh)
' Christmas Boxing can swap if Christmas day must move but boxing could remain on 26 Dec
Dim xmas As New Date(yyyy, 12, 25, 12, 0, 0, 0, 0)
Select Case xmas.DayOfWeek
Case DayOfWeek.Friday
bh.Name1 = "Christmas Day"
bh.Date1 = xmas
ret.Add(bh)
bh.Name1 = "Boxing Day" ' Boxing Day must move
bh.Date1 = xmas.AddDays(3)
ret.Add(bh)
Case DayOfWeek.Saturday
bh.Name1 = "Christmas Day" ' Christmas and Boxing Day must move
bh.Date1 = xmas.AddDays(2)
ret.Add(bh)
bh.Name1 = "Boxing Day"
bh.Date1 = xmas.AddDays(3)
ret.Add(bh)
Case DayOfWeek.Sunday
bh.Name1 = "Christmas Day" ' Boxing Day could stay on 26 Dec and Christmas must move
bh.Date1 = xmas.AddDays(2)
ret.Add(bh)
bh.Name1 = "Boxing Day" ' Don't move boxing day unless you have to
bh.Date1 = xmas.AddDays(1)
ret.Add(bh)
Case Else
bh.Name1 = "Christmas Day"
bh.Date1 = xmas
ret.Add(bh)
bh.Name1 = "Boxing Day"
bh.Date1 = xmas.AddDays(1)
ret.Add(bh)
End Select
' One-Off Bank Holidays
Select Case yyyy
Case 2002
bh.Name1 = "Golden Jubilee Bank Holiday"
bh.Date1 = New Date(2002, 6, 3, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2011
bh.Name1 = "William and Catherine Wedding"
bh.Date1 = New Date(2011, 4, 29, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2012
bh.Name1 = "Diamond Jubilee Bank Holiday"
bh.Date1 = New Date(2012, 6, 5, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2020
bh.Name1 = "VE Day Anniversary"
bh.Date1 = New Date(2020, 5, 8, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2022
bh.Name1 = "Platinum Jubilee Bank Holiday"
bh.Date1 = New Date(2022, 6, 3, 12, 0, 0, 0, 0)
ret.Add(bh)
bh.Name1 = "Bank Holiday for the State Funeral of Queen Elizabeth II"
bh.Date1 = New Date(2022, 9, 19, 12, 0, 0, 0, 0)
ret.Add(bh)
Case 2023
bh.Name1 = "Bank Holiday for the coronation of King Charles III"
bh.Date1 = New Date(2023, 5, 8, 12, 0, 0, 0)
ret.Add(bh)
End Select
ret.Sort(Function(x, y) x.Date1.CompareTo(y.Date1))
Return ret
End Function
DigitalDan.co.uk