我正在創建圖書館管理系統。如何計算C#中兩個日期之間的天數減去星期天?
我已經使用時間戳來計算日期差異,並藉助於日期差異我正在計算罰款也。
現在這個日期差異包括一週中的所有日子。但對於圖書館申請,罰款僅在周內收取6天(週一至週六)。
我無法做到這一點。
任何人都可以幫助我完成這項任務嗎?
在此先感謝!
我正在創建圖書館管理系統。如何計算C#中兩個日期之間的天數減去星期天?
我已經使用時間戳來計算日期差異,並藉助於日期差異我正在計算罰款也。
現在這個日期差異包括一週中的所有日子。但對於圖書館申請,罰款僅在周內收取6天(週一至週六)。
我無法做到這一點。
任何人都可以幫助我完成這項任務嗎?
在此先感謝!
基本上,你可以計算原始天數;你需要找到從這個數字中減去的星期日數。你知道每7天是一個星期天,所以你可以將原始天數除以7,並從原始天數中減去該數字。現在,您需要刪除存在的剩餘時間星期日的數量;原始天數的mod會告訴您剩餘的天數。要了解該跨度是否包含星期日,您必須知道第一天的星期幾;如果您將星期一定義爲0,星期二爲1,星期三爲3等,那麼如果將跨度開始的星期幾的值添加到原始數的mod(7)天,如果這個數字是6或更大,你已經跨過了一個額外的星期天,並且應該從你的罰款數字中刪除1天。
僞代碼:
int fine;
int numdays = endDay - startDay;
fine = numdays - (numdays/7);
int dayOfWeek = startDate.DayOfWeek;
if (dayOfWeek + (numdays % 7) > 6)
{
fine = fine - 1;
}
這將做到這一點:
private int DaysLate(DateTime dueDate, DateTime returnDate)
{
var ts = returnDate - dueDate;
int dayCount = 0;
for (int i = 1; i <= ts.Days; i++)
{
if (dueDate.AddDays(i).DayOfWeek != DayOfWeek.Sunday)
dayCount++;
}
return dayCount;
}
充分利用TimeSpan/Date類絕對是走向IMO的方式。 – 2009-07-07 18:16:18
到目前爲止最好的答案。但是:一般來說,使用「DateTime.Now」是一種「氣味」。 例如,你如何單元測試這個?單元測試的結果可能與星期一的星期一不同。 然後,最好添加一個參數,例如「DateTime returnedDate」並從中減去dueDate。其次,要對DateTime.Now保持警惕。它計算當前日期和時間,考慮時區。奇怪的事情可能會在夏令時發生變化時每年發生兩次。 – 2009-07-07 18:29:08
快速測試這一點,似乎滿足您的需要:(編輯:增加了清晰一些意見和更正後的代碼錯誤)
private static int CalculateDaysToFine(DateTime dateDue, DateTime dateIn)
{
TimeSpan ts = dateIn - dateDue;
int daysToFine = ts.Days - (ts.Days/7); //subtract full weeks (1 Sunday each)
if (((int)dateDue.DayOfWeek + (ts.Days%7)) >6) //check to see if the remaining days contain a Sunday
daysToFine--;
return daysToFine;
}
我Linqy方法(有由於是更易於閱讀,但需要一個小PERF創建一個結構類型列表):
private int DaysLate(DateTime dateDue, DateTime dateReturned)
{
return getDayList(dateDue, dateReturned).Where(d => d.DayOfWeek != DayOfWeek.Sunday).Count();
}
private List<DateTime> getDayList(DateTime begin, DateTime end)
{
List<DateTime> dates = new List<DateTime>();
DateTime counter = begin;
while (counter <= end)
{
dates.Add(counter);
counter = counter.AddDays(1);
}
return dates;
}
基於Jacob Proffitt的答案,但沒有內存列表的開銷。由於DaysBetween動態生成它的日期,計數計算生成的列表:
int c = DaysBetween(begin, end).Count(d => d.DayOfWeek != DayOfWeek.Sunday);
private IEnumerable<DateTime> DaysBetween(DateTime begin, DateTime end)
{
for(var d = begin; d <= end; d.AddDays(1)) yield return d;
}
當然,如果你不想showoff LINQ,你可以把它簡化,並用一個函數去:
private int DaysBetween(DateTime begin, DateTime end)
{
int count = 0;
for(var d = begin; d <= end; d.AddDays(1))
if(d.DayOfWeek != DayOfWeek.Sunday) count++
return count;
}
恕我直言,這兩個都比每個人的最愛(烏鴉的答案)更清潔,更易於理解,調試,排除故障和修改。
當然,這是一個O(n)解決方案,這意味着分離的日子越多,計算所需的時間就越長。雖然這可能是好於大多數的實際應用,在某些情況下,你可能更喜歡基於公式的方法,東西沿着這些線路:
int q = end.Subtract(begin).Days - (end.Subtract(begin).Days/7);
這裏是我的實現。我的目標是使用類似McWafflestix的方法執行O(1)。我試圖保持它的可讀性,最大化OO代碼並儘可能地減少「數學魔法」(並非我對數學或魔術有任何反應)。
這個想法是確定截止日期和返回日期之間的完整7天周的數量,以及通過更正數字來調整它的「增量」天數。只要您可以保證星期日(假定您的描述不會成爲問題)的到期日和退回日期都不會發生,就可以按預期工作。
static int CalculateFineDays(DateTime due, DateTime returned)
{
TimeSpan ts = returned - due;
if (ts < TimeSpan.Zero)
return 0;
int delta = returned.DayOfWeek - due.DayOfWeek;
return delta + ts.Subtract(TimeSpan.FromDays(delta)).Days * 6/7;
}
編輯:我曾提出了一個解決方案更早發現了一個bug在裏面,和我的工作就可以了我減少了代碼到這一點。
感謝您的回覆。 非常好的解釋 你能通過編碼的方式來編程地表示解釋嗎? – sheetal 2009-07-07 17:23:45
添加了僞代碼。 – 2009-07-07 17:24:48