获取C#中两个日期之间的日历周数

Phi*_*tes 14 c# asp.net

出于这个问题的目的,让我们假设用户来自美国,并将使用标准公历.因此,日历周从星期日开始,到星期六结束.

我要做的是确定两个日期之间存在的日历周数.我的问题的一个完美的例子存在于2010年10月.在10/16和10/31之间有4个日历周.


  1. 10月10日至10月16日
  2. 10月17日 - 10月23日
  3. 10月24日至10月30日
  4. 10月31日至11月6日

我宁愿远离任何硬编码逻辑,如:

if (Day == DayOfWeek.Saturday && LastDayOfMonth == 31) { ... }
Run Code Online (Sandbox Code Playgroud)

谁能想到一个合乎逻辑的方法来做到这一点?

更新:
感谢所有伟大的回应,经过一些考虑后,我使用的解决方案:

//get the start and end dates of the current pay period
DateTime currentPeriodStart = SelectedPeriod.Model.PeriodStart;
DateTime currentPeriodEnd = SelectedPeriod.Model.PeriodEnd;

//get the first sunday & last saturday span that encapsulates the current pay period
DateTime firstSunday = DayExtensions.SundayBeforePeriodStart(currentPeriodStart);
DateTime lastSaturday = DayExtensions.SaturdayAfterPeriodEnd(currentPeriodEnd);

//get the number of calendar weeks in the span
int numberOfCalendarWeeks = DayExtensions.CalendarWeeks(firstSunday, lastSaturday);
Run Code Online (Sandbox Code Playgroud)

以下是辅助类的方法:

    /// <summary>
    /// Get the first Sunday before the pay period start date
    /// </summary>
    /// <param name="periodStartDate">Date of the pay period start date</param>
    /// <returns></returns>
    public static DateTime SundayBeforePeriodStart(DateTime periodStartDate)
    {
        DateTime firstDayOfWeekBeforeStartDate;

        int daysBetweenStartDateAndPreviousFirstDayOfWeek = (int)periodStartDate.DayOfWeek - (int)DayOfWeek.Sunday;

        if (daysBetweenStartDateAndPreviousFirstDayOfWeek >= 0)
        {
            firstDayOfWeekBeforeStartDate = periodStartDate.AddDays(-daysBetweenStartDateAndPreviousFirstDayOfWeek);
        }
        else
        {
            firstDayOfWeekBeforeStartDate = periodStartDate.AddDays(-(daysBetweenStartDateAndPreviousFirstDayOfWeek + 7));
        }

        return firstDayOfWeekBeforeStartDate;
    }

    /// <summary>
    /// Get the first Saturday after the period end date
    /// </summary>
    /// <param name="periodEndDate">Date of the pay period end date</param>
    /// <returns></returns>
    public static DateTime SaturdayAfterPeriodEnd(DateTime periodEndDate)
    {
        DateTime lastDayOfWeekAfterEndDate;

        int daysBetweenEndDateAndFollowingLastDayOfWeek = (int)DayOfWeek.Saturday - (int)periodEndDate.DayOfWeek;

        if (daysBetweenEndDateAndFollowingLastDayOfWeek >= 0)
        {
            lastDayOfWeekAfterEndDate = periodEndDate.AddDays(daysBetweenEndDateAndFollowingLastDayOfWeek);
        }
        else
        {
            lastDayOfWeekAfterEndDate = periodEndDate.AddDays(daysBetweenEndDateAndFollowingLastDayOfWeek + 7);
        }

        return lastDayOfWeekAfterEndDate;
    }

    /// <summary>
    /// Get the calendar weeks between 2 dates
    /// </summary>
    /// <param name="d1">First day of date span</param>
    /// <param name="d2">Last day of date span</param>
    /// <returns></returns>
    public static int CalendarWeeks(DateTime d1, DateTime d2)
    {
        return 1 + (int)((d2 - d1).TotalDays / 7);
    }
Run Code Online (Sandbox Code Playgroud)

如果你很好奇,这就是我最后做的日期:

//create an array of all the sundays in this span
DateTime[] _sundays = new DateTime[numberOfCalendarWeeks];

//put the first sunday in the period
_sundays[0] = firstSunday;

//step through each week and get each sunday until you reach the last saturday
for (int i = 1; i <= numberOfCalendarWeeks - 1; i++)
{
     DateTime d = new DateTime();
     d = firstSunday.AddDays(i * 7);
      _sundays[i] = d;
}

for (int i = 0; i <= _sundays.Length-1; i++)
{
      //bind my view model with each sunday.
}
Run Code Online (Sandbox Code Playgroud)

小智 7

这是一个通用的解决方案,我认为应该适用于周开始和结束日的任何选择.您可以根据情况简化它,但是如果有必要,此代码可让您选择更改周的开始和结束(例如,周一到周日).在工资单应用程序中更改日历周的定义并不罕见.

        DateTime periodStart = new DateTime(2010, 10, 17);
        DateTime periodEnd = new DateTime(2010, 11, 14);

        const DayOfWeek FIRST_DAY_OF_WEEK = DayOfWeek.Monday;
        const DayOfWeek LAST_DAY_OF_WEEK = DayOfWeek.Sunday;
        const int DAYS_IN_WEEK = 7;

        DateTime firstDayOfWeekBeforeStartDate;
        int daysBetweenStartDateAndPreviousFirstDayOfWeek = (int)periodStart.DayOfWeek - (int)FIRST_DAY_OF_WEEK;
        if (daysBetweenStartDateAndPreviousFirstDayOfWeek >= 0)
        {
            firstDayOfWeekBeforeStartDate = periodStart.AddDays(-daysBetweenStartDateAndPreviousFirstDayOfWeek);
        }
        else
        {
            firstDayOfWeekBeforeStartDate = periodStart.AddDays(-(daysBetweenStartDateAndPreviousFirstDayOfWeek + DAYS_IN_WEEK));
        }

        DateTime lastDayOfWeekAfterEndDate;
        int daysBetweenEndDateAndFollowingLastDayOfWeek = (int)LAST_DAY_OF_WEEK - (int)periodEnd.DayOfWeek;
        if (daysBetweenEndDateAndFollowingLastDayOfWeek >= 0)
        {
            lastDayOfWeekAfterEndDate = periodEnd.AddDays(daysBetweenEndDateAndFollowingLastDayOfWeek);
        }
        else
        {
            lastDayOfWeekAfterEndDate = periodEnd.AddDays(daysBetweenEndDateAndFollowingLastDayOfWeek + DAYS_IN_WEEK);
        }

        int calendarWeeks = 1 + (int)((lastDayOfWeekAfterEndDate - firstDayOfWeekBeforeStartDate).TotalDays / DAYS_IN_WEEK);
Run Code Online (Sandbox Code Playgroud)


Ant*_*ram 6

我要解决这个问题的方法是在任何特定日期获得本周的开始.使用它,您可以从结束日期的结果中减去开始日期的结果.你的日差总是7的倍数,所以除以1(0天=> 1周,7天=> 2周等).这将告诉您任何两个日期涵盖或代表的日历周数.

static int GetWeeksCovered(DateTime startDate, DateTime endDate)
{
    if (endDate < startDate)
        throw new ArgumentException("endDate cannot be less than startDate");

    return (GetBeginningOfWeek(endDate).Subtract(GetBeginningOfWeek(startDate)).Days / 7) + 1;
}

static DateTime GetBeginningOfWeek(DateTime date)
{
    return date.AddDays(-1 * (int)date.DayOfWeek).Date;
}
Run Code Online (Sandbox Code Playgroud)
  • 2010年10月16日和2010年10月16日=> 1周(或代表).
  • 根据规范,2010年10月16日和2010年10月31日=> 4周.