2009-03-02 123 views
4

我需要模擬一些關於季節的信息,並需要以年份不可知的方式根據開始/結束日期對其進行跟蹤。即我需要允許用戶將夏季定義爲5月15日和9月10日之間,並且每年都這樣做。爲日期範圍忽略年份日期的最佳做法

我需要做很多isThisDateInSeason類型的檢查)。所有日期操作功能(即日期,日曆)似乎只適用於有效日期,即包括年份信息。

有沒有關於如何做到這一點的最佳做法?我可以想到一些這樣做的黑客方式(即存儲每月的月份和日期或存儲日期,並將它們帶到一個基準年,以便我可以比較),但似乎可能有更好的方法。

我正在用Java或Groovy編寫它。

Joda-Time庫會在這裏幫助嗎?我沒有經驗,但它看起來有更多的靈活性。

我發現this question關於如何確定一個季節從日期,但重點是幾個月,我需要更多的靈活性,以包括日期。

+0

用戶間是否會使用相同的數據?即1個數據輸入,幾個用戶可以根據他們的位置看到夏季還是冬季?或者每個用戶都有自己的數據? – Rosstified 2009-03-02 02:00:51

+0

它將取決於位置,用戶將能夠進一步定製它。 – 2009-03-02 03:03:13

回答

4

如果每個用戶擁有他們自己的數據(即他們指定他們的季節,然後他們輸入他們自己的信息),那麼你可以存儲與季節的數據作爲其一部分,但我有一種感覺,你是用於定義不同季節的衆多用戶共享數據。

由於閏年可能會導致意想不到的問題,即試圖將2月29日設置爲非閏年會導致問題/異常,所以您必須非常小心'正常化'日期。

我已經把下面放在一起,毫無疑問地將它的C#放在一起,但概念將是相同的。我實際上測試過代碼,但是作爲psudo代碼可能會有所幫助。

public class SeasonChecker 
{ 
    public enum Season {Summer, Autumn, Winter, Spring}; 
    private List<SeasonRange> _seasons = new List<SeasonRange>(); 

    public void DefineSeason(Season season, DateTime starting, DateTime ending) 
    { 
     starting = starting.Date; 
     ending = ending.Date; 

     if(ending.Month < starting.Month) 
     { 
      // split into 2 
      DateTime tmp_ending = new DateTime(ending.Year, 12, 31); 
      DateTime tmp_starting = new DateTime(starting.Year, 1, 1); 

      SeasonRange r1 = new SeasonRange() { Season = season, Starting= tmp_starting, Ending = ending }; 
      SeasonRange r2 = new SeasonRange() { Season = season, Starting= starting, Ending = tmp_ending }; 

      this._seasons.Add(r1); 
      this._seasons.Add(r2); 
     } 
     else 
     { 
      SeasonRange r1 = new SeasonRange() { Season = season, Starting= starting, Ending = ending }; 
      this._seasons.Add(r1); 
     } 
    } 

    public Season GetSeason(DateTime check) 
    { 
     foreach(SeasonRange range in _seasons) 
     { 
      if(range.InRange(check)) 
       return range.Season; 
     } 

     throw new ArgumentOutOfRangeException("Does not fall into any season"); 
    } 


    private class SeasonRange 
    { 
     public DateTime Starting; 
     public DateTime Ending; 
     public Season Season; 

     public bool InRange(DateTime test) 
     { 
      if(test.Month == Starting.Month) 
      { 
       if(test.Day >= Starting.Day) 
       { 
        return true; 
       } 
      } 
      else if(test.Month == Ending.Month) 
      { 
       if(test.Day <= Ending.Day) 
       { 
        return true; 
       } 
      } 
      else if(test.Month > Starting.Month && test.Month < Ending.Month) 
      { 
       return true; 
      } 

      return false; 
     } 

    } 
} 

請注意,上面的代碼假設季節不會在同一個月開始和結束 - 我認爲這是相當安全的!

+0

羅斯 - 非常感謝偉大的代碼示例。我需要一個地理學的通用定義,但也需要用戶自定義的能力。 奇怪的是,如果不存儲年份,無論是在Java還是C#中都沒有辦法做到這一點,但我想它不會經常出現足以證明特殊API的合理性。 – 2009-03-02 20:02:04

2

我想你將不得不推出你自己的DateRange類,儘管這是一個常見的問題,你希望已經有一個聰明的實用程序。作爲處理季節的一般要點,你還必須考慮到地理,這會讓生活變得非常困難。在奧茲我們是美國的反面,所以夏天從十一月到二月。

2

數據在哪裏?如果它在數據庫中,我會考慮爲日期創建一個表格(如OLAP中的時間維度)。然後,您可以在某個時間維度示例中爲財務季度計算您季節的列。 (這是假設你的賽季不會改變,但是有固定的日期)。

所有「如果在賽季中的日期」類型檢查將預先構建,將計算季節的成本計入您的設置時間,而不是您的運行時間。

編輯:剛剛看到您對用戶可配置季節日期的評論。這仍然可以工作,因爲您可以在數據庫中執行連接,包括時間維度,可以更容易地使用Java中的一組數據。

相關問題