2010-12-06 41 views
0

我需要計算兩個日期之間的工作日數。工作日是星期一至星期五的任何一天,節假日除外。下面的代碼是這樣做的,但它使用了一個循環。有沒有人看到擺脫循環或至少優化它的方式?請幫助優化此循環

感謝 康斯坦丁


using System; 
using System.Linq; 

namespace consapp 
{ 
    static class Program 
    { 
     static void Main(string[] args) 
     { 
      var holidays = new DateTime[] { new DateTime(2010, 11, 23), new DateTime(2010, 11, 30) }; 

      var date_start = new DateTime(2010, 12, 3); 
      var date_end = date_start.AddDays(-9.9); 
      var duration = (date_end - date_start).Duration(); 

      for (var d = date_end; d < date_start; d = d.Date.AddDays(1)) 
      { 
       if (holidays.Contains(d.Date) || d.DayOfWeek == DayOfWeek.Saturday || d.DayOfWeek == DayOfWeek.Sunday) 
       { 
        duration -= TimeSpan.FromDays(1) - d.TimeOfDay; 
       } 
      } 
      Console.WriteLine(duration); 
     } 
    } 
} 
+5

在嘗試優化之前,您是否首次測試它是否正常工作?你是否分析了代碼以確保這是瓶頸? – 2010-12-06 19:32:11

+0

你的程序通常運行什麼日期範圍?代碼現在表現如何以及您需要如何執行?雖然我確信有更好的方法來做這件事,但我會首先確認它的表現不佳。 – 2010-12-06 19:32:19

+0

[計算兩個日期之間的工作天數?]可能重複(http://stackoverflow.com/questions/1617049/calculate-the-number-of-business-days-between-two-dates) – NotMe 2010-12-06 19:32:51

回答

0

我會研究像下面這樣的算法。 (對不起,沒有提供代碼。)

  1. 計算你的開始和結束日期之間整整7天的週數。您應該可以使用.NET DateTime和TimeSpan對象進行此操作。
  2. 對於每個完整的7天工作周,請在結果中添加5天。
  3. 找出包括您的開始和結束日期的部分星期。
  4. 循環播放您的假期,並在開始和結束日期之間爲每個假期減少1的結果。循環在這裏比較好,因爲可能會比開始和結束日期之間的天數少得多。

玩得開心!

編輯:對於源代碼,看看這個答案:Calculate the number of business days between two dates?

0

是表現確實有問題嗎?除非分析表明否則我猜這個代碼並不會真的減慢你的應用程序。除非您計算每秒數千個長時間間隔的工作日,否則性能應該沒有問題。

如果您的假期列表比兩個日期大得多,則將其轉換爲具有O(1)查找時間的HashSet<T>

當然,你可以轉過身的代碼。所以你不會在這段時間內循環播放,而是在假期中循環播放。然後,您只需計算間隔內的週日數(應該是簡單的數學運算),然後減去一週中的假期數。

如果確實有必要,您可以預先計算自某個固定日期以來的工作日,然後從期末的查找結果中減去期間開始時的查找結果。

0

,如果你想更快的代碼,不要在循環中的每一天範圍:

從您的假期表中刪除所有星期日或星期六的假期,然後使用時間跨度方法爲您提供兩個日期之間的天數。用一個小數學(考慮整數除以7),可以得到該範圍中的星期四天的數量,從該數字中減去週末沒有落下的假期數,並且完成。

0

只需按照原樣滾動即可。由於邊界很小,這不會浪費太多時間。當你有一些工作代碼時,繼續前進。沒有必要無情地無故優化代碼。

0

只是因爲我一開始這是一個有趣的益智,下面的代碼:

[Test] 
    public void TestDateTime() { 
     var start = DateTime.Now.Date; 
     var end = DateTime.Now.Date.AddDays(35); 
     var workdays = (end - start).Days - ((end - start).Days/7)*2 
      - (((end - start).Days%7==0)?0:(((int)start.DayOfWeek==0)?1:Math.Max(Math.Min((int)start.DayOfWeek + (end - start).Days%7 - 6, 2), 0))); 
     new []{DateTime.Now.AddDays(19), DateTime.Now.AddDays(20)}.ToList().ForEach(
      x => { if (x.DayOfWeek != DayOfWeek.Saturday && x.DayOfWeek != DayOfWeek.Sunday) workdays--; }); 
     Console.Out.WriteLine("workdays = {0}", workdays); 
    } 

聖誕節和節禮日被列爲假日。