C# Tips n Tricks: Simple IsHoliday Class

Today I had a need to check if the current date was a holiday. I wrote up this quick class to do the calculations. This may be a good class to add as an extension to the DateTime class as well. It is one of those nice simple classes that is always useful.

    public class Holiday
    {
        public static bool IsHoliday(DateTime date)
        {
            return
                Holiday.IsNewYearsDay(date)
             || Holiday.IsNewYearsEve(date)
             || Holiday.IsThanksgivingDay(date)
             || Holiday.IsDayAfterThanksgiving(date)
             || Holiday.IsChristmasEve(date)
             || Holiday.IsChristmasDay(date)
             || Holiday.IsFourthOfJuly(date)
             || Holiday.IsLaborDay(date)
             || Holiday.IsMemorialDay(date);
        }
        public static bool IsNewYearsDay(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 1, 1)).DayOfYear;
        }
        public static bool IsNewYearsEve(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 12, 31)).DayOfYear;
        }
        public static bool IsChristmasEve(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 12, 24)).DayOfYear;
        }
        public static bool IsChristmasDay(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 12, 25)).DayOfYear;
        }
        public static bool IsFourthOfJuly(DateTime date)
        {
            return date.DayOfYear == AdjustForWeekendHoliday(new DateTime(date.Year, 7, 4)).DayOfYear;
        }
        public static bool IsLaborDay(DateTime date)
        { // First Monday in September
            DateTime laborDay = new DateTime(date.Year, 9, 1);
            DayOfWeek dayOfWeek = laborDay.DayOfWeek;
            while (dayOfWeek != DayOfWeek.Monday)
            {
                laborDay = laborDay.AddDays(1);
                dayOfWeek = laborDay.DayOfWeek;
            }
            return date.DayOfYear == laborDay.DayOfYear;
        }
        public static bool IsMemorialDay(DateTime date)
        { //Last Monday in May
            DateTime memorialDay = new DateTime(date.Year, 5, 31);
            DayOfWeek dayOfWeek = memorialDay.DayOfWeek;
            while (dayOfWeek != DayOfWeek.Monday)
            {
                memorialDay = memorialDay.AddDays(-1);
                dayOfWeek = memorialDay.DayOfWeek;
            }
            return date.DayOfYear == memorialDay.DayOfYear;
        }
        public static bool IsThanksgivingDay(DateTime date)
        {//4th Thursday in November
            var thanksgiving = (from day in Enumerable.Range(1, 30)
                                where new DateTime(date.Year, 11, day).DayOfWeek == DayOfWeek.Thursday
                                select day).ElementAt(3);
            DateTime thanksgivingDay = new DateTime(date.Year, 11, thanksgiving);
            return date.DayOfYear == thanksgivingDay.DayOfYear;
        }
        public static bool IsDayAfterThanksgiving(DateTime date)
        {//Day after Thanksgiving
            var thanksgiving = (from day in Enumerable.Range(1, 30)
                                where new DateTime(date.Year, 11, day).DayOfWeek == DayOfWeek.Thursday
                                select day).ElementAt(3);
            DateTime thanksgivingDay = new DateTime(date.Year, 11, thanksgiving + 1);
            return date.DayOfYear == thanksgivingDay.DayOfYear;
        }

        private static DateTime AdjustForWeekendHoliday(DateTime holiday)
        {
            if (holiday.DayOfWeek == DayOfWeek.Saturday)
            {
                return holiday.AddDays(-1);
            }
            else if (holiday.DayOfWeek == DayOfWeek.Sunday)
            {
                return holiday.AddDays(1);
            }
            else
            {
                return holiday;
            }
        }
    }

SQL Tips n Tricks: Show events by time of day

Sometime times I get a request for data from a user that is actually fun to write.  Today was one like that.  The request from the user was to look at a series of event that occurred in the last week.  It needed to be organized by day of week and time of day, by the half hour.  Now that it is done I see a series of user reports in my future that takes this data and presents it for user review.

Here is what the data looks like after it is run:

Num Files Hour Of Day Monday Tuesday Wednesday Thursday Friday Saturday Sunday
23 6:00 6 2 4 7 2 1 1
80 6:30 12 17 19 17 10 5 0
616 7:00 86 132 129 137 115 17 0
1006 7:30 130 214 183 239 177 63 0
1963 8:00 285 374 449 390 389 76 0
2613 8:30 391 523 557 488 547 107 0
3529 9:00 588 750 690 744 648 109 0
3670 9:30 692 787 701 701 663 126 0
4214 10:00 699 944 851 847 738 133 2
4753 10:30 835 1004 902 955 938 118 1
4850 11:00 885 976 1019 917 954 96 3
4549 11:30 826 920 913 927 883 76 4
4504 12:00 821 866 869 1077 796 72 3
3792 12:30 694 757 793 765 705 75 3
4170 13:00 738 898 838 874 776 42 4
4333 13:30 908 891 868 814 801 49 2
4234 14:00 856 866 774 880 800 54 4
3948 14:30 733 833 787 788 767 36 4
4721 15:00 860 930 1121 890 882 36 2
5089 15:30 1111 1013 977 985 967 30 6
4773 16:00 962 974 937 874 1005 20 1
4753 16:30 944 971 986 865 947 38 2
4516 17:00 958 932 908 855 844 14 5
3519 17:30 716 727 696 687 679 13 1
2761 18:00 497 558 560 600 538 6 2
2129 18:30 447 446 424 432 377 3 0
852 19:00 183 180 184 150 151 4 0
53 19:30 9 8 15 7 8 6 0
24 20:00 9 1 8 0 2 1 3
6 20:30 0 0 0 0 1 0 5
19 21:00 2 4 4 6 2 0 1
4 21:30 1 0 1 0 0 0 2

Here is the SQL used to create it:

SELECT COUNT(Audit_Row_Id) AS NumberFilesRun
     , RIGHT('00' + CAST(DATEPART(HOUR, FI.Audit_Create_Date) AS NVARCHAR(2)), 2) 
       + ':' 
       + (CASE WHEN DATEPART(MINUTE, FI.Audit_Create_Date) < 30 THEN '00' ELSE '30' END) 
       AS HourOfDay
     , SUM(CASE WHEN  datename(dw,Audit_Create_Date) = 'Monday' THEN 1 ELSE 0 END) AS Monday
     , SUM(CASE WHEN  datename(dw,Audit_Create_Date) = 'Tuesday' THEN 1 ELSE 0 END) AS Tuesday
     , SUM(CASE WHEN  datename(dw,Audit_Create_Date) = 'Wednesday' THEN 1 ELSE 0 END) AS Wednesday
     , SUM(CASE WHEN  datename(dw,Audit_Create_Date) = 'Thursday' THEN 1 ELSE 0 END) AS Thursday
     , SUM(CASE WHEN  datename(dw,Audit_Create_Date) = 'Friday' THEN 1 ELSE 0 END) AS Friday
     , SUM(CASE WHEN  datename(dw,Audit_Create_Date) = 'Saturday' THEN 1 ELSE 0 END) AS Saturday
     , SUM(CASE WHEN  datename(dw,Audit_Create_Date) = 'Sunday' THEN 1 ELSE 0 END) AS Sunday
FROM Audit_File_Information FI
WHERE Audit_Create_User = 'UniqueUserName'
AND Audit_Create_Date BETWEEN DATEADD(week, -2, GETDATE()) AND  DATEADD(week, -1, GETDATE())
GROUP BY RIGHT('00' 
             + CAST(DATEPART(HOUR, FI.Audit_Create_Date) AS NVARCHAR(2)), 2) 
             + ':' 
			 + (CASE WHEN DATEPART(MINUTE, FI.Audit_Create_Date) < 30 THEN '00' ELSE '30' END)
ORDER BY 2 

JavaScript Tips n Tricks: Has only digits

Sometimes it’s necessary to do validation manually in javascript.  One that I had to do recently was to do a simple check that a value only had digits in it.  It should be obvious but since I had to look it up I figure I will post it so I can reference it in the future.


var notes = $("#txtContactExt").val();
if (/\D/.test(notes))
{
validationText += "*Please use numbers only for Phone Extension.";
}

C# Tips n Tricks: ToStringOrEmpty()

Here is another one of those extension methods that I carry with me from job to job.  It’s a super simple one that just makes sense.  So many times I am working with variables that need to be displayed as empty strings when they are null.  The following code gets tiresome when generating dozens of strings in a row.

var displayString = value == null ? String.Empty : value.ToString();

Instead I added the following extension method for strings. Technically it works for any object that has ToString() implemented.

It means that I can simply show the following code which is much simpler and nicer and cleans my code up tremendously.

        public static string ToStringOrEmpty(this object value)
        {
            return ((object)value ?? String.Empty).ToString();
        }

Update: A former co-worker sent me this CodeProject Article: Chained null checks and the Maybe monad that takes this concept a bit further with a fairly complex set of extensions that allow cleaning up null checks even more.  I’ll have to dig into it deeper.