2009-01-09 4 views
6

Necesito almacenar si algo sucede una vez, todos los días, días de la semana, semanalmente, algunos días de la semana, algunos días del mes, que pueden ser numéricos o simbólicos, como el primer lunes de cada mes, y así sucesivamente.¿Cómo almacenaría los tiempos posibles recurrentes?

¿Alguna recomendación? ¿Algún código, estructura de datos o esquema a mirar?

Respuesta

1

Esto suena como un "evento recurrente", como en Outlook. Yo usaría una tabla llamada RecurrenceType para almacenar cada período de tiempo (diario, semanal, etc.) Otra tabla llamada Event woud se referirá por clave a RecurrenceType. Las fechas futuras para la mayoría de los tipos de recurrencia se pueden calcular utilizando funciones de fecha estándar.

8

Existen soluciones complejas y soluciones fáciles. Las dos soluciones más sencillas son:

  1. Ventilador cabo eventos periódicos hasta un número constante de los casos, o hasta cierto intervalo de tiempo fijo en el futuro. Almacene un F Recurrence_id con cada instancia que apunte a una descripción de la recurrencia, y permita la edición masiva y la cancelación.

    La ventaja del enfoque de salida de ventilador precalculado es que es muy fácil implementar excepciones de recurrencia, que seguramente será la primera solicitud de función que obtenga.

  2. Calcular en tiempo de visualización. Las computadoras son rápidas, dependiendo de las preguntas que desee que puedan responder acerca de sus datos, a menudo será trivialmente fácil calcular todas las ocurrencias en un rango de fechas. Puede ser inteligente y tratar de delimitar rápidamente su rango de fechas antes de realizar el cálculo de recurrencia, o puede forzarlo desde la fecha de inicio.

Más allá de que sólo tiene una solución para almacenar la regla de repetición que trabaja con lo que usted está utilizando para el cálculo de las recurrencias. (por ejemplo, si está utilizando una biblioteca de habilitación de iCalendar, su esquema es varchar (255) con valores RRULE)

Si tiene que rodar su propia calculadora de recurrencia, y desea mantenerla simple, limitando sus recurrencias a diario, semanal, mensual o anual cubre su primer caso de uso del 80% y es trivialmente fácil de calcificar.

Momento en el que el esquema de potencial de recurrencia se ve algo como:

id 
recurrence_start 
recurrence_end 
type (daily|weekly|monthly|yearly) 
day_of_week (for weekly) 
month 
day_of_month 

Y francamente las soluciones complejas probablemente no valen la pena :)

+0

Hola kellan, ¿cómo implementarías el rango de un evento (fechas de inicio y finalización) al usar el esquema de recurrencia que proporcionaste? ¿Algunas ideas? Estoy teniendo un montón de problemas para diseñar algo como esto. ¡Gracias! – Tom

1

El problema es que hay infinitas posibilidades para la especificación de tales un intervalo. Por ejemplo, "El primer lunes de cada dos meses si la fecha es par, pero no 4, y el mes no es febrero de un año largo". ¿Qué tan lejos estás dispuesto a ir? Eventualmente, solo tendrá que hacer que los usuarios escriban en una expresión booleana que se evalúa como VERDADERO en los días en que se repetirá el evento. No es muy agradable desde la perspectiva de la interfaz de usuario.

Debe decidir algunas limitaciones para su sistema. Una vez que los conozca, el resto debería ser fácil, o al menos responder en SO. :)

3

Martin Fowler escribió a really great paper acerca de esto. Puede encontrar muchas de las mismas ideas que discute en runt, una biblioteca de Ruby para tratar con expresiones temporales.

+1

El documento de Fowler es claro y legible, pero no trata las excepciones a la regla, que IMO es uno de los problemas candentes con este patrón de diseño ... –

0

Es mencionado en a related, useful SO thread, pero una buena alternativa, mantenido de forma activa a Runt si sucede utilizar Ruby es ice_cube. No ha mencionado cuáles son sus requisitos de back-end de almacenamiento, pero para el esquema de la base de datos, @ kellan y algunos en el hilo antes mencionado son buenos comienzos.

Cuestiones relacionadas