问题
I'm building a tv series scheduling app in Ruby on Rails which performs certain actions based on what's currently on tv. Users can create a series, which has a start and end date, and can create broadcasts for those series. Broadcasts can be on one of three channels, and are in the form of "every Tuesday, on channel 2, from 10:00:00 until 14:00:00".
Currently, I'm storing these broadcasts in MySQL with the following columns: a wday
integer, a starts_at
and ends_at
time field, and a channel_id
integer. So the aforementioned broadcast would be stored with wday
2, channel_id
2, starts_at
"10:00:00" and ends_at
"14:00:00", and a reference to the event it belongs to. Broadcasts can "cross" midnight, so the app should allow broadcasts with start "23:00:00" and end "02:00:00", being 2 in the morning the next day.
I'm having some serious trouble with the following two issues:
Only one broadcast can be scheduled on a specific time on a specific channel. The app needs to validate user input, and check whether a broadcast exists for the specific channel and times.
The app needs to show the currently shown broadcast, if any, for each of the three channels. Basically, for each channel, find a broadcast with starts_at < current time < ends_at. Obviously, this needs to work with broadcasts crossing midnight as well.
I'm not sure at all whether using time fields for start/end times is the best solution. Bear in mind, I need to store time values, not dates, since a broadcast can occur every Tuesday for the duration of the series.
How would you store these broadcasts, allowing validation and allowing querying around a specific time, allowing broadcasts to "cross" midnight?
回答1:
This kind of problem is such a minefield of edge cases that I would always delegate the logic to something like IceCube (https://github.com/seejohnrun/ice_cube). It is made to deal with these kinds of recurring schedules, and comes with easy support for serialization etc. Even if it requires a little rethinking of how you do things, I would strongly recommend using it.
回答2:
Fair enough - you should then just store the start/end time as seconds after midnight on Monday (or whenever). You can then have accessors/settors to convert data into and out of a human-parseable format. Finding the currently shown program becomes as easy as:
time_now = 18494
Program.where 'start_time >= ? AND end_time < ?', time_now, time_now
Validating is similarly simple.
回答3:
What about using Unix / epoch timestamps, and creating some business logic to convert that into a pretty date once all checks and calculations are done (should be available out of the box somewhere)? That way it seems you'll avoid a lot of midnight and other date related problems...
来源:https://stackoverflow.com/questions/16853284/scheduling-events-and-having-events-cross-midnight