我會在這坐刺...你可以使用LINQ生成所有日期範圍一次。這不是最漂亮的查詢,但它的工作原理。
DateTime start = ...
DateTime end = ...
var cal = System.Globalization.CultureInfo.CurrentCulture.Calendar;
var range =
from y in Enumerable.Range(start.Year, end.Year - start.Year + 1)
let maxMonth = y < end.Year ? cal.GetMonthsInYear(y) : end.Month
let minMonth = y > start.Year ? 1 : start.Month
from m in Enumerable.Range(minMonth, maxMonth - minMonth + 1)
let isStart = (y == start.Year && m == start.Month)
let isEnd = (y == end.Year && m == end.Month)
select new
{
StartDate = isStart ? start : new DateTime(y, m, 1),
EndDate = isEnd ? end : new DateTime(y, m, cal.GetDaysInMonth(y, m)),
NumberOfMonths = isStart || isEnd ? .5 : 1
};
它重複多年來從start
到end
,然後在幾個月迭代每年,與邊緣的情況下(isStart
和isEnd
)特殊處理。這個基本的算法可以被封裝在這樣一個函數中:
public class DateTimeRange
{
Date StartDate { get; set; }
Date EndDate { get; set; }
float NumberOfMonths { get; set; }
}
public static IEnumerable<DateTimeRange> SplitByMonths(DateTime start,
DateTime end,
Calendar cal)
{
return (
from y in Enumerable.Range(start.Year, end.Year - start.Year + 1)
let maxMonth = y < end.Year ? cal.GetMonthsInYear(y) : end.Month
let minMonth = y > start.Year ? 1 : start.Month
from m in Enumerable.Range(minMonth, maxMonth - minMonth + 1)
let isStart = (y == start.Year && m == start.Month)
let isEnd = (y == end.Year && m == end.Month)
select new DateTimeRange
{
StartDate = isStart ? start : new DateTime(y, m, 1),
EndDate = isEnd ? end : new DateTime(y, m, cal.GetDaysInMonth(y, m)),
NumberOfMonths = isStart || isEnd ? .5 : 1
});
}
你能用一些代碼和細節來說明你的問題嗎? – 2013-05-07 23:08:47
爲什麼5-20-2013 - 5-31-2013定義爲.5個月,而不是更精確? – 2013-05-07 23:14:01
您是否已經嘗試自行解決問題?如果是,發佈一些代碼。如果沒有,在你問之前就這麼做。 – filipko 2013-05-07 23:20:27