none
How to calculate the day of the month? RRS feed

  • Question

  • How to find the last Thursday of the November and last Monday of May to calculate the holidays.
    Friday, October 18, 2019 4:24 PM

Answers

  • In order to find the last Thursday of November, 2019, check this example:

    int year = 2019;

    int month = 11;

    DayOfWeek dayOfWeek = DayOfWeek.Thursday;

     

    var d = new DateTime( year, month, DateTime.DaysInMonth( year, month ) );

    var n = dayOfWeek - d.DayOfWeek;

    if( n > 0 ) n -= 7;

    DateTime result = d.AddDays( n );

     

    Console.WriteLine(result.ToLongDateString());

    Saturday, October 19, 2019 7:36 AM
  • Hello,

    See the following

    https://stackoverflow.com/questions/3709584/business-holiday-date-handling

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace ConsoleApp1
    {
        public static class HolidayInformation
        {
            public static HashSet<DateTime> Get(int year)
            {
                var holidays = new HashSet<DateTime>();
    
                // New Years
                DateTime newYearsDate = AdjustForWeekendHoliday(new DateTime(year, 1, 1));
                holidays.Add(newYearsDate);
    
                // Memorial Day -- last monday in May 
                var memorialDay = new DateTime(year, 5, 31);
                DayOfWeek dayOfWeek = memorialDay.DayOfWeek;
                while (dayOfWeek != DayOfWeek.Monday)
                {
                    memorialDay = memorialDay.AddDays(-1);
                    dayOfWeek = memorialDay.DayOfWeek;
                }
                holidays.Add(memorialDay);
    
                // Independence Day
                DateTime independenceDay = AdjustForWeekendHoliday(new DateTime(year, 7, 4));
                holidays.Add(independenceDay);
    
                // Labor Day -- 1st Monday in September 
                var laborDay = new DateTime(year, 9, 1);
                dayOfWeek = laborDay.DayOfWeek;
                while (dayOfWeek != DayOfWeek.Monday)
                {
                    laborDay = laborDay.AddDays(1);
                    dayOfWeek = laborDay.DayOfWeek;
                }
                holidays.Add(laborDay);
    
                // Thanksgiving Day -- 4th Thursday in November 
                var thanksgiving = (from day in Enumerable.Range(1, 30)
                                    where new DateTime(year, 11, day).DayOfWeek == DayOfWeek.Thursday
                                    select day).ElementAt(3);
                var thanksgivingDay = new DateTime(year, 11, thanksgiving);
                holidays.Add(thanksgivingDay);
    
                // Christmas Day 
                DateTime christmasDay = AdjustForWeekendHoliday(new DateTime(year, 12, 25));
                holidays.Add(christmasDay);
    
                // Next year's new years check
                DateTime nextYearNewYearsDate = AdjustForWeekendHoliday(new DateTime(year + 1, 1, 1));
                if (nextYearNewYearsDate.Year == year)
                    holidays.Add(nextYearNewYearsDate);
    
                return holidays;
            }
    
            public 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;
                }
            }
        }
    }
    

    Example call

    var result = HolidayInformation.Get(DateTime.Now.Year);
    var memorialDay = result.Where(item => item.Month == 5);


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by Reet11 Monday, October 21, 2019 6:43 PM
    Friday, October 18, 2019 4:57 PM
    Moderator

All replies

  • Hello,

    See the following

    https://stackoverflow.com/questions/3709584/business-holiday-date-handling

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace ConsoleApp1
    {
        public static class HolidayInformation
        {
            public static HashSet<DateTime> Get(int year)
            {
                var holidays = new HashSet<DateTime>();
    
                // New Years
                DateTime newYearsDate = AdjustForWeekendHoliday(new DateTime(year, 1, 1));
                holidays.Add(newYearsDate);
    
                // Memorial Day -- last monday in May 
                var memorialDay = new DateTime(year, 5, 31);
                DayOfWeek dayOfWeek = memorialDay.DayOfWeek;
                while (dayOfWeek != DayOfWeek.Monday)
                {
                    memorialDay = memorialDay.AddDays(-1);
                    dayOfWeek = memorialDay.DayOfWeek;
                }
                holidays.Add(memorialDay);
    
                // Independence Day
                DateTime independenceDay = AdjustForWeekendHoliday(new DateTime(year, 7, 4));
                holidays.Add(independenceDay);
    
                // Labor Day -- 1st Monday in September 
                var laborDay = new DateTime(year, 9, 1);
                dayOfWeek = laborDay.DayOfWeek;
                while (dayOfWeek != DayOfWeek.Monday)
                {
                    laborDay = laborDay.AddDays(1);
                    dayOfWeek = laborDay.DayOfWeek;
                }
                holidays.Add(laborDay);
    
                // Thanksgiving Day -- 4th Thursday in November 
                var thanksgiving = (from day in Enumerable.Range(1, 30)
                                    where new DateTime(year, 11, day).DayOfWeek == DayOfWeek.Thursday
                                    select day).ElementAt(3);
                var thanksgivingDay = new DateTime(year, 11, thanksgiving);
                holidays.Add(thanksgivingDay);
    
                // Christmas Day 
                DateTime christmasDay = AdjustForWeekendHoliday(new DateTime(year, 12, 25));
                holidays.Add(christmasDay);
    
                // Next year's new years check
                DateTime nextYearNewYearsDate = AdjustForWeekendHoliday(new DateTime(year + 1, 1, 1));
                if (nextYearNewYearsDate.Year == year)
                    holidays.Add(nextYearNewYearsDate);
    
                return holidays;
            }
    
            public 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;
                }
            }
        }
    }
    

    Example call

    var result = HolidayInformation.Get(DateTime.Now.Year);
    var memorialDay = result.Where(item => item.Month == 5);


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by Reet11 Monday, October 21, 2019 6:43 PM
    Friday, October 18, 2019 4:57 PM
    Moderator
  • Consider using a calendar table or equivalent for lookups. Fill it once. This will avoid a lot of troubles.

    Friday, October 18, 2019 5:00 PM
  • In order to find the last Thursday of November, 2019, check this example:

    int year = 2019;

    int month = 11;

    DayOfWeek dayOfWeek = DayOfWeek.Thursday;

     

    var d = new DateTime( year, month, DateTime.DaysInMonth( year, month ) );

    var n = dayOfWeek - d.DayOfWeek;

    if( n > 0 ) n -= 7;

    DateTime result = d.AddDays( n );

     

    Console.WriteLine(result.ToLongDateString());

    Saturday, October 19, 2019 7:36 AM
  • ... and for the last Monday of May, you can use the following. No, it's not the most efficient way to do it (it's better to find the day of week for the last day of may and then subtract the number of days that are needed to go back to a Monday). But it illustrates how to write a "for" loop on dates, which is useful for solving many problems similar to this one:

    DateTime startingDate = new DataTime(DateTime.Now.Year, 5, 31)
    for (DateTime d = startingDate, d > d.AddDays(-7); d = d.AddDays(-1))
    {
        if (d.DayOfWeek == DayOfWeek.Monday)
        {
            return d;
        }
    }

    Sunday, October 20, 2019 9:50 AM
    Moderator