Reputation: 13
I want to count occurrences, for each day of the week, between two given dates.
For example:
Between 20/07/2014 to 27/7/2014, an 8 day span, there were:
Sunday=2, monday=1, tuesday=1,...
Upvotes: 1
Views: 2349
Reputation: 62488
you can achieve it using Linq:
DateTime StartDate = DateTime.Now.AddDays(-14);
DateTime EndDate = DateTime.Now;
DayOfWeek day = DayOfWeek.Monday;
First get the all days between two dates:
List<DateTime> dates = Enumerable.Range(0, (int)((EndDate - StartDate).TotalDays) + 1)
.Select(n => StartDate.AddDays(n))
.ToList();
Now get Count on the base of day, currently it will get Count of Monday:
var MondayCount = dates.Count(x => x.DayOfWeek == day);
https://dotnetfiddle.net/ZopkFY
Upvotes: 0
Reputation: 9319
public static Dictionary<DayOfWeek, int> CountDayOfWeeks(DateTime @from, DateTime to)
{
var start = @from.Date;
var ret = Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>().ToDictionary(x => x, x => 0);
while (start <= to)
{
ret[start.DayOfWeek]++;
start = start.AddDays(1);
}
return ret;
}
Upvotes: 0
Reputation: 476557
You better convert the days first to DateTime
instances:
DateTime d1 = new DateTime(2014,07,20);
DateTime d2 = new DateTime(2014,07,27);
Next you calculate the total days between the two dates:
int days = (int) Math.Floor((d2-d1).TotalDays)+1;
As well as the day of the week of the first date:
int dow = (int) d1.DayOfWeek;
Now we devide the number of days by seven and assign that number to all days: since this is the minimum occurences for each day:
int d7 = days/7;
int[] counts = new int[7];
for(int i = 0; i < 7; i++) {
counts[i] = d7;
}
The remainder of the days are distributed with the day of the week of d1
first:
int remainder = days-7*d7;
int dowi = dow;
while(remainder > 0) {
counts[dowi]++;
dowi = (dowi+1)%7;//next day of the week
remainder--;
}
Then we can return the arrray:
return counts;
Full method:
public static int[] countDelta (DateTime d1, DateTime d2) {
int days = (int) Math.Floor((d2-d1).TotalDays)+1;
int dow = (int) d1.DayOfWeek;
int d7 = days/7;
int[] counts = new int[7];
for(int i = 0; i < 7; i++) {
counts[i] = d7;
}
int remainder = days-7*d7;
int dowi = dow;
while(remainder > 0) {
counts[dowi]++;
dowi = (dowi+1)%7;//next day of the week
remainder--;
}
return counts;
}
The result of a csharp
interactive session:
csharp> Foo.countDelta(new DateTime(2014,07,20),new DateTime(2014,07,27));
{ 2, 1, 1, 1, 1, 1, 1 }
The method runs in constant time (if the dates differ much, this will not have an impact on performance). The only constraint is that calendar must be modern: if somewhere in history, people skipped a few "days of the week", this could result in some problems.
Upvotes: 1
Reputation: 21757
Try this:
DateTime start = new DateTime(2014,07,20);
DateTime end = new DateTime(2014,07,27);
TimeSpan ts = end - start;
int limit = ts.Days;
var result = Enumerable.Range(0,limit+1)
.Select(x => start.AddDays(x))
.GroupBy(x => x.DayOfWeek)
.Select(x => new {day = x.Key, count = x.Count()});
We create a range of dates from start to end, inclusive of both dates, and then group by the day of week to get the days and corresponding counts.
Upvotes: 3
Reputation: 787
the simple way is for loop each day in the period, and use switch case or if else to check the current date.DayOfWeek to count and save the week number, something like the following:
int mondays = 0;
switch(current.DayOfWeek){
case DayOfWeek.Monday:
mondays++;
break;
...
}
Upvotes: 0
Reputation: 805
You can try something like this. It may be not the best solution, but it's the first that came in mind:
var startDate = DateTime.Now;
var endDate = startDate.AddDays(15);
var rusultDictionary = new Dictionary<DayOfWeek, int>();
while (!startDate.Date.Equals(endDate.Date))
{
rusultDictionary[startDate.DayOfWeek] = rusultDictionary.ContainsKey(startDate.DayOfWeek) ? rusultDictionary[startDate.DayOfWeek] + 1 : 1;
startDate = startDate.AddDays(1);
}
Upvotes: 0