I have a calendar application which utilizes the newer PHP DateTime classes. I have a way that I handle recurring events, but it seems hack-ish and I wanted to see if you guys have better ideas:
- I have a recurring event that starts 11/16/2009 (Nov 16, 2009)
- It will occur every 3 days
- The event will recur indefinitely
Let's say the user looks at the calendar for Dec, 3100 - this event should show there repeating every 3 days like normal. The question is - how do I calculate those days in that month?
=========================================
This is how I basically do it, but I know I'm missing something easier:
- I calculate the difference in days between the start of the month being looked at (Dec 1, 3100) and the event start date (Nov 16, 2009) stored as $daysDiff
- I subtract the modulus, so that I get a factor of 3 days from the start like this: $daysDiff - ($daysDiff % 3)
- For the sake of argument lets say that gives me Nov 29, 3100 as a date.
- I then add 3 days to that date repeatedly until I have all the dates within Dec 3100
My main problem comes with step 1. The PHP DateInterval::date_diff function does not calculate differences in days. It will give me years, months, and days. I then have to fudge the numbers to get an estimate date around Dec, 3100. 11/16/2009 + (1090 years * 365.25 days) + (9 months * 30.5 days) + 15 days
When you go REAL far into the future like the year 9999, this estimation can be off by a month, then I have to subtract a lot of 3 day intervals to get where I need.
This can be done nicely using a DatePeriod as an Iterator and then filterd to the start date you want to display:
You could format your date as a unix timestamp then use modular division to find the first instance in the selected month, then step in increments of 3 days from there. So for your example:
Obviously, you've got a few variables to swap out so the user can select any month, but that should be the basic algorithm. Also, ensure your DateTimes are the correct date, but with the time set as 00:00:00, or else the first while loop will never resolve. This also assumes you've ensured the selected date is later than the beginning date of the event.