簡體   English   中英

忽略日期范圍的年份的最佳做法

[英]Best practice for ignoring year in date for date ranges

我需要建模一些關於季節的信息,並且需要以一年不可知的方式基於開始/結束日期跟蹤它們。 即我需要允許用戶將夏季定義為介於5月15日和9月10日之間,並且這些年份都是如此。

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

有沒有關於如何做到這一點的最佳實踐? 我可以想到一堆hacky方法(即存儲月份或日期或存儲日期,只需將它們帶到基准年,這樣我就可以比較),但似乎可能有更好的方法。

我用Java或Groovy編寫這個。

Joda-Time圖書館會幫忙嗎? 我沒有它的經驗,但它看起來有更多的靈活性。

我發現了一個關於如何確定一個季節的問題 ,但這個問題主要關注幾個月,我需要更多的靈活性來包含日期。

如果每個用戶擁有自己的數據(即他們指定他們的季節,然后他們輸入他們自己的信息),那么你可以將季節中的數據作為其中的一部分存儲,但是我感覺你所追求的場景是用於共享數據眾多用戶之間的定義不同。

你必須非常謹慎地“標准化”日期,因為閏年​​可能會導致意外問題,即嘗試在非閏年設置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;
        }

    }
}

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

我認為你必須推出自己的DateRange類,雖然這是一個常見的問題,你希望已經有一個聰明的實用程序可以實現它。 作為處理季節的一般要點,你還必須考慮到地理,這將使生活變得非常困難。 在奧茲國,我們與美國相反,因此夏季從11月到2月。

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

所有“if date in season”類型檢查都是預先構建的,將計算季節的成本計入您的設置時間而不是運行時間。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM