# next occurence

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on

Hi,

Interesting question:

A user fills a form about how often an event happen.
He has 4 fields: [Day of the week, Day of the month, Month, Year].
In any of them, he can enter "*" as a joker, to say it doesn't matter.

For example, his birthday is every October 5th, so he enters:
[*,5,10,*], because the day of the week, or the year don't matter.
He has an apointment every Monday:
[Monday,*,*,*]
He has to pay the rent first day of each month in 2005:
[*,1,*,2005]

You get the situation?
Now once I've collected the data, I want to know WHEN is the next time
this event will happen.
How do I do that?

I've tried to play around with strtotime(), but it doesn't work for
everything.

Thank You,

Nathan

## Re: next occurence

Hmmm...let's see.  I'll propose a relatively simple solution, although
it certainly isn't on the cutting edge of efficiency.  Suppose we have:

\$dayOfWeek; //Monday, Tuesday, etc.
\$dayOfMonth;
\$month;
\$year;

Then we can just keep adding one day at a time until we find the next
match:

\$i = 1; //set to 0 if you want to include today
while(true) {
\$thisTime = strtotime("+" . \$i . " day"); //\$i days from now

if(\$year != "*" && date("Y", \$thisTime) != \$year)
continue;
if(\$month != "*" && date("n", \$thisTime) != \$month)
continue;
if(\$dayOfMonth != "*" && date("m", \$thisTime) != \$dayOfMonth)
continue;
if(\$dayOfWeek != "*" && date("l", \$thisTime) != \$dayOfWeek)
continue;

return \$thisTime; //UNIX timestamp of the next event occurence
}

You should also include some check in the while loop to avoid an
infinite loop (imagine a situation where you specify all four
parameters and they represent a date that doesn't exist, i.e.
[Tuesday,27,3,2005] or the case where they enter a date in the past).

As I said, it's horribly inefficient in terms of performance, but
reasonably efficient in terms of coding. This way you avoid all the
crazy cases and various combinations of wildcards.

## Re: next occurence

Cool that's a very useful shortcut.
2 little mistakes though:
- Need to increment \$i .
- The day of the the month is "j" not "m".

Now add a little trick, I'd like the user to be able to enter "last"
instead of a number in \$dayOfMonth. So that it doesn't matter how many
days there are in the month.

## Re: next occurence

Yeah, my oversight.  Correcting my mistakes, and then adding the
ability to specify the \$dayOfMonth as "last" as well:

\$i = 0; //set to -1 if you want to include today
while(true) {
\$i++;
\$thisTime = strtotime("+" . \$i . " day"); //\$i days from now

\$thisDayOfMonth = \$dayOfMonth;
if(\$dayOfMonth != "*" && \$dayOfMonth == "last")
\$thisDayOfMonth = date("t", \$thisTime);

if(\$year != "*" && date("Y", \$thisTime) != \$year)
continue;
if(\$month != "*" && date("n", \$thisTime) != \$month)
continue;
if(\$thisDayOfMonth != "*" && date("j", \$thisTime) !=
\$thisDayOfMonth)
continue;
if(\$dayOfWeek != "*" && date("l", \$thisTime) != \$dayOfWeek)
continue;

return \$thisTime; //UNIX timestamp of the next event occurence
}