iCal backend - recurring dates - php

I am building a calendaring system using FullCalendar as the front end. The backend will be MySQL/PHP.
It will store a list of public appointments for users which are generated and inserted by the application. These appointments will be a single event which will start and finish on the same day. In addition users will be able to mark their unavailablity in the calendar due to personal commitments. This latter functionality requires the use of recurring events. Rather than re-invent the wheel I have been looking at using a structure based on iCal. This post was very helpful ical-field-list-for-database-schema-based-on-ical-standard in determining the database structure.
I have created the application form which allows the user to enter the necessary data in order to store a private single/recurring appointment. Upon submission of the form, the data is sent via Ajax to the server. I have found a great PHP script which generates an array of the recurring dates based on the parameters entered by the user, either in their native format or using RRULE.
I am unsure what is the best way to store/retrieve these recurring dates. The application needs to be able to render a calendar view for the user including the public and private dates. The application will also need to be able to return for example all users who may be free for a given time/date period.
Is it sufficient to store all events in the iCal format, and be able to retrieve events upon demand? The problem that I foresee is that repeating events are not easily searchable as their parameters would have to be expanded on the fly? I was considering creating a second table of every individual event (as generated ) with a reference back to the original RRULE that created it. I would look to limit the number of recurring dates that users may enter in order to prevent users from entering an event every day for the next 100 years! I think that this approach would also me to edit individual events which were originally created by a recurring rule.
Is this a good approach, or is there a better way?

Have a look at when building a calendar app, should i store dates or recurrence rules in my database?.
You should store the rrule, exrule, rdate and exdate associated with validity information (to be able to track changes over time : like if your users might want to look back in the past when they had a specific event happen and if the rrule changed between the occurence and the point of time when he/she looks back),
For events which have finite number of occurences do a pre-computation of start and end for a time window for easier queries and have a rolling window for which you have the occurences of all events in a table. When users look for occurences out of the time window (should be rare to have people looking more than one year back or more than one year in future) you compute relevant events specific for the time window the users is requesting and generate them on the fly.

How about a table along the following lines:
CREATE TABLE RecurringAppointments (
startdate DATE NOT NULL,
enddate DATE,
freq INT NOT NULL, -- contains #days between each occurrence
-- etc.
)
Then, to fetch all such appointments that occur on a given thedate:
SELECT * FROM RecurringAppointments
WHERE
thedate BETWEEN startdate AND enddate
AND DATEDIFF(thedate, startdate) % freq = 0;

Related

Mysql (+php) Right approach to store, retrieve and show date ranges

I'm working on a calendar application where you can set events which can last multiple days. On a given date there can be multiple events, already started or starting that day. The user will view everything as a calendar.
Now, my question is: which of the following is the right approach? Is there an even better approach?
1) use 2 tables, events and events_days and store the days of every event in the event_days table
2) use just one table with the events stored with a date_from field and a date_to field and generate every time with mysql and php a list of days for the desired range with the events
Obviously the first option will require much more db storage, while the second one will require a bigger work from the server to generate the list (every single time the user asks for it).
The db storage shouldn't be a problem for now, but i don't know if will be the same in the future. And i fear the second option will need too many resources.
I have used both approaches. Here is a list of pros and cons that I have noticed:
Two tables: events(id) and events_dates(eventid, date)
Pros:
Query to check if there are events on a given date or between given dates is trivial:
SELECT eventid FROM events_dates WHERE date BETWEEN '2015-01-01' AND '2015-01-10'
Query to select the list of dates for an event is trivial
SELECT date FROM events_dates WHERE eventid = 1
Cons:
While selecting the list of dates is trivial, inserting the list of dates for an event requires scripting (or a table-of-dates)
Additional measures required to make sure data remains consistent, for example, when inserting an event spanning three days you need four insert queries
This structure not suitable in situations where time is involved, for example, meetings schedule
One table: events(id, start, end)
Cons:
Query to check if there is are events on a given date or between given dates is tricky.
Query to select the list of dates for an event is tricky.
Pros:
Inserting an event is trivial
This structure suitable in situations where time is involved

MySQL - Single DATETIME or Separate DATE and TIME Columns?

In my application I'm developing a functionality for creating "reminders".
A reminder has a date and a time. In my application, I have a form to create / edit reminders - this has two separate fields to input this information:
<input type="text" name="date"></input> <!-- datepicker plugin -->
<input type="text" name="time"></input> <!-- timepicker plugin -->
Now as a rule I have always used a DATETIME column whenever I have needed to store date/time, however this is the first time I'm having to store a user inputted date/time.
I figured it would be best to have seperate DATE and TIME columns, because it would be easier to insert / retrieve the data to / from my application. For example I won't have to combine the values from the two input fields to create a single value to insert in to the database. And likewise I won't have to split a single value in to two values to populate the form fields in edit mode.
But on the other hand won't it be easier to query the table if I used one column? What do you think?
You should build bottom-up (database at the bottom). Don't think about the application, just the database. Now, what makes sense at the database level. DateTime.
So you need to write extra code at the application level.
Please see it
Adding a Timepicker to jQuery UI Datepicker
http://trentrichardson.com/examples/timepicker/
convert your date time according to your mysql format and store it
$mydate = strtotime($_POST['date']);
$myfinaldate = date("d-m-y", $mydate);
$mytime = strtotime($_POST['time']);
$myfinaltime = date("H:i:s", $mytime);
Seperating columns is unlogical. You can use timestamp as datatype and you can use mktime function to parse date and time easily.
Doesn't it depends on the system you're creating.
If you want to store dates beyond 2038 I would store the datetime and time separate.
what if you are developing a reservation application and at one end you need to know on what date and at what time to schedule an appointment for a user, and at the other end, you need to match the user to a doctors schedule. You save the doctors schedule in a database and you need to know (amoung other things) when the doctor is available (on what days), and at what times. Let us forget about the on what days for a moment, and focus on the time shedule first...
You need to develop a programmable schedule so that if you know that the doctor works 6 months in a particular calendar year. (Jan - Jun), He or she may work (9-5 M,W,Fr), and (10-3 T,Th). Sat and Sunday the doctor is off. So you develop a table to hold the Daily time schedule with 2 columns to hold the daily starttime and daily end time for each day of the week. 14 columns in total and a primary and possibly secondary key. So now its time for some date arithmetic (This is where it gets hairy:-|...
You can say i your query: (mySQL)
Select such and such...
where form.theapptdatetime between doctorschedule_startime_tuesday and doctorschedule_endime_tuesday
and this will do a match to see if your datetime is within the date range of your doctorschedulestartime and endtime... but what if all you need is the time??
will the date arithmetic still work if the time value is stored as a datetime???
In other words if I have 01:00:00 as my doctorschedule_startime, is this a legitimate date value for my arithmetic to work, or will a date portion be forced upon me.
Perhaps I should store the time as a varchar, and convert it to a suitable datetime value and perform the arithmetic in the code instead of the query????
An example comes to my mind as to when have date and time split:
You could want to have DATE a part of the unique index, so that a user is only allowed to add 1 record to some table per date, but still you want to know the TIME he added it, so you keep DATE and TIME separate.

Submitting Dates between Date Range - mySQL

In teaching myself php and mySQL a year or two ago, I created a movie database for the theater I work at, to help automate the more mundane web updates that need to be done weekly. So far this only pertains to film information (title, ratings, synopsis, start date) - but does not include showtimes, but lately I've thought it might be fun to see if it's possible to build on this aspect of the site.
My initial idea was to build a table that displayed showtimes via date groups (ie 5/15 - 5/20), but it was suggested that submitting times for individual days would probably be more useful from a user perspective (ie the showtimes for 5/15 are...), especially since there are occasionally changes and cancellations throughout the week due to special events.
Problem I'm having even starting this - is how to submit more than one date at once. Would it be possible, in the form, to have a 'start date' and 'end date' and have the single form submit all the times input on those two dates and all the dates inbetween?
From a back-end perspective submitting the same 4 or 5 showtimes every day, 7 days a week for 10 to 14 films a week is more work for US than just putting the times in manually in dreamweaver - so I'm just trying to figure out how to make the process easier for us behind the scenes. If we could batch insert a set of showtimes, then we could go back through and edit the individual days that have special/cancelled times (which would probably mean building in a 'draft, live, hidden' system - but I've got at least a basic knowledge of how to go about that.
I've got a very basic table set up for showtimes with (user end example of what I'm aiming for here):
MOVIE_ID (links with the movie info database to pull in film info - title, runtime, etc)
sched_date (uses datetime to set a specific showtime on a specific date)
I guess I might have to abandon using datetime if there's any way to do this?
Any help would be hot! Much thanks!
You can have 2 date fields with names from_date and end_date in your PHP form. In your PHP form submit code you then need to use the DateTime class and start from from_date and use the DateTime::add method to loop till end_date is reached. Please note you need to first convert the 2 dates i.e. from_date and end_date to datetime using either new DateTime('YYYY-MM-DD') or using DateTime::createFromFormat.
In the loop simply send insert commands to MySQL to insert the rows to your DB.

Filtering popular items by using day / week / month

I am developing a website which will have 200.000 pages. There is also a browse section, which shows most popular, highest rated etc. documents. However this section will become almost static couple of weeks later, after launch. So I also would like to implement a filtering system which will show today's, this week's, this month's most popular items, just like youtube.
Just like this:
http://www.youtube.com/videos?c=2
How should I implement this function? Do I need another table, which will have a new entry for every document each day?
docid, date, view_count, rating
So I will get today's row for filtering by using a day, or calculate a week (7 rows) for filtering by using week? It seems not efficient. Do you have any suggestions?
I am using LAMP stack by the way.
Thanks,
Assuming you timestamp the records in your table, you should be able to put a where clause that limits the timestamp to whatever timeframe you want.
You can cache the result, especially the longer ones, for long enough to make the request inconsequential.
EDIT
But perhaps you mean most popular today, not most popular that was added today?
In which case, I don't have an answer.
The most direct approach is to save the timestamp and the resource id each time the resource is shown in recent_views(what, when). Daily/weekly/monthly charts can be created with appropriate WHERE clauses like WHERE when > $beginOfPeriod AND when < $endOfPeriod.
For performance reasons you can aggregate the values each night, save the sums in separate tables like daily_views(what, sum) and truncate the source table.
I guess I would calculate the date's in code and then pass them as arguments, to the SQL you are using.
I would do it using a compiler. Youtube probably does that too, considering the amount of traffic and the response times.
The principle is easy to understand. You log every every view or rating in a page_view table. You define periods at which the compilation occurs (hourly, daily, weekly, monthly). Every time you hit the good time (e.g.: end of the day), you execute the compiler, which essentially execute a query à-la...
SELECT * FROM page_view WHERE date > $from_date AND date < $to_date
... and store the result. This probably works better in a cron job.
The next time you need to display the information, you can just fetch the stored result and display it without re-computation. There are a variety of storage methods you can use: a MySQL table (e.g.: page_view_compiled), memcached, etc.

Recreate/find a Joomla/Community Builder 'Latest Users' module. Dates in MySQL/Joomla

When Joomla first sprung up and I moved over from Mambo I remember finding a component called Community Builder (CB) that extends the user-based interface behind Joomla.
I remember a small module I found in CB that displayed a couple of useful details about users that I want to be able to extract from my current project. These details included:
Total users registered
Total users registered per day
Total users registered per week
Total users registered per month
Latest user registered
Total visitors to the site
My question is how to recreate something very similar. I've been trying to construct an SQL statement that can manipulate the user table results and compare them to a set criteria eg. find all user's with a 'registerDate' variable within the last week.
The problem that has me lost is how to manipulate and compare a date string that resembles '2008-08-05 07:41:40'
The problem that has me lost is how to manipulate and compare a date string that resembles '2008-08-05 07:41:40'
You can have MySQL turn this into a UNIX timestamp, or you can run it through strtotime.
MySQL:
SELECT UNIX_TIMESTAMP(datetime_field) FROM table
strtotime:
$timestamp = strtotime('2008-08-05 07:41:40');

Categories