Pregunta

Necesito modelar cierta información sobre las temporadas, y debo rastrearlas en función de la fecha de inicio / finalización de una manera independiente al año. Es decir. Necesito permitir que los usuarios definan el verano como, por ejemplo, entre el 15 de mayo y el 10 de septiembre, y hacerlo durante todos los años.

Tendré que hacer una gran cantidad de comprobación del tipo isThisDateInSeason). Todas las funciones de manipulación de fechas (es decir, fecha, calendario) parecen funcionar solo con fechas válidas, es decir, con información sobre el año.

¿Existen prácticas recomendadas sobre cómo hacer esto? Se me ocurren varias maneras de hacerlo (p. Ej., Mes de la tienda y día del mes o para almacenar las fechas y llevarlas a un año base para poder compararlas), pero parece que podría haber una mejor manera. .

Estoy escribiendo esto en Java o Groovy.

¿Ayudaría aquí la biblioteca Joda-Time ? No tengo experiencia con eso, pero parece tener mucha más flexibilidad.

Encontré esta pregunta sobre cómo identificar un temporada a partir de la fecha, pero eso se enfoca en meses, y necesito más flexibilidad para incluir fechas.

¿Fue útil?

Solución

Si cada usuario posee sus propios datos (es decir, especifican sus temporadas y luego ingresan su propia información), entonces usted podría almacenar los datos con la temporada como parte de ella, sin embargo, tengo la sensación de que el escenario que está buscando es para datos compartidos a través de numerosos usuarios que definen las estaciones de manera diferente.

Tendría que tener mucho cuidado de "normalizar" las fechas, ya que el año bisiesto puede causar problemas inesperados, es decir, tratar de establecer el 29 de febrero en un año bisiesto causará problemas / excepciones.

He reunido lo siguiente, de manera imprevista su c #, pero el concepto será el mismo. Realmente no he probado el código, pero como un código de psudo puede ayudar.

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

    }
}

Tenga en cuenta que el código anterior presupone que la temporada no comenzará ni terminará el mismo mes, ¡creo que es bastante seguro!

Otros consejos

Creo que tendrás que lanzar tu propia clase de DateRange, aunque este es un problema tan común que desearías que ya exista una herramienta inteligente que lo haga. Como punto general cuando se trata de estaciones, también hay que tener en cuenta la geografía, lo que hará la vida realmente difícil. En Oz somos lo contrario de los Estados Unidos, por lo que el verano se extiende de noviembre a febrero.

¿Dónde están los datos? Si está en una base de datos, consideraría hacer una tabla para las fechas (como una dimensión de tiempo en OLAP). Luego puede calcular una columna para sus temporadas tal como son para los trimestres financieros en algunos ejemplos de Dimensión temporal. (esto se supone que su temporada no cambia pero tiene fechas fijas).

Todas las " si la fecha en la temporada " la comprobación de tipos se creará previamente e impulsará los costos de calcular la temporada en su tiempo de configuración en lugar de su tiempo de ejecución.

Editar: Acabo de ver tu comentario sobre las fechas de temporada configurables por el usuario. Esto seguiría funcionando, ya que puede unirse en una base de datos, incluida la dimensión de tiempo, lo que podría ser más fácil trabajar con el conjunto de datos que en Java.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top