c# - Manejando correctamente los horarios de apertura con NodaTime.
.net datetime (1)
Actualmente estoy escribiendo una aplicación bastante simple que maneja los horarios de apertura / cierre de las empresas y se encuentra con serias dificultades para descubrir cómo almacenar adecuadamente la información.
¡La mayor parte de nuestra funcionalidad crítica depende en gran medida de que los tiempos sean absolutamente perfectos, por lo que obviamente quiero que las cosas se hagan de la mejor manera posible para comenzar!
Además, los usuarios ingresarán los datos, por lo que si la representación subyacente es un poco más compleja (por ejemplo, utilizando TimeSpans para tener en cuenta la apertura después de la medianoche), esto debe ser invisible para el usuario.
En primer lugar, debo almacenar los horarios de apertura del negocio, por día de la semana, con una zona horaria asociada a ellos, por ejemplo:
- M: 1000 - 2330
- T: 1000 - 0030
- W: 1900 - 0300
- Th: 2000 - 0300
- F: 2000 - 0800
- Sa: 1000 - 0500
- Su: 1000 - 2300
Actualmente estoy pensando que la mejor manera de almacenar esto es usar una clase como esta:
public class OpeningHours
{
ZonedDateTime OpeningTime { get; set; }
Period durationOpen { get; set; }
// TODO: add a method to calculate ClosingTime as a ZonedDateTime
}
Sin embargo, hay 2 complicaciones principales aquí:
No quiero almacenar la parte del año, mes o fecha de ZonedDateTime, solo me importa el DayOfWeek.
Claro, podría simplemente almacenar cada valor como el primer lunes / martes, etc., después del 1 de enero de 1970, pero esto parece bastante extraño, y como el autor de NodaTime, muy correctamente, explica here cuando se habla de las limitaciones del BCL DateTime. implementación. También tengo la sensación de que esto probablemente terminaría con bichos extraños y extraños si más adelante intentamos hacer cualquier cálculo con las fechas.
- El usuario tendrá que ingresar el ClosingTime de todos modos. Lado del cliente Supongo que podría hacer algo simple, como suponer siempre que ClosingTime es el día siguiente si es antes de Opening Time, pero nuevamente, no es perfecto y tampoco tiene en cuenta los lugares que podrían estar abiertos durante más de 24 horas (por ejemplo, supermercados)
Otra cosa que he considerado es usar una tabla con horas / días y dejar que las personas resalten las horas de la semana para elegir los horarios de apertura, pero todavía tiene el mismo problema con solo querer almacenar la parte DayOfWeek de OpeningTime.
¡Cualquier sugerencia sería apreciada, dedicando las últimas 6 horas a leer sobre las maneras tan divertidas que los humanos representan que el tiempo me ha agotado un poco!
Yo consideraría fuertemente usar LocalTime
lugar de ZonedDateTime
, por un par de razones:
- No estás tratando de representar un solo instante en el tiempo; estos son patrones naturalmente recurrentes (no hay fecha asociada)
- No está tratando de hacer frente a la situación en la que la tienda se encuentra en diferentes zonas horarias para diferentes horarios de apertura; Probablemente desee asociar una zona horaria a cada tienda una vez , y luego puede aplicar esa zona horaria cuando lo desee.
Por lo tanto, tendría algo como esto (mostrando solo los miembros de los datos; cómo se resuelve el comportamiento es un asunto aparte):
public class StoreOpeningPeriod
{
IsoDayOfWeek openingDayOfWeek;
LocalTime openingTime;
LocalTime closingTime;
}
Tenga en cuenta que esto sigue exactamente sus datos originales tal como lo ha mostrado, lo que siempre es una buena señal: no está agregando ni perdiendo información, y probablemente se encuentre en una forma conveniente.
Si la hora de cierre es anterior a la hora de apertura, se supone que esta medianoche cruzada; es posible que desee agregar un cuadro de confirmación para el usuario si esto es relativamente poco frecuente, pero sin duda es fácil de identificar y manejar en el código.