none
Find the last thursday of a month between two dates C# RRS feed

  • Question

  • I am trying to get the last Thursday of every month between two days. Some of my results are correct, others are occurring a day late on Fridays. Below is my code and the results.
    Any help will be appreciated.

    public class BusinessWeekDays
    {
    public DateTime StartDateMonth;
    public DateTime EndMonth;
    } 
    
    static void Main(string[] args)
    {
    var StartDate = DateTime.Parse("04/25/2019");
    var SeriesEndDate = DateTime.Parse("09/30/2019");
    
    var months = new List<businessweekdays>();
    var Monthly = 1;
    for (var i = StartDate; i < SeriesEndDate; i = i.AddMonths(Monthly))
    {
    const int thursday = 4;
    const int dayDiff = 7 - thursday;
    
    var Day = DateTime.DaysInMonth(i.Year, i.Month);
    var DayOfWeek = (int)new DateTime(i.Year, i.Month, Day).DayOfWeek;
    
    var _dtNew = new DateTime(i.Year, i.Month, Day).AddDays(-(DayOfWeek < thursday ? DayOfWeek + dayDiff : DayOfWeek - thursday));
    var e = _dtNew.AddMonths(+1).AddDays(-2);
    months.Add(new BusinessWeekDays{ StartDateMonth = _dtNew, EndMonth = e});
    Console.WriteLine(months);
    }
    }
    }
    
    Results:
    ------------ 
    [0]
    StartDateMonth {4/25/2019 12:00:00 AM} 
    EndMonth {5/23/2019 12:00:00 AM}---Correct Date and day-Thursday  
    [1]  
    StartDateMonth {5/30/2019 12:00:00 AM} 
    EndMonth {6/28/2019 12:00:00 AM}---- Incorrect Date and Day Friday  

    [2]
    StartDateMonth {6/27/2019 12:00:00 AM} 
    EndMonth {7/25/2019 12:00:00 AM}----Correct Date and Day Thursday

    [3]  
    StartDateMonth {7/25/2019 12:00:00 AM}  
    EndMonth {8/23/2019 12:00:00 AM}-- ---Incorrect Date and day Friday  
    [4]  
    StartDateMonth {8/29/2019 12:00:00 AM}  
    EndMonth {9/27/2019 12:00:00 AM}------ ---- Incorrect Date and Day Friday


    Ebenezer


    • Edited by denkyira Sunday, April 7, 2019 5:31 AM
    Sunday, April 7, 2019 5:27 AM

Answers

  • Hi 

    Thanks a lot. Your code didn't work but I have managed to get it working correctly the way I want.

    Below is my working code.

     static void Main(string[] args)
            {
                var StartDate = DateTime.Parse("04/25/2019");
                var SeriesEndDate = DateTime.Parse("09/30/2019");
    
                var months = new List<BusinessWeekDays>();
                var Monthly = 1;
                for (var i = StartDate; i < SeriesEndDate; i = i.AddMonths(Monthly))
                {
                    const int thursday = 4;
                    const int dayDiff = 7 - thursday;
    
                    var Day = DateTime.DaysInMonth(i.Year, i.Month);
                    var DayOfWeek = (int)new DateTime(i.Year, i.Month, Day).DayOfWeek;
    
                    var _dtNew =
                        new DateTime(i.Year, i.Month, Day).AddDays(-(DayOfWeek < thursday
                            ? DayOfWeek + dayDiff
                            : DayOfWeek - thursday));
                    var e = returnEndMonth(_dtNew);
                    months.Add(new BusinessWeekDays { StartDateMonth = _dtNew, EndMonth = e });
                    Console.WriteLine(months);
                }
    
               
    
            public static DateTime returnEndMonth(DateTime sdt)
            {
                int alldays = DateTime.DaysInMonth(sdt.Year, sdt.AddMonths(1).Month);
                DateTime endtime = new DateTime(sdt.Year, sdt.AddMonths(1).Month, alldays);
                for (int i = 0; i <= alldays; i++)
                {
                    if (endtime.AddDays(-i).DayOfWeek.ToString() == "Thursday")
                    {
                        endtime = endtime.AddDays(-i);
                        break;
                    }
                }
    
                return endtime;
            }


    Ebenezer

    • Marked as answer by denkyira Monday, April 8, 2019 9:56 AM
    Monday, April 8, 2019 9:56 AM

All replies

  • Hi ,

         Your logic of finding Thursday is incorrect in below line:

    var e = _dtNew.AddMonths(+1).AddDays(-2);

    This will always fail when you have 31 days in month while it works for the moths where we have 30 days.

    As in case of 30 days it will add 27 days (  4 weeks) while in case of 31 days it will add 29 days (4 weeks + 1 

    You should use the same logic you are using to get StartDatemonth for next month. 


         

    A user friendly computer first requires a friendly user

    Sunday, April 7, 2019 6:10 AM
  • Hi

    Thanks for your response. I think a little explanation will get me help. The code gets me the last Thursday of each month correctly without these two line:

    var e = _dtNew.AddMonths(+1).AddDays(-2);
    months.Add(new BusinessWeekDays{ StartDateMonth = _dtNew, EndMonth = e});

    The purpose of these two line are just to display the start and the end date for each month and that is where I am having an issue. So for example I know the start date is 04/25/2019

    the following month Last Thursday is 5/30/2019

    the next month last Thursday is 6/27/2019

    I just want to display

    StartDate              EnDate

    4/25/2019            5/30/2019

    startdate               6/27/2019

    
    


    Ebenezer


    • Edited by denkyira Sunday, April 7, 2019 6:30 PM
    Sunday, April 7, 2019 6:25 PM
  • Hi Ebenezer,

    Do you mean that you only need to know how to display the values correctly? If so, instead of the Console.WriteLine() that you currently have, put the following code *outside* of your loop that adds all the dates to the months List:

    Console.WriteLine("StartDate\tEndDate");
    foreach (var month in months)
    {
        Console.WriteLine(month.StartDateMonth.ToString("MM/dd/yyyy") + "\t" + month.EndMonth.ToString("MM/dd/yyyy"));
    }
    


    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Sunday, April 7, 2019 10:11 PM
    Moderator
  • Hi Bonnie

    I need a way to get the correct Start and end date hence this line of code: 

    var e = _dtNew.AddMonths(+1).AddDays(-2); but it is not giving me the correct end date. For example 

    StartDateMonth of 5/30/2019 

    should end  6/27/2019 
     So that line of code in incorrect and that is where I am  struggling get it output the correct last Thursday of the month


    Ebenezer

    Sunday, April 7, 2019 10:34 PM
  • Ebenezer,

    I'm not sure what the relationship is between the StartDate and the last Thursday, but this will at least get you all of the last Thurdays:

    for (var i = StartDate; i < SeriesEndDate; i = i.AddMonths(Monthly))
    {
        const int thursday = 4;
        const int dayDiff = 7 - thursday;
    
        var Day = DateTime.DaysInMonth(i.Year, i.Month);
        var DayOfWeek = (int)new DateTime(i.Year, i.Month, Day).DayOfWeek;
    
        var _dtNew = new DateTime(i.Year, i.Month, Day).AddDays(-(DayOfWeek < thursday ? DayOfWeek + dayDiff : DayOfWeek - thursday));
        //var e = _dtNew.AddMonths(+1).AddDays(-2);
        //months.Add(new BusinessWeekDays { StartDateMonth = _dtNew, EndMonth = e });
        months.Add(new BusinessWeekDays { StartDateMonth = i, EndMonth = _dtNew });
    }
    


    Given your example, can you show us exactly what you need each StartDate/EndMonth to be? I see that in your for loop, you are just adding a month to each iteration. Since you're starting with 04/25/2019, each iteration of the loop will result in i being MM/25/2019 until MM is greater than 9 (09/30/2015, your SeriesEndDate).

    My change above results in each StartDate being the 25th of each month. I doubt if that's what you want, but it's still not clear what you *do* want. Changing i to some other date would give you a different StartDate, and perhaps that's what needs to be done.


    ~~Bonnie DeWitt [C# MVP]

    http://geek-goddess-bonnie.blogspot.com

    Sunday, April 7, 2019 11:48 PM
    Moderator
  • Greetings Denkyira.

    Bahushekh has told you the problem. You are assuming there are thirty days in every month, so your code doesn't work for months with 31 days. Here's some code that should work for every month except February, which I will leave to you.

          public class BusinessWeekDays
          {
             public DateTime StartDateMonth;
             public DateTime EndMonth;
          }
    
          static void Main(string[] args)
          {
             var StartDate = DateTime.Parse("04/25/2019");
             var SeriesEndDate = DateTime.Parse("09/30/2019");
    
             var months = new List<BusinessWeekDays>();
             var Monthly = 1;
             for (var i = StartDate; i < SeriesEndDate; i = i.AddMonths(Monthly))
             {
                const int thursday = 4;
                const int dayDiff = 7 - thursday;
    
                var Day = DateTime.DaysInMonth(i.Year, i.Month);
                var DayOfWeek = (int)new DateTime(i.Year, i.Month, Day).DayOfWeek;
    
                var _dtNew = new DateTime(i.Year, i.Month, Day).AddDays(-(DayOfWeek < thursday ? DayOfWeek + dayDiff : DayOfWeek - thursday));
                var e = _dtNew.AddMonths(+1).AddDays(ThirtyOneDays(_dtNew.Month) ? -3 : -2);
                months.Add(new BusinessWeekDays { StartDateMonth = _dtNew, EndMonth = e });
                Console.WriteLine(months[months.Count - 1].StartDateMonth.DayOfWeek + "    " + months[months.Count - 1].EndMonth.DayOfWeek);
             }
          }
    
          static bool ThirtyOneDays(int month)
          {
             return !(month == 4 || month == 6 || month == 9 || month == 11);
          }
       }


    • Edited by Ante Meridian Monday, April 8, 2019 12:15 AM Wrong date format.
    Monday, April 8, 2019 12:14 AM
  • Hi 

    Thanks a lot. Your code didn't work but I have managed to get it working correctly the way I want.

    Below is my working code.

     static void Main(string[] args)
            {
                var StartDate = DateTime.Parse("04/25/2019");
                var SeriesEndDate = DateTime.Parse("09/30/2019");
    
                var months = new List<BusinessWeekDays>();
                var Monthly = 1;
                for (var i = StartDate; i < SeriesEndDate; i = i.AddMonths(Monthly))
                {
                    const int thursday = 4;
                    const int dayDiff = 7 - thursday;
    
                    var Day = DateTime.DaysInMonth(i.Year, i.Month);
                    var DayOfWeek = (int)new DateTime(i.Year, i.Month, Day).DayOfWeek;
    
                    var _dtNew =
                        new DateTime(i.Year, i.Month, Day).AddDays(-(DayOfWeek < thursday
                            ? DayOfWeek + dayDiff
                            : DayOfWeek - thursday));
                    var e = returnEndMonth(_dtNew);
                    months.Add(new BusinessWeekDays { StartDateMonth = _dtNew, EndMonth = e });
                    Console.WriteLine(months);
                }
    
               
    
            public static DateTime returnEndMonth(DateTime sdt)
            {
                int alldays = DateTime.DaysInMonth(sdt.Year, sdt.AddMonths(1).Month);
                DateTime endtime = new DateTime(sdt.Year, sdt.AddMonths(1).Month, alldays);
                for (int i = 0; i <= alldays; i++)
                {
                    if (endtime.AddDays(-i).DayOfWeek.ToString() == "Thursday")
                    {
                        endtime = endtime.AddDays(-i);
                        break;
                    }
                }
    
                return endtime;
            }


    Ebenezer

    • Marked as answer by denkyira Monday, April 8, 2019 9:56 AM
    Monday, April 8, 2019 9:56 AM