2009-03-02 17 views
4

季節に関するいくつかの情報をモデル化する必要があり、開始/終了日に基づいて年齢に関係なく追跡する必要があります。私。私はユーザーが5月15日から9月10日までの間に夏を定義することを許可し、すべての年にそれを行う必要があります。日付範囲の年月を無視するためのベストプラクティス

isThisDateInSeasonタイプのチェックをたくさん行う必要があります。すべての日付操作関数(日付、カレンダー)は、有効な日付、つまり年の情報だけを使用しているように見えます。

これを行う方法に関するベストプラクティスはありますか?私はそれを行うためのハッキーな方法(すなわち、月や月の月を保存するか、日付を保存して基準年に持っていくことができるので、私は比較できる)を考えることができますが、より良い方法があるようです。

これはJavaまたはGroovyで書いています。

Joda-Timeライブラリはここで役立つでしょうか?私はそれに経験はありませんが、はるかに柔軟性があるように見えます。

季節を特定する方法については、this questionが見つかりましたが、それは数ヶ月に焦点を当てています。日付を含めるのに柔軟性が必要です。

+0

ユーザー間で同じデータを使用できますか? 1つのデータ入力と複数のユーザーが、その場所に応じて夏か冬のどちらかを見ることができますか?または、各ユーザーは独自のデータを持っていますか? – Rosstified

+0

それは場所に依存し、ユーザーはそれをさらにカスタマイズすることができます。 –

答えて

4

各ユーザーが自分のデータを所有している場合(つまり、季節を指定してから自分の情報を入力した場合)、シーズンのデータをその一部として保存できますが、シーズンを異なる方法で定義する多数のユーザー間で共有されるデータ用です。

うるう年が予期せぬ問題を引き起こす可能性があるため、2月29日にうるう年を設定しようとすると問題/例外が発生するため、日付を '正規化'するのに非常に注意する必要があります。

私はunforutnatlyその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; 
     } 

    } 
} 

注上記のコードは、シーズンが開始し、同月に終了しないという仮定を作る - 私は思うかなり安全な1!

+0

ロス - 偉大なコードサンプルのために多くの感謝。地理的に共通の定義と、ユーザーがカスタマイズできる機能の両方が必要です。 年を保存せずにJavaやC#でそれを行う方法がないのは奇妙ですが、特殊なAPIを正当化するのに十分な頻度ではないと思います。 –

+0

NYWebGuy - N.P.うん、それはかなり一般的な問題のように見える、あなたが最後に何を思いつくのか興味がある。私が追加できるのは、n/s半球をカバーする2つのテンプレートを持つことができ、ユーザーがフォームをカスタマイズできることだけです。 – Rosstified

2

私はあなた自身のDateRangeクラスをロールバックする必要があると思いますが、これは既にそこに巧妙なユーティリティが存在することを望むような共通の問題です。季節を扱う際の一般的なポイントとして、地理を考慮する必要があります。これは人生を本当に難しくします。オズの伝説はアメリカと逆のので、サマーは11月から2月までです。

2

データはどこにありますか?データベースにある場合は、日付用のテーブルを作成することを検討します(OLAPの時間ディメンションなど)。 Time Dimensionのいくつかの例では、四半期ごとの季節の列を計算することができます。 (これはあなたの季節は変わらず、日付が固定されていると仮定しています)。

すべての「シーズンの日付」型チェックは、実行時間ではなくセットアップ時間にシーズンを計算するコストをプッシュするために事前設定されます。

編集:ユーザー設定可能な季節の日付にあなたのコメントを見ました。これは、Javaのデータセットで作業するのが簡単な時間ディメンションを含むデータベースで結合を行うことができるため、引き続き機能します。

+0

ありがとう、@レア。私がGroovy/GORMを使って作業していますが、私はあなたが提案しているものと似たようなことをしなければならないように見えるので、最初はDBレベルよりも少し上を保とうとしており、後で最適化するように働きます。 –

関連する問題