How to calculate holidays for the USA
vb.net
Solution
This is one way to do it. A weakness of this method is that since the rules are hard coded I would need to change the code in the rare event that congress changed the rules. For my in-house software that is not a problem but it might be for others.
Also I don't calculate Easter since that is not a US federal holiday. See Nature (1876) Algorithm for Calculating the Date of Easter
Public Function getHolidayList(ByVal vYear As Integer) As List(Of Date)
Dim FirstWeek As Integer = 1
Dim SecondWeek As Integer = 2
Dim ThirdWeek As Integer = 3
Dim FourthWeek As Integer = 4
Dim LastWeek As Integer = 5
Dim HolidayList As New List(Of Date)
' http://www.usa.gov/citizens/holidays.shtml
' http://archive.opm.gov/operating_status_schedules/fedhol/2013.asp
' New Year's Day Jan 1
HolidayList.Add(DateSerial(vYear, 1, 1))
' Martin Luther King, Jr. third Mon in Jan
HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 1, 1), DayOfWeek.Monday, ThirdWeek))
' Washington's Birthday third Mon in Feb
HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 2, 1), DayOfWeek.Monday, ThirdWeek))
' Memorial Day last Mon in May
HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 5, 1), DayOfWeek.Monday, LastWeek))
' Juneteenth National Independence Day, June 19
HolidayList.Add(DateSerial(vYear, 6, 19))
' Independence Day July 4
HolidayList.Add(DateSerial(vYear, 7, 4))
' Labor Day first Mon in Sept
HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 9, 1), DayOfWeek.Monday, FirstWeek))
' Columbus Day second Mon in Oct
HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 10, 1), DayOfWeek.Monday, SecondWeek))
' Veterans Day Nov 11
HolidayList.Add(DateSerial(vYear, 11, 11))
' Thanksgiving Day fourth Thur in Nov
HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 11, 1), DayOfWeek.Thursday, FourthWeek))
' Christmas Day Dec 25
HolidayList.Add(DateSerial(vYear, 12, 25))
'saturday holidays are moved to Fri; Sun to Mon
For i As Integer = 0 To HolidayList.Count - 1
Dim dt As Date = HolidayList(i)
If dt.DayOfWeek = DayOfWeek.Saturday Then
HolidayList(i) = dt.AddDays(-1)
End If
If dt.DayOfWeek = DayOfWeek.Sunday Then
HolidayList(i) = dt.AddDays(1)
End If
Next
'return
Return HolidayList
End Function
Private Function GetNthDayOfNthWeek(ByVal dt As Date, ByVal DayofWeek As Integer, ByVal WhichWeek As Integer) As Date
'specify which day of which week of a month and this function will get the date
'this function uses the month and year of the date provided
'get first day of the given date
Dim dtFirst As Date = DateSerial(dt.Year, dt.Month, 1)
'get first DayOfWeek of the month
Dim dtRet As Date = dtFirst.AddDays(6 - dtFirst.AddDays(-(DayofWeek + 1)).DayOfWeek)
'get which week
dtRet = dtRet.AddDays((WhichWeek - 1) * 7)
'if day is past end of month then adjust backwards a week
If dtRet >= dtFirst.AddMonths(1) Then
dtRet = dtRet.AddDays(-7)
End If
'return
Return dtRet
End Function
Problem
I need to know how to calculate USA holidays. I need a solution that works for any year. I didn't want to simply store the dates in a database that would need to be maintained. For holidays on the weekend it needs to follow policy of the US government to adjust to a weekday. If it falls on a Saturday it is adjusted to Friday. If it falls on a Sunday it needs to be adjusted to Monday. I understand many (most?) banks in the US do it the same way. How do I calculate a list of USA holidays? ``` Public Function getHolidayList(ByVal vYear As Integer) As List(Of Date) Dim HolidayList As New List(Of Date) '...fill the list with holidays ' New Year's Day Jan 1 ' Martin Luther King, Jr. third Mon in Jan ' Washington's Birthday third Mon in Feb ' Memorial Day last Mon in May ' Juneteenth June 19th ' Independence Day July 4 ' Labor Day first Mon in Sept ' Columbus Day second Mon in Oct ' Veterans Day Nov 11 ' Thanksgiving Day fourth Thur in Nov ' Christmas Day Dec 25 'adjust for weekends End Function ``` www.archives.gov www.usa.gov www.opm.gov