P: n/a

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.
Please help me to find a way to solve this problem.
Thank You,
Nathan  
Share this Question
P: n/a

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.  
P: n/a

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.  
P: n/a

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
}   This discussion thread is closed Replies have been disabled for this discussion.   Question stats  viewed: 1214
 replies: 3
 date asked: Jul 17 '05
