Для целей этого вопроса предположим, что пользователь будет из США и будет использовать стандартный григорианский календарь. Итак, календарная неделя начинается в воскресенье и заканчивается в субботу.Получите количество календарных недель между двумя датами в C#
То, что я пытаюсь сделать, - определить количество календарных недель, которые существуют между двумя датами. Прекрасный пример моей проблемы существует в октябре 2010 года. Между 10/16 и 10/31 существует 4 календарных недели.
- 10 октября - 16 октября
- 17 октября - 23 октября
- 24 октября - 30 октября
- 31 октября - 6 ноября
Я предпочел бы держаться подальше от любого закодированного логики, как:
if (Day == DayOfWeek.Saturday && LastDayOfMonth == 31) { ... }
Можно ли думать логически способ сделать это?
UPDATE:
Спасибо за все великие ответы, после некоторого рассмотрения здесь является решение, которое я использовал:
//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);
А вот методы из вспомогательного класса:
/// <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);
}
И если вам интересно, это то, что я делаю с датами:
//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.
}
Если я вас правильно понял, вы хотите, количество полных недель (который я думаю, должно быть от * понедельник * в воскресенье) между двумя указанными датами, поэтому с четверга, 18 июня в среду, 24 июня, вы не было бы одной недели (как в 7 дней), но никто, поскольку вы только проходите один понедельник один раз и не добираетесь до воскресенья, это правильно? – Treb
Это конкретное приложение требует Sun-Sat. Подумайте о 2 периодах оплаты в месяц (период 10/1 и период 10/16). Рабочая неделя в этом сценарии - Sun-Sat. Таким образом, период оплаты 10/16 работает через 4 календарных недели. Имеют смысл? –
Вы ищете простой формульный подход, или вы в порядке с алгоритмическим подходом? Кроме того, насколько важно, чтобы формула/алгоритм учитывала високосные годы/дни и т. Д.? – jrista