How to handle dates that repeat indefinitely - php

I am implementing a fairly simple calendar on a website using PHP and MySQL. I want to be able to handle dates that repeat indefinitely and am not sure of the best way to do it.
For a time limited repeating event it seems to make sense to just add each event within the timeframe into my db table and group them with some form of recursion id.
But when there is no limit to how often the event repeats, is it better to
a) put records in the db for a specific time frame (eg the next 2 years) and then periodically check and add new records as time goes by - The problem with this is that if someone is looking 3 years ahead, the event won't show up
b) not actually have records for each event but instead when i check in my php code for events within a specified time period, calculate wether a repeated event will occur within this time period - The problem with this is that it means there isn't a specific record for each event which i can see being a pain when i then want to associate other info (attendance etc) with that event. It also seems like it might be a bit slow
Has anyone tried either of these methods? If so how did it work out? Or is there some other ingenious crafty method i'm missing?

I'd take approach b and if someone adds something to it, I'd create a "real" event entry.
Edit:
How many periodic events do you expect and what kind of periodic events would that be? (eg: every monday, every two weeks etc.)

I would create a single record for a repeated event. Then in case more info has to be added to a specific date, I would create a record for the attachment with a reference to the repeated event.

Third vote for option B - rationale being that the data should only ever be queried for a limited timeframe (i.e. start and end). For performance reasons I'd suggest that, in addition to storing the date/time of the first occurrence, number of occurrences and frequency that you also maintain the last occurrence in the database.
C.

From my experience, generating recurring dates and checking if a specific date is in that pattern isn't all that bad performance-wise. There's only 365 days in a year. 10,000 days is already almost 30 years. which means, the size of the input/output is relatively small in a practical scenario.
This library may help (but it's javascript): http://github.com/mooman/recurring_dates

Related

Writing for holes in ranges

I'm trying to write a program that relies on date ranges. I am trying to be able to alert users when there are holes in their ranges but I need a reliable way to find those, and to be able to handle them effectively.
My solution was to change any dates so that any day inserted into the app is rewritten so it is that day at noon. Here is the code for that:
public function reformDate($date){
return strtotime(date("F j, Y", $date)." 12:00pm");
}
This would allow me to deal with a more regular and consistent dataset. Because I only had to see how many days they were apart, rather than seeing how many seconds they were apart and making a decision whether that time quantity represented an intentional gap or not...
I saw, however, when you put something in for today at noon, then if you put something tomorrow at noon, since the values are the same, and based on my restriction:
Select * from times where :date between start and end
It triggers a response. My solution for this was to just add one to the start variable, and detract one from the end variable, so I can easily check if there are overlap by asking if the difference between the start of one and end of another is more than 2.
Anyway, my question is: is this a good way to do this? I'm particularly worried about the number 2 - do I need to worry about using such small units of time (that is unix time, by the way). Alternately, should I create a test that if two time units overlap perfectly - they should be accepted?

Start a php code (competition in which some users are) for users, logged in or not

Ok I know the title doesn't really tell you what my problem is but I'll try it now.
I am developing a game. People can subscribe their animals for a race. That race starts at a specific time. It is a race for which ALL users can subscribe. So the calculation of which animal is first, second etc. happens in an php file that is executed, every 2mins there is a new calculation for about 1h. So there are 30 calculations. But ofc. this code is not connected to the logged in user. The logged in user can click on the LIVE button to see the current result.
Example: There is a race at 17.00 later today. 15 animals subscribed, from 4 players and they can all check how their animals are doing.
I do not want someone to post me the full code but I want to know how I should let a php code run for about 1 hour (so execute code, sleep 2min, new calculation, sleep 2min and so on) on my server or so. So it is not connected to the user.
I thought about cron jobs but that is really not the solution for this I believe.
Thank you for reading :p
Two approaches:
You use an algorithm which will always come to the same conclusion, regardless of when it is run and who runs it. You just define the starting parameters, then at any time you can calculate the result (or the intermediate result at any point in time between start and finish) when needed. So any user can at any time visit your site and the algorithm will calculate the current standings on the fly from some fixed starting condition.
Alternatively, you keep all data in a central data store and actually update the data in certain intervals; any user can request the current standings at any time and the latest data from the datastore will be used. You will still need an algorithm that has traits of the one described above, since you're likely explicitly not actually running the simulation in real time. Just every x seconds, you run your calculations again, calculating what is supposed to have changed from the last time you ran them.
In essence, any algorithm you use needs this approach. Even a "realtime" program simply keeps looping, changing values little by little from their previous state. The interval between theses changes can be arbitrarily stretched out, to the point where you calculate nothing until it becomes necessary. In the meantime, you just store all the data you need in a database.
Cron jobs are the wright way i think. Check this out when you are not so good with algorithm:How To: PHP with Cron job Maybe you have to use different cron jobs.

PHP + MySQL + Repeating Calendar Events

I know this has been a question asked many times and I wish there was some solid answers out there, so i'm going to try and ask it and see if we can get a different response.
I realize there are tons of complexity's in dealing with recurring events. But is my understanding right if I were to do something like of this nature:
MySQL column (RRULE)
When a user enters in an event ant says, "This repeats", now enter in this RRULE information Such as, (ie: FREQ=YEARLY;BYMONTH=3;BYDAY=2SU )
So use this method instead of INSERTING hundreds of events of the same thing, just create 1 table to store my repeating events and then add this RRULE column for the event, correct?
Question 2. How do you determine the maximum length of an event if stated, "Repeat this forever" (ie: a birthday).
Question 3. Is there a better way to do this, than what I am thinking?
If you could shed some light on what I am questioning, that would be greatly appreciated. I would like to write a class that handles all the information based on this setup but would like to know if I am on the right track or not.
Please and thank you!
Yes, just enter it once. Calculate the first day for it to run, based off user input (what did they choose? yearly, monthly, etc) when you insert it, and put that in as the next run date. Also store their type choice. Then when you run the task at the specified time, you update the next run date/time based off the stored type choice. In addition you may want another field that indicates how many times to repeat; forever, 4 times etc. Decrement this accordingly when running the task.

Best way to develop/manage/design recurring tasks/calendar

An example of what I'm talking about is similar to Google Calendar. When a new recurring task is created.
After creating the recurring task "template" - which all of the individual tasks are based on, do you create all of the individual tasks and store them in the database? or do you just store the "template" recurring events and their exceptions?
If the user requests a "month" view, and you want to display all of the events/tasks, it seems like creating the output in real time from the template, and including all of the exceptions would be a lot more resource intensive then if each individual recurring tasks was created from the template and inserted into the database.
This would make searching/sorting, etc, a lot more easier too.
Anybody create something like this before? ideas?
Store it all in the database.
You want to have a "Task Template" table and a "Task" table where there is a one->many relationship.
When the user indicates they want a task to reoccur, create a "Task Template" record and then create as many "Tasks" as the user has indicated (don't allow a user to create tasks too far into the future). Each Task is linked to the Task Template via a Foreign Key. The idea is that SQL is going to be more efficient at managing these records than trying to do this all in code based on one template. This way, you will have more option when your sorting and filtering your data. After all, writing a SQL query is easier than writing, testing, and maintaining a PHP function that manipulates the data.
Some other tips I would give you is:
Try to get a lot of information in your "Task Template" record. Keep the number of tasks the Template covers, the date the last task ends, the time elapsed between the first task and the last, etc.. This "Meta Data" can help save you query time when you're looking to sort and filter tasks.
Put an index on the Date and FK field, this will help query time as well.
I just built two calendar apps at work that were pretty well received by the bosses. I used the "FullCalendar" JQuery plugin (http://arshaw.com/fullcalendar/). I used JQuery AJAX to handle most of my events, and it had built in support for Month, Day, and Week view.
For recurring events I did the following a while back:
When a user entered an event I stored the event's date pattern GNU date style - the keyword for PHP is relative date formats.
Then I started off by creating events for e.g. the next year. And created actual records where I converted the relative date to an actual -- e.g. "every first Monday" to a "mm-dd-YYYY". This allowed me to display them and also allow the user to e.g. move a single event or cancel one, etc..
Then figure out how far to go into the future - my idea was to create events when the actual pages were browsed. E.g. if I had created events through June 2011 and someone skipped all the way to July 2011, I would iterate on my events and set them up transparently.
When the user changes the relative pattern, offer to update all following events -- unless they have a custom pattern already. Relative patterns make it super easy to calculate all that.
I went through the same problem a while back and instead of reinventing the wheel, I used Google Calendar APIs. (http://code.google.com/apis/calendar/data/2.0/developers_guide.html)
You create a Google Account and access the calendar information. There are APIs to create/edit/delete a recurring entry. Also, you can specify a date/time information and query for matching events.
When you create an event on Google Calendar, you will receive a token/id which you can store in your own database and reference it within the context of the application.
If the user requests a "month" view, and you want to display all of the events/tasks, it seems like creating the output in real time from the template, and including all of the exceptions would be a lot more resource intensive then if each individual recurring tasks was created from the template and inserted into the database.
I would disagree on that. What if a task repeats every saturday for the next 7 years... And what if there were a lot of these repeating tasks? That would cost you a lot of waste space. Therefor, I think it's better to save a recurring task as just one record + one record for every exception (since there are less exceptions than recurrences).
Well, the only problem left is how to set up a query to select each task (still thinking abou that)

user generated / user specific functions

I'm looking for the most elegant and secure method to do the following.
I have a calendar, and groups of users.
Users can add events to specific days on the calendar, and specify how long each event lasts for.
I've had a few requests from users to add the ability for them to define that events of a specific length include a break, of a certain amount of time, or require that a specific amount of time be left between events.
For example, if event is >2 hours, include a 20min break. for each event, require 30 minutes before start of next event.
The same group that has asked for an event of >2 hours to include a 20 min break, could also require that an event >3 hours include a 30 minute break.
In the end, what the users are trying to get is an elapsed time excluding breaks calculated for them. Currently I provide them a total elapsed time, but they are looking for a running time.
However, each of these requests is different for each group. Where one group may want a 30 minute break during a 2 hour event, and another may want only 10 minutes for each 3 hour event.
I was kinda thinking I could write the functions into a php file per group, and then include that file and do the calculations via php and then return a calculated total to the user, but something about that doesn't sit right with me.
Another option is to output the groups functions to javascript, and have it run client-side, as I'm already returning the duration of the event, but where the user is part of more than one group with different rules, this seems like it could get rather messy.
I currently store the start and end time in the database, but no 'durations', and I don't think I should be storing the calculated totals in the db, because if a group decides to change their calculations, I'd need to change it throughout the db.
Is there a better way of doing this?
I would just store the variables in mysql, but I don't see how I can then say to mysql to calculate based on those variables.
I'm REALLY lost here. Any suggestions? I'm hoping somebody has done something similar and can provide some insight into the best direction.
If it helps, my table contains
eventid, user, group, startDate, startTime, endDate, endTime, type
The json for the event which I return to the user is
{"eventid":"'.$eventId.'", "user":"'.$userId.'","group":"'.$groupId.'","type":"'.$type.'","startDate":".$startDate.'","startTime":"'.$startTime.'","endDate":"'.$endDate.'","endTime":"'.$endTime.'","durationLength":"'.$duration.'", "durationHrs":"'.$durationHrs.'"}
where for example, duration length is 2.5 and duration hours is 2:30.
Store only the start time and end time for the event, and a BLOB field named notes.
I've worked on several systems that suffered from feature creep of these sorts of requirements until the code and data modeling became nothing but an unmaintainable collection of exception cases. It was a lot of work to add new permutations to the code, and typically these cases were used only once.
If you need enforcement of the rules and conditions described in the notes field, it's actually more cost-effective to hire an event coordinator instead of trying to automate everything in software. A detail-oriented human can adapt to the exception cases much more rapidly than you can adapt the code to handle them.

Categories