# [ACCEPTED]-Count number of Mondays in a given date range-datediff

Score: 52

Try this:

``````static int CountDays(DayOfWeek day, DateTime start, DateTime end)
{
TimeSpan ts = end - start;                       // Total duration
int count = (int)Math.Floor(ts.TotalDays / 7);   // Number of whole weeks
int remainder = (int)(ts.TotalDays % 7);         // Number of remaining days
int sinceLastDay = (int)(end.DayOfWeek - day);   // Number of days since last [day]
if (sinceLastDay < 0) sinceLastDay += 7;         // Adjust for negative days since last [day]

// If the days in excess of an even week are greater than or equal to the number days since the last [day], then count this one, too.
if (remainder >= sinceLastDay) count++;

return count;
}
``````

0

Score: 22

Since you're using C#, if you're using C#3.0, you 5 can use LINQ.

Assuming you have an Array/List/IQueryable 4 etc that contains your dates as DateTime 3 types:

``````DateTime[] dates = { new DateTime(2008,10,6), new DateTime(2008,10,7)}; //etc....

var mondays = dates.Where(d => d.DayOfWeek == DayOfWeek.Monday); // = {10/6/2008}
``````

Not sure if you meant grouping 2 them and counting them, but here's how to 1 do that in LINQ as well:

``````var datesgrouped = from d in dates
group d by d.DayOfWeek into grouped
select new { WeekDay = grouped.Key, Days = grouped };

foreach (var g in datesgrouped)
{
Console.Write (String.Format("{0} : {1}", g.WeekDay,g.Days.Count());
}
``````
Score: 20

It's fun to look at different algorithms 9 for calculating day of week, and @Gabe Hollombe's 8 pointing to WP on the subject was a great 7 idea (and I remember implementing Zeller's Congruence in COBOL 6 about twenty years ago), but it was rather 5 along the line of handing someone a blueprint 4 of a clock when all they asked what time 3 it was.

In C#:

``````    private int CountMondays(DateTime startDate, DateTime endDate)
{
int mondayCount = 0;

for (DateTime dt = startDate; dt < endDate; dt = dt.AddDays(1.0))
{
if (dt.DayOfWeek == DayOfWeek.Monday)
{
mondayCount++;
}
}

return mondayCount;
}
``````

This of course does not evaluate 2 the end date for "Mondayness", so 1 if this was desired, make the for loop evaluate

``````dt < endDate.AddDays(1.0)
``````
Score: 5

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 8 days, and `DayOfWeek` returns the day of the week as 7 an integer. It doesn't really matter what 6 mapping `DayOfWeek` uses, as long as it is increasing 5 and matches up with `DayImLookingFor`.

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

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

Score: 3

Any particular language and therefore date 7 format?

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

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

Score: 2
You could try this, if you want to get specific week days between two dates
``````public List<DateTime> GetSelectedDaysInPeriod(DateTime startDate, DateTime endDate, List<DayOfWeek> daysToCheck)
{
var selectedDates = new List<DateTime>();

if (startDate >= endDate)
return selectedDates; //No days to return

if (daysToCheck == null || daysToCheck.Count == 0)
return selectedDates; //No days to select

try
{
//Get the total number of days between the two dates
var totalDays = (int)endDate.Subtract(startDate).TotalDays;

//So.. we're creating a list of all dates between the two dates:
var allDatesQry = from d in Enumerable.Range(1, totalDays)
select new DateTime(

//And extracting those weekdays we explicitly wanted to return
var selectedDatesQry = from d in allDatesQry
where daysToCheck.Contains(d.DayOfWeek)
select d;

//Copying the IEnumerable to a List
selectedDates = selectedDatesQry.ToList();
}
catch (Exception ex)
{
//Log error
//...

//And re-throw
throw;
}
return selectedDates;
}
``````

0

Score: 1

Add the smallest possible number to make 3 the first day a Monday. Subtract the smallest 2 possible number to make the last day a Monday. Calculate 1 the difference in days and divide by 7.

Score: 1

Convert the dates to Julian Day Number, then 3 do a little bit of math. Since Mondays are 2 zero mod 7, you could do the calculation 1 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
``````
Score: 1

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

``````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 5 between function that return true if, starting 4 from the start day, we meet first the dayImLookingFor 3 before the endDay.

I have done the between 2 function by computing the number of day 1 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)
{
}
else
{
}
}
``````
Score: 1

This will return a collection of integers 4 showing how many times each day of the week 3 occurs within a date range

``````    int[] CountDays(DateTime firstDate, DateTime lastDate)
{
var totalDays = lastDate.Date.Subtract(firstDate.Date).TotalDays + 1;
var weeks = (int)Math.Floor(totalDays / 7);

var result = Enumerable.Repeat<int>(weeks, 7).ToArray();
if (totalDays % 7 != 0)
{
int firstDayOfWeek = (int)firstDate.DayOfWeek;
int lastDayOfWeek = (int)lastDate.DayOfWeek;
if (lastDayOfWeek < firstDayOfWeek)
lastDayOfWeek += 7;
for (int dayOfWeek = firstDayOfWeek; dayOfWeek <= lastDayOfWeek; dayOfWeek++)
result[dayOfWeek % 7]++;
}
return result;
}
``````

Or a slight variation 2 which lets you do FirstDate.TotalDaysOfWeeks(SecondDate) and 1 returns a Dictionary

``````    public static Dictionary<DayOfWeek, int> TotalDaysOfWeeks(this DateTime firstDate, DateTime lastDate)
{
var totalDays = lastDate.Date.Subtract(firstDate.Date).TotalDays + 1;
var weeks = (int)Math.Floor(totalDays / 7);

var resultArray = Enumerable.Repeat<int>(weeks, 7).ToArray();
if (totalDays % 7 != 0)
{
int firstDayOfWeek = (int)firstDate.DayOfWeek;
int lastDayOfWeek = (int)lastDate.DayOfWeek;
if (lastDayOfWeek < firstDayOfWeek)
lastDayOfWeek += 7;
for (int dayOfWeek = firstDayOfWeek; dayOfWeek <= lastDayOfWeek; dayOfWeek++)
resultArray[dayOfWeek % 7]++;
}
var result = new Dictionary<DayOfWeek, int>();
for (int dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++)
result[(DayOfWeek)dayOfWeek] = resultArray[dayOfWeek];
return result;
}
``````
Score: 1

A bit Modified Code is here works and Tested 1 by me

``````        private int CountDays(DayOfWeek day, DateTime startDate, DateTime endDate)
{
int dayCount = 0;

for (DateTime dt = startDate; dt < endDate; dt = dt.AddDays(1.0))
{
if (dt.DayOfWeek == day)
{
dayCount++;
}
}

return dayCount;
}
``````

Example:

``````int Days = CountDays(DayOfWeek.Friday, Convert.ToDateTime("2019-07-04"),
Convert.ToDateTime("2019-07-27")).ToString();
``````
Score: 0

I had a similar problem for a report. I 7 needed the number of workdays between two 6 dates. I could have cycled through the dates 5 and counted but my discrete math training 4 wouldn't let me. Here is a function I wrote 3 in VBA to get the number of workdays between 2 two dates. I'm sure .net has a similar 1 WeekDay function.

``````   1
2  ' WorkDays
3  ' returns the number of working days between two dates
4  Public Function WorkDays(ByVal dtBegin As Date, ByVal dtEnd As Date) As Long
5
6     Dim dtFirstSunday As Date
7     Dim dtLastSaturday As Date
8     Dim lngWorkDays As Long
9
10     ' get first sunday in range
11     dtFirstSunday = dtBegin + ((8 - Weekday(dtBegin)) Mod 7)
12
13     ' get last saturday in range
14     dtLastSaturday = dtEnd - (Weekday(dtEnd) Mod 7)
15
16     ' get work days between first sunday and last saturday
17     lngWorkDays = (((dtLastSaturday - dtFirstSunday) + 1) / 7) * 5
18
19     ' if first sunday is not begin date
20     If dtFirstSunday <> dtBegin Then
21
22        ' assume first sunday is after begin date
23        ' add workdays from begin date to first sunday
24        lngWorkDays = lngWorkDays + (7 - Weekday(dtBegin))
25
26     End If
27
28     ' if last saturday is not end date
29     If dtLastSaturday <> dtEnd Then
30
31        ' assume last saturday is before end date
32        ' add workdays from last saturday to end date
33        lngWorkDays = lngWorkDays + (Weekday(dtEnd) - 1)
34
35     End If
36
37     ' return working days
38     WorkDays = lngWorkDays
39
40  End Function
``````
Score: 0
``````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)

return EndDate.Subtract(StartDate).Days / 7 + 1;
}
``````

0

Score: 0

Four years later, I thought I'd run a test:

``````[TestMethod]
public void ShouldFindFridaysInTimeSpan()
{
//reference: http://stackoverflow.com/questions/248273/count-number-of-mondays-in-a-given-date-range

var spanOfSixtyDays = new TimeSpan(60, 0, 0, 0);
var setOfDates = new List<DateTime>(spanOfSixtyDays.Days);
var now = DateTime.Now;

for(int i = 0; i < spanOfSixtyDays.Days; i++)
{
}

Assert.IsTrue(setOfDates.Count == 60,
"The expected number of days is not here.");

var fridays = setOfDates.Where(i => i.DayOfWeek == DayOfWeek.Friday);

Assert.IsTrue(fridays.Count() > 0,
"The expected Friday days are not here.");
Assert.IsTrue(fridays.First() == setOfDates.First(i => i.DayOfWeek == DayOfWeek.Friday),
"The expected first Friday day is not here.");
Assert.IsTrue(fridays.Last() == setOfDates.Last(i => i.DayOfWeek == DayOfWeek.Friday),
"The expected last Friday day is not here.");
}
``````

My 2 use of `TimeSpan` is a bit of overkill---actually 1 I wanted to query `TimeSpan` directly.

More Related questions