Question

Je dois modéliser certaines informations sur les saisons et les suivre en fonction de la date de début / fin de manière indépendante de l'année. C'est à dire. Je dois permettre aux utilisateurs de définir l'été comme étant compris entre le 15 mai et le 10 septembre, par exemple, et ce, pour toutes les années.

Je devrai faire beaucoup de vérifications du type isThisDateInSeason). Toutes les fonctions de manipulation de date (date, calendrier, etc.) ne semblent fonctionner qu’avec des dates valides, c’est-à-dire des informations sur l’année.

Existe-t-il des meilleures pratiques concernant la procédure à suivre? Je peux penser à un tas de façons de le faire (stocker le mois et le jour du mois ou stocker les dates et les ramener simplement à une année de référence afin que je puisse comparer), mais il semble qu'il existe peut-être un meilleur moyen .

J'écris ceci en Java ou Groovy.

La bibliothèque Joda-Time serait-elle utile ici? Je n’ai pas d’expérience, mais il me semble que nous aurons beaucoup plus de flexibilité.

J'ai trouvé cette question sur la façon d'identifier un saison à partir de la date, mais cela se concentre sur les mois, et j'ai besoin de plus de flexibilité pour inclure les dates.

Était-ce utile?

La solution

Si chaque utilisateur possède ses propres données (c.-à-d. qu'il spécifie ses saisons et qu'il entre ensuite ses propres informations), vous pouvez simplement stocker les données avec la saison dans le cadre de celle-ci. Cependant, j'ai le sentiment que le scénario que vous recherchez est pour les données partagées sur de nombreux utilisateurs qui définissent les saisons différemment.

Vous devez faire très attention à "normaliser" les dates car l'année bissextile peut causer des problèmes inattendus, c'est-à-dire qu'essayer de régler le 29 février sur une année non bissextile causera des problèmes / exceptions.

J'ai mis le texte ci-dessous ensemble, toujours son c #, mais le concept sera le même. Je n'ai pas testé le code, mais en tant que code psudo, cela peut aider.

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

    }
}

Notez que le code ci-dessus suppose que la saison ne débutera ni ne se termine le même mois - une période relativement sûre, je pense!

Autres conseils

Je pense que vous devrez lancer votre propre classe DateRange, bien que ce soit un problème si commun que vous espériez qu'il existe déjà une fonction intelligente qui le fait. En règle générale, lorsque vous faites face aux saisons, vous devez également tenir compte de la géographie, ce qui rendra la vie vraiment difficile. En Oz, nous sommes à l’inverse des États-Unis, donc l’été s'étend de novembre à février.

Où sont les données? Si c'est dans une base de données, j'aimerais envisager de créer un tableau pour les dates (comme une dimension de temps dans OLAP). Vous pouvez ensuite calculer une colonne pour vos saisons, comme pour les trimestres financiers, dans certains exemples de dimension temporelle. (cela suppose que votre saison ne change pas mais a des dates fixes).

Tous les "si date en saison" La vérification de type sera prédéfinie, ce qui inclura les coûts de calcul de la saison dans votre temps d'installation plutôt que dans votre temps d'exécution.

Modifier: votre commentaire sur les dates de saison configurables par l'utilisateur. Cela fonctionnerait quand même, car vous pouvez créer une jointure dans une base de données, y compris la dimension temporelle, ce qui faciliterait l'utilisation de l'ensemble de données en Java.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top