计算给定日期范围内的星期一数

时间:2022-08-14 01:26:43

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#.

我目前在C#工作。

14 个解决方案

#1


36  

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;
}

#2


20  

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

由于您使用的是C#,如果您使用的是C#3.0,则可以使用LINQ。

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

假设您有一个包含日期为DateTime类型的Array / List / IQueryable等:

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}

Added:

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

不确定你是否意味着将它们分组并计算它们,但是这里也是如何在LINQ中做到这一点:

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());
}

#3


15  

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

看看计算星期几的不同算法是很有趣的,而且@Gabe Hollombe在这个主题上指向WP是一个好主意(我记得大约二十年前在COBOL中实现了Zeller的同余),但它更像是当他们问到时间是什么时,把某人的蓝图交给他人。

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 the end date for "Mondayness", so if this was desired, make the for loop evaluate

这当然不会评估“星期一”的结束日期,因此如果需要,请进行for循环评估

dt < endDate.AddDays(1.0)

#4


4  

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.

其中DifferenceInDays返回End - 以天为单位开始,DayOfWeek以整数形式返回星期几。 DayOfWeek使用的映射并不重要,只要它正在增加并与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.

请注意,此算法假定日期范围包含在内。如果End不应该是范围的一部分,则必须稍微调整算法。

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

翻译成C#留给读者练习。

#5


3  

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.

如果将日期表示为天数,那么两个值加上一(天)和除以7之间的差异就是答案的大部分。如果两个结束日期都是相关日期,请添加一个。

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

编辑:纠正'模7'到'除以7' - 谢谢。这是整数除法。

#6


3  

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

我遇到了一个使用linq解决这个问题的方法。

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

Hope that helps.

希望有所帮助。

#7


1  

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

添加尽可能小的数字,使第一天成为星期一。减去最小的可能数字,使最后一天成为星期一。计算天数之差并除以7。

#8


1  

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:

将日期转换为朱利安日数,然后做一些数学运算。由于星期一是零mod 7,你可以这样计算:

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

#9


1  

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.

我今天也有同样的需要。我开始使用cjm函数,因为我不理解JonB函数,因为Cyber​​herbalist函数不是线性的。

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.

如果从开始日开始,我们在endDay之前首先遇到dayImLookingFor,那么返回true之间的函数。

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

我通过计算从startDay到其他两天的天数来完成介于两者之间的功能:

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;
    }
}

#10


1  

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(
                                                  startDate.AddDays(d).Year,
                                                  startDate.AddDays(d).Month,
                                                  startDate.AddDays(d).Day);

        //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;
}

#11


1  

This will return a collection of integers showing how many times each day of the week 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 which lets you do FirstDate.TotalDaysOfWeeks(SecondDate) and returns a Dictionary

或稍微变化,让你做FirstDate.TotalDaysOfWeeks(SecondDate)并返回一个字典

    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;
    }

#12


0  

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

我的报告也有类似的问题。我需要两个日期之间的工作日数。我可以在日期中循环并计算,但我的离散数学训练不会让我。这是我在VBA中编写的函数,用于获取两个日期之间的工作日数。我确定.net有类似的WeekDay功能。

   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

#13


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)
    StartDate = StartDate.AddDays(1);

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

#14


0  

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

四年后,我以为我会做一个测试:

[TestMethod]
public void ShouldFindFridaysInTimeSpan()
{
    //reference: http://*.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++)
    {
        setOfDates.Add(now.AddDays(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 use of TimeSpan is a bit of overkill---actually I wanted to query TimeSpan directly.

我对TimeSpan的使用有点过分 - 实际上我想直接查询TimeSpan。

#1


36  

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;
}

#2


20  

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

由于您使用的是C#,如果您使用的是C#3.0,则可以使用LINQ。

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

假设您有一个包含日期为DateTime类型的Array / List / IQueryable等:

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}

Added:

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

不确定你是否意味着将它们分组并计算它们,但是这里也是如何在LINQ中做到这一点:

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());
}

#3


15  

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

看看计算星期几的不同算法是很有趣的,而且@Gabe Hollombe在这个主题上指向WP是一个好主意(我记得大约二十年前在COBOL中实现了Zeller的同余),但它更像是当他们问到时间是什么时,把某人的蓝图交给他人。

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 the end date for "Mondayness", so if this was desired, make the for loop evaluate

这当然不会评估“星期一”的结束日期,因此如果需要,请进行for循环评估

dt < endDate.AddDays(1.0)

#4


4  

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.

其中DifferenceInDays返回End - 以天为单位开始,DayOfWeek以整数形式返回星期几。 DayOfWeek使用的映射并不重要,只要它正在增加并与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.

请注意,此算法假定日期范围包含在内。如果End不应该是范围的一部分,则必须稍微调整算法。

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

翻译成C#留给读者练习。

#5


3  

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.

如果将日期表示为天数,那么两个值加上一(天)和除以7之间的差异就是答案的大部分。如果两个结束日期都是相关日期,请添加一个。

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

编辑:纠正'模7'到'除以7' - 谢谢。这是整数除法。

#6


3  

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

我遇到了一个使用linq解决这个问题的方法。

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

Hope that helps.

希望有所帮助。

#7


1  

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

添加尽可能小的数字,使第一天成为星期一。减去最小的可能数字,使最后一天成为星期一。计算天数之差并除以7。

#8


1  

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:

将日期转换为朱利安日数,然后做一些数学运算。由于星期一是零mod 7,你可以这样计算:

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

#9


1  

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.

我今天也有同样的需要。我开始使用cjm函数,因为我不理解JonB函数,因为Cyber​​herbalist函数不是线性的。

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.

如果从开始日开始,我们在endDay之前首先遇到dayImLookingFor,那么返回true之间的函数。

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

我通过计算从startDay到其他两天的天数来完成介于两者之间的功能:

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;
    }
}

#10


1  

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(
                                                  startDate.AddDays(d).Year,
                                                  startDate.AddDays(d).Month,
                                                  startDate.AddDays(d).Day);

        //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;
}

#11


1  

This will return a collection of integers showing how many times each day of the week 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 which lets you do FirstDate.TotalDaysOfWeeks(SecondDate) and returns a Dictionary

或稍微变化,让你做FirstDate.TotalDaysOfWeeks(SecondDate)并返回一个字典

    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;
    }

#12


0  

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

我的报告也有类似的问题。我需要两个日期之间的工作日数。我可以在日期中循环并计算,但我的离散数学训练不会让我。这是我在VBA中编写的函数,用于获取两个日期之间的工作日数。我确定.net有类似的WeekDay功能。

   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

#13


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)
    StartDate = StartDate.AddDays(1);

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

#14


0  

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

四年后,我以为我会做一个测试:

[TestMethod]
public void ShouldFindFridaysInTimeSpan()
{
    //reference: http://*.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++)
    {
        setOfDates.Add(now.AddDays(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 use of TimeSpan is a bit of overkill---actually I wanted to query TimeSpan directly.

我对TimeSpan的使用有点过分 - 实际上我想直接查询TimeSpan。