Domanda

Devo modellare alcune informazioni sulle stagioni e devo tracciarle in base alla data di inizio / fine in modo annuale. Cioè Devo consentire agli utenti di definire l'estate come tra, diciamo, 15 maggio e 10 settembre, e farlo per tutti gli anni.

Dovrò fare molti controlli del tipo isThisDateInSeason). Tutte le funzioni di manipolazione della data (ad es. Data, Calendario) sembrano funzionare solo con date valide, ad esempio includendo le informazioni sull'anno.

Esistono delle migliori pratiche su come farlo? Mi viene in mente un sacco di modi bizzarri di farlo (cioè memorizzare mese e giorno del mese o memorizzare le date e portarle solo a un anno di riferimento in modo che io possa confrontare), ma sembra che ci potrebbe essere un modo migliore .

Sto scrivendo questo in Java o Groovy.

La Joda-Time aiuterebbe qui? Non ho esperienza con esso, ma sembra avere molta più flessibilità.

Ho trovato questa domanda su come identificare un stagione da data, ma che si concentra su mesi e ho bisogno di maggiore flessibilità per includere le date.

È stato utile?

Soluzione

Se ogni utente possiede i propri dati (ovvero specifica le proprie stagioni e quindi inserisce le proprie informazioni), puoi semplicemente archiviare i dati con la stagione come parte di essi, tuttavia ho la sensazione che lo scenario che stai cercando sia per dati condivisi tra numerosi utenti che definiscono le stagioni in modo diverso.

Dovresti stare molto attento a "normalizzare" le date poiché l'anno bisestile può causare problemi imprevisti, vale a dire provare a impostare il 29 febbraio in un anno non bisestile causerà problemi / eccezioni.

Ho messo insieme il seguito, senza dubbio il suo c # ma il concetto sarà lo stesso. In realtà non ho testato il codice, ma anche come codice psudo può essere d'aiuto.

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

    }
}

Nota che il codice sopra riportato presuppone che la stagione non inizi e finisca nello stesso mese - penso che sia abbastanza sicura!

Altri suggerimenti

Penso che dovrai lanciare la tua classe DateRange, anche se questo è un problema così comune che speri che ci sia già un util software là fuori che lo fa. Come punto generale quando si affrontano le stagioni bisogna anche tener conto della geografia, che renderà la vita davvero dura. A Oz siamo il contrario degli Stati Uniti, quindi l'estate va da novembre a febbraio.

Dove sono i dati? Se si trova in un database, prenderei in considerazione la possibilità di creare una tabella per le date (come una dimensione temporale in OLAP). È quindi possibile calcolare una colonna per le stagioni come per i quartieri finanziari in alcuni esempi di dimensione temporale. (questo presuppone che la tua stagione non cambi ma abbia date fisse).

Tutti i " se la data nella stagione " il controllo del tipo sarà pre-costruito spingendo i costi del calcolo della stagione nel tempo di installazione piuttosto che nel tempo di esecuzione.

Modifica: Ho appena visto il tuo commento sulle date di stagione configurabili dall'utente. Funzionerebbe comunque, dato che è possibile eseguire un join in un database, inclusa la dimensione temporale, che potrebbe essere più semplice lavorare con l'insieme di dati rispetto a Java.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top