Vì mục đích của câu hỏi này, giả sử người dùng sẽ đến từ Hoa Kỳ và sẽ sử dụng lịch Gregorian chuẩn. Vì vậy, một tuần dương lịch bắt đầu vào Chủ Nhật và kết thúc vào Thứ Bảy.Lấy số tuần theo lịch giữa 2 ngày trong C#
Điều tôi đang cố gắng làm là xác định số tuần lịch tồn tại giữa hai ngày. Một ví dụ hoàn hảo về vấn đề của tôi tồn tại trong tháng 10 năm 2010. Từ 10/16 đến 10/31 có 4 tuần theo lịch.
- 10 tháng mười - 16 tháng 10
- 17 tháng mười - 23 tháng 10
- 24 Tháng Mười - 30 tháng mười
- Tháng mười 31 - tháng 11 6
Tôi muốn tránh xa mọi logic được mã hóa cứng như:
if (Day == DayOfWeek.Saturday && LastDayOfMonth == 31) { ... }
Có ai nghĩ cách hợp lý để làm điều này không?
UPDATE:
Cảm ơn tất cả các câu trả lời tuyệt vời, sau khi một số xem xét ở đây là giải pháp tôi sử dụng:
//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);
Và đây là những phương pháp từ lớp helper:
/// <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);
}
Và nếu bạn tò mò, đây là những gì tôi sẽ làm với những ngày:
//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.
}
Nếu tôi hiểu chính xác, bạn muốn số tuần đầy đủ (tôi nghĩ là từ * Thứ Hai * đến Chủ Nhật) giữa hai ngày cụ thể, từ Thứ Năm, 18 Tháng Sáu đến Thứ Tư, 24 Tháng Sáu, bạn sẽ không có một tuần (như trong 7 ngày), nhưng không có, vì bạn chỉ vượt qua thứ hai một lần, và không đạt đến chủ nhật sau đó, là chính xác? – Treb
Ứng dụng cụ thể này gọi cho Sun-Sat. Hãy nghĩ về 2 kỳ lương trong một tháng (giai đoạn 10/1 và thời kỳ 10/16). Một tuần làm việc trong kịch bản này là Sun-Sat. Vì vậy, giai đoạn trả lương 10/16 chạy qua 4 tuần theo lịch. Có lý? –
Bạn đang tìm kiếm một cách tiếp cận công thức đơn giản, hoặc bạn có ok với một cách tiếp cận thuật toán? Ngoài ra, công thức/thuật toán có tính đến năm nhuận/ngày, v.v. quan trọng như thế nào? – jrista