5

季節に関するいくつかの情報をモデル化する必要があり、年にとらわれない方法で開始日/終了日に基づいてそれらを追跡する必要があります。つまり、ユーザーが夏を 5 月 15 日から 9 月 10 日の間と定義できるようにする必要があり、それをすべての年で行う必要があります。

タイプ isThisDateInSeason の多くのチェックを行う必要があります)。すべての日付操作関数 (つまり、日付、カレンダー) は、有効な日付 (年情報を含む) でのみ機能するようです。

これを行う方法に関するベストプラクティスはありますか? 私はそれを行うためのハックな方法をたくさん考えることができます(つまり、月と日を保存するか、日付を保存して、比較できるようにそれらをベースラインの年に持ってくるだけです)が、より良い方法があるようです.

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

Joda -Timeライブラリはここで役立ちますか? 私はそれを経験していませんが、はるかに柔軟性があるようです。

日付から季節を識別する方法に関するこの質問を見つけましたが、それは月に焦点を当てているため、日付を含めるにはもっと柔軟性が必要です。

4

3 に答える 3

5

各ユーザーが独自のデータを所有している場合(つまり、季節を指定してから独自の情報を入力する場合)、季節をその一部としてデータを保存するだけで済みますが、あなたが求めているシナリオは共有データ用であると感じています季節を異なって定義する多数のユーザー間で。

うるう年は予期しない問題を引き起こす可能性があるため、日付の「正規化」には細心の注意を払う必要があります。つまり、2 月 29 日をうるう年以外に設定しようとすると、問題や例外が発生します。

以下をまとめましたが、残念ながらそのc#ですが、コンセプトは同じです。私は実際にコードをテストしたことはありませんが、疑似コードとしても役立つかもしれません。

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;
        }

    }
}

上記のコードは、シーズンが同じ月に開始および終了しないことを前提としていることに注意してください。これはかなり安全だと思います!

于 2009-03-02T02:36:20.113 に答える
2

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

すべての「シーズン中の場合」タイプのチェックは事前に構築されており、シーズンの計算コストを実行時間ではなくセットアップ時間に押し込みます。

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

于 2009-03-02T03:07:31.833 に答える
2

独自の DateRange クラスをロールバックする必要があると思いますが、これは非常に一般的な問題であり、それを行う賢いユーティリティが既に存在することを願っています。季節を扱うときの一般的なポイントとして、地理も考慮に入れる必要があります。オズではアメリカとは逆なので、夏は 11 月から 2 月まで続きます。

于 2009-03-02T02:27:24.127 に答える