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
' 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
Federal holidays are observed according to the legislation of individual states. The dates of these holidays, and others, are decided upon by each state government, not by the federal (national) government. Each state can agree on the same date that the President has proclaimed, such as Thanksgiving Day.
The Federal Government provides employees with 11 paid holidays each year. 1 Private sector employers may provide these holidays off with pay, holidays off without pay, or holiday pay for working on a holiday, but they are not necessarily required to offer any of these options.
Take the daily number of hours for a full-time employee eg. 8 hours, then multiply by the total number of holiday days in a year, including the bank holidays (whether you work on them or not). This will give you the number of holiday hours for a full-time employee.
Overview. As of June 2021, there are eleven annual federal holidays in the United States, and one additional quadrennial holiday (Inauguration Day).
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))
' 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
Converted to C# as a console program... I needed the dates in a text file quickly:
class Program
{
public class Holiday
{
public string HolidayName { get; set; }
public DateTime Date { get; set; }
public Holiday(string holidayName, DateTime date)
{
HolidayName = holidayName;
Date = date;
}
}
public static List<Holiday> getHolidayList(int vYear)
{
int FirstWeek = 1;
int SecondWeek = 2;
int ThirdWeek = 3;
int FourthWeek = 4;
int LastWeek = 5;
List<Holiday> HolidayList = new List<Holiday>();
// 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(new Holiday("NewYears", new DateTime(vYear, 1, 1)));
// Martin Luther King, Jr. third Mon in Jan
HolidayList.Add(new Holiday("MLK", GetNthDayOfNthWeek(new DateTime(vYear, 1, 1), DayOfWeek.Monday, ThirdWeek)));
// Washington's Birthday third Mon in Feb
HolidayList.Add(new Holiday("WashingtonsBDay", GetNthDayOfNthWeek(new DateTime(vYear, 2, 1), DayOfWeek.Monday, ThirdWeek)));
// Memorial Day last Mon in May
HolidayList.Add(new Holiday("MemorialDay", GetNthDayOfNthWeek(new DateTime(vYear, 5, 1), DayOfWeek.Monday, LastWeek)));
// Independence Day July 4
HolidayList.Add(new Holiday("IndependenceDay", new DateTime(vYear, 7, 4)));
// Labor Day first Mon in Sept
HolidayList.Add(new Holiday("LaborDay", GetNthDayOfNthWeek(new DateTime(vYear, 9, 1), DayOfWeek.Monday, FirstWeek)));
// Columbus Day second Mon in Oct
HolidayList.Add(new Holiday("Columbus", GetNthDayOfNthWeek(new DateTime(vYear, 10, 1), DayOfWeek.Monday, SecondWeek)));
// Veterans Day Nov 11
HolidayList.Add(new Holiday("Veterans", new DateTime(vYear, 11, 11)));
// Thanksgiving Day fourth Thur in Nov
HolidayList.Add(new Holiday("Thanksgiving", GetNthDayOfNthWeek(new DateTime(vYear, 11, 1), DayOfWeek.Thursday, FourthWeek)));
// Christmas Day Dec 25
HolidayList.Add(new Holiday("Christmas", new DateTime(vYear, 12, 25)));
//saturday holidays are moved to Fri; Sun to Mon
foreach (var holiday in HolidayList)
{
if (holiday.Date.DayOfWeek == DayOfWeek.Saturday)
{
holiday.Date = holiday.Date.AddDays(-1);
}
if (holiday.Date.DayOfWeek == DayOfWeek.Sunday)
{
holiday.Date = holiday.Date.AddDays(1);
}
}
//return
return HolidayList;
}
private static System.DateTime GetNthDayOfNthWeek(DateTime dt, DayOfWeek dayofWeek, int WhichWeek)
{
//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
System.DateTime dtFirst = new DateTime(dt.Year, dt.Month, 1);
//get first DayOfWeek of the month
System.DateTime dtRet = dtFirst.AddDays(6 - (int)dtFirst.AddDays(-1 * ((int)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))
{
dtRet = dtRet.AddDays(-7);
}
//return
return dtRet;
}
static void Main(string[] args)
{
for(int ii = 2013; ii < 2100; ii++)
{
var holidays = getHolidayList(ii);
foreach (var holiday in holidays)
{
Console.WriteLine(holiday.HolidayName + ": " + holiday.Date.ToShortDateString());
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With