Introduction
I am unfortunate enough to have to be tasked with writing QlikView scripts instead of being a real programmer, but every once in a while, I get to write some good old-fashioned C# code. The impetus for writing this code is to enhance my existing DateTime extention class, and is basicially a copy of the same function I wrote for SQL (for use in Qlikview scripts).
The SQL version of this tip is here: US Federal Holidays (SQL)
Background
Frequently, the analysts I work with need to know if a particular date is a US federal holiday. This extension method covers all ten of the current federal holidays that are observed as of this writing.
Using the code
Normally, I abhore multiple return points in a method, because I think it muddies the code up. However, my I overrode my OCD tendancies because I felt it was more important to return as soon as possible if a holiday was detected.
There are essentially two types of holidays - holidays that fall on an nth day of the week (such as MLK day, President's Day, etc), and holidays that occur on a certain day of the month but that are adjusted when that day occurs on a weekend (such as New Year's Day, Christmas, etc). For no other reason than "it just made sense to do it that way", I check for each holiday in the order it appears in the year. Using the method below as a template, you can add additional holidays that are applicable to your project(s). Comments indicate which holiday I'm checking for.
public static bool IsFederalHoliday(this DateTime date)
{
int nthWeekDay = (int)(Math.Ceiling((double)date.Day / 7.0d));
DayOfWeek dayName = date.DayOfWeek;
bool isThursday = dayName == DayOfWeek.Thursday;
bool isFriday = dayName == DayOfWeek.Friday;
bool isMonday = dayName == DayOfWeek.Monday;
bool isWeekend = dayName == DayOfWeek.Saturday || dayName == DayOfWeek.Sunday;
if ((date.Month == 12 && date.Day == 31 && isFriday) ||
(date.Month == 1 && date.Day == 1 && !isWeekend) ||
(date.Month == 1 && date.Day == 2 && isMonday)) return true;
if (date.Month == 1 && isMonday && nthWeekDay == 3) return true;
if (date.Month == 2 && isMonday && nthWeekDay == 3) return true;
if (date.Month == 5 && isMonday && date.AddDays(7).Month == 6) return true;
if ((date.Month == 7 && date.Day == 3 && isFriday) ||
(date.Month == 7 && date.Day == 4 && !isWeekend) ||
(date.Month == 7 && date.Day == 5 && isMonday)) return true;
if (date.Month == 9 && isMonday && nthWeekDay == 1) return true;
if (date.Month == 10 && isMonday && nthWeekDay == 2) return true;
if ((date.Month == 11 && date.Day == 10 && isFriday) ||
(date.Month == 11 && date.Day == 11 && !isWeekend) ||
(date.Month == 11 && date.Day == 12 && isMonday)) return true;
if (date.Month == 11 && isThursday && nthWeekDay == 4) return true;
if ((date.Month == 12 && date.Day == 24 && isFriday) ||
(date.Month == 12 && date.Day == 25 && !isWeekend) ||
(date.Month == 12 && date.Day == 26 && isMonday)) return true;
return false;
}
Points of Interest
It's not hard to prepare bacon. And it's yummy.
History
01 Feb 2017 - Original submission.
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.
My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.