Count number of Mondays in a given date range

后端 未结 15 1169
南旧
南旧 2020-11-28 09:35

Given a date range, I need to know how many Mondays (or Tuesdays, Wednesdays, etc) are in that range.

I am currently working in C#.

相关标签:
15条回答
  • 2020-11-28 09:44

    Here's some pseudocode:

    DifferenceInDays(Start, End) / 7   // Integer division discarding remainder
    + 1 if DayOfWeek(Start) <= DayImLookingFor
    + 1 if DayOfWeek(End)   >= DayImLookingFor
    - 1
    

    Where DifferenceInDays returns End - Start in days, and DayOfWeek returns the day of the week as an integer. It doesn't really matter what mapping DayOfWeek uses, as long as it is increasing and matches up with DayImLookingFor.

    Note that this algorithm assumes the date range is inclusive. If End should not be part of the range, you'll have to adjust the algorithm slightly.

    Translating to C# is left as an exercise for the reader.

    0 讨论(0)
  • 2020-11-28 09:46

    Any particular language and therefore date format?

    If dates are represented as a count of days, then the difference between two values plus one (day), and divide by 7, is most of the answer. If both end dates are the day in question, add one.

    Edited: corrected 'modulo 7' to 'divide by 7' - thanks. And that is integer division.

    0 讨论(0)
  • 2020-11-28 09:46

    Convert the dates to Julian Day Number, then do a little bit of math. Since Mondays are zero mod 7, you could do the calculation like this:

    JD1=JulianDayOf(the_first_date)
    JD2=JulianDayOf(the_second_date)
    Round JD1 up to nearest multiple of 7
    Round JD2 up to nearest multiple of 7
    d = JD2-JD1
    nMondays = (JD2-JD1+7)/7    # integer divide
    
    0 讨论(0)
  • 2020-11-28 09:49
    private System.Int32 CountDaysOfWeek(System.DayOfWeek dayOfWeek, System.DateTime date1, System.DateTime date2)
    {
      System.DateTime EndDate;
      System.DateTime StartDate;
    
      if (date1 > date2)
      {
        StartDate = date2;
        EndDate = date1;
      }
      else
      {
        StartDate = date1;
        EndDate = date2;
      }
    
      while (StartDate.DayOfWeek != dayOfWeek)
        StartDate = StartDate.AddDays(1);
    
      return EndDate.Subtract(StartDate).Days / 7 + 1;
    }
    
    0 讨论(0)
  • 2020-11-28 09:50

    I've come across a slightly easier way to solve this problem using linq.

    public static int NumberOfFridays(DateTime start, DateTime end) 
    { 
        return start.GetDaysInBetween(end, inclusive: true).Count(d => d.DayOfWeek == DayOfWeek.Friday); 
    } 
    

    Hope that helps.

    0 讨论(0)
  • 2020-11-28 09:52

    I have had the same need today. I started with the cjm function since I don't understand the JonB function and since the Cyberherbalist function is not linear.

    I had have to correct

    DifferenceInDays(Start, End) / 7   // Integer division discarding remainder
    + 1 if DayOfWeek(Start) <= DayImLookingFor
    + 1 if DayOfWeek(End)   >= DayImLookingFor
    - 1
    

    to

    DifferenceInDays(Start, End) / 7   // Integer division discarding remainder
    + 1 if DayImLookingFor is between Start.Day and End.Day 
    

    With the between function that return true if, starting from the start day, we meet first the dayImLookingFor before the endDay.

    I have done the between function by computing the number of day from startDay to the other two days:

    private int CountDays(DateTime start, DateTime end, DayOfWeek selectedDay)
    {
        if (start.Date > end.Date)
        {
            return 0;
        }
        int totalDays = (int)end.Date.Subtract(start.Date).TotalDays;
        DayOfWeek startDay = start.DayOfWeek;
        DayOfWeek endDay = end.DayOfWeek;
        ///look if endDay appears before or after the selectedDay when we start from startDay.
        int startToEnd = (int)endDay - (int)startDay;
        if (startToEnd < 0)
        {
            startToEnd += 7;
        }
        int startToSelected = (int)selectedDay - (int)startDay;
        if (startToSelected < 0)
        {
            startToSelected += 7;
        }
        bool isSelectedBetweenStartAndEnd = startToEnd >= startToSelected;
        if (isSelectedBetweenStartAndEnd)
        {
            return totalDays / 7 + 1;
        }
        else
        {
            return totalDays / 7;
        }
    }
    
    0 讨论(0)
提交回复
热议问题