none
How to get the First, second and third Monday of the month between two dates C# RRS feed

  • Question

  • I want to get the first, second and third Monday of the Month between two dates. I can get the first Monday of the month but not between two day. Below is my code. Any help will be appreciated.

     class Program
        {
            public class BusinessWeekDays
            {
                public DateTime Tuesday;
                public DateTime Monday;
            }
           
     
            static void Main(string[] args)
            {
                var StartDate = DateTime.Parse("04/25/2019");
                var SeriesEndDate = DateTime.Parse("09/30/2019");
    
                for (int mth = 1; mth <= 12; mth++)
                {
                    DateTime dt = new DateTime(2010, mth, 1);
                    while (dt.DayOfWeek != DayOfWeek.Monday)
                    {
                        dt = dt.AddDays(1);
                    }
                    Console.WriteLine(dt.ToLongDateString());
                }
                Console.ReadLine();
                //for (var i = StartDate; i < SeriesEndDate; i = i.AddMonths(Monthly))
                //{
    
                //    months.Add(new BusinessWeekDays { Tuesday = dt, Monday = dt.AddDays(7) });
    
                //    Console.WriteLine(months);
                //}
            }
    


    Ebenezer

    Wednesday, April 10, 2019 4:39 PM

Answers

  • There are several different ways to do it but I think this problem can be kept simple. However there is some ambiguity in your question so I'm making the following assumptions.

    1) You want the first Monday within the given date range which could include the first or last day in the range. 

    2) You don't care how many days of the month have elapsed before the first Monday. In some areas the first X of the month has to fall on a week that has all the days in the month, for example.

    3) Since you want the first 3 Mondays of the month the end date isn't really relevant unless it happens to be within 3 weeks of the start date.

    4) There are at least 3 weeks between the start and end date.

    To make this a little more useful here's a method that gets all the DOWs between 2 dates (inclusive). Combining this with LINQ (which you can wrap in a method if you want) gives you the first 3 Mondays.

    static IEnumerable<DateTime> GetDaysOfWeek ( DayOfWeek dayOfWeek, DateTime start, DateTime end )
    {
        //Find the first day with the matching DOW on or after start
        //Could do a diff as well but enumerating 7 values is really fast already            
        var current = start;
        while (current <= end)
        {
            if (current.DayOfWeek == dayOfWeek)
                break;
    
            current = current.AddDays(1);
        };
    
        while (current <= end)
        {
            yield return current;
    
            //Jump ahead a week
            current = current.AddDays(7);
        };
    }
    
    //And a usage
    static void Main ( string[] args )
    {
        var start = DateTime.Parse("4/25/2019");
        var end = DateTime.Parse("9/30/2019");
    
        var days = GetDaysOfWeek(DayOfWeek.Monday, start, end);
    
        //Just want the first 3
        var firstThreeMondays = days.Take(3);
    }

    And finally a plug, if you find yourself needing a lot of date support then I recommend using a standalone Date type instead. I wrote one years ago that I use heavily and for which this kind of functionality is a simple extension method. You might consider doing similar if you don't want to have to deal with times and whatnot.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by denkyira Thursday, April 11, 2019 10:02 AM
    Wednesday, April 10, 2019 6:11 PM
    Moderator
  • Hi denkyira,

    Thank you for posting here.

    For your question, you could try the code below.

      string[] WeekDayNames = new[] { "Monday" };
                DayOfWeek[] days = WeekDayNames
                    .Select(s => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), s))
                    .ToArray();
                DateTime start = new DateTime(2019, 3, 30);
                DateTime end = new DateTime(2019, 4, 11);
    
                IEnumerable<DateTime> range = Enumerable.Range(0, (end - start).Days + 1)
        .Select(d => start.AddDays(d))
        .Where(dt => days.Contains(dt.DayOfWeek));

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by denkyira Thursday, April 11, 2019 10:02 AM
    Thursday, April 11, 2019 7:29 AM
    Moderator

All replies

  • There are several different ways to do it but I think this problem can be kept simple. However there is some ambiguity in your question so I'm making the following assumptions.

    1) You want the first Monday within the given date range which could include the first or last day in the range. 

    2) You don't care how many days of the month have elapsed before the first Monday. In some areas the first X of the month has to fall on a week that has all the days in the month, for example.

    3) Since you want the first 3 Mondays of the month the end date isn't really relevant unless it happens to be within 3 weeks of the start date.

    4) There are at least 3 weeks between the start and end date.

    To make this a little more useful here's a method that gets all the DOWs between 2 dates (inclusive). Combining this with LINQ (which you can wrap in a method if you want) gives you the first 3 Mondays.

    static IEnumerable<DateTime> GetDaysOfWeek ( DayOfWeek dayOfWeek, DateTime start, DateTime end )
    {
        //Find the first day with the matching DOW on or after start
        //Could do a diff as well but enumerating 7 values is really fast already            
        var current = start;
        while (current <= end)
        {
            if (current.DayOfWeek == dayOfWeek)
                break;
    
            current = current.AddDays(1);
        };
    
        while (current <= end)
        {
            yield return current;
    
            //Jump ahead a week
            current = current.AddDays(7);
        };
    }
    
    //And a usage
    static void Main ( string[] args )
    {
        var start = DateTime.Parse("4/25/2019");
        var end = DateTime.Parse("9/30/2019");
    
        var days = GetDaysOfWeek(DayOfWeek.Monday, start, end);
    
        //Just want the first 3
        var firstThreeMondays = days.Take(3);
    }

    And finally a plug, if you find yourself needing a lot of date support then I recommend using a standalone Date type instead. I wrote one years ago that I use heavily and for which this kind of functionality is a simple extension method. You might consider doing similar if you don't want to have to deal with times and whatnot.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by denkyira Thursday, April 11, 2019 10:02 AM
    Wednesday, April 10, 2019 6:11 PM
    Moderator
  • Hi denkyira,

    Thank you for posting here.

    For your question, you could try the code below.

      string[] WeekDayNames = new[] { "Monday" };
                DayOfWeek[] days = WeekDayNames
                    .Select(s => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), s))
                    .ToArray();
                DateTime start = new DateTime(2019, 3, 30);
                DateTime end = new DateTime(2019, 4, 11);
    
                IEnumerable<DateTime> range = Enumerable.Range(0, (end - start).Days + 1)
        .Select(d => start.AddDays(d))
        .Where(dt => days.Contains(dt.DayOfWeek));

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by denkyira Thursday, April 11, 2019 10:02 AM
    Thursday, April 11, 2019 7:29 AM
    Moderator