next occurence

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • nasht

    next occurence

    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

  • ZeldorBlat

    #2
    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,20 05] 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.

    Comment

    • nasht

      #3
      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.

      Comment

      • ZeldorBlat

        #4
        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($thisDayOfMo nth != "*" && date("j", $thisTime) !=
        $thisDayOfMonth )
        continue;
        if($dayOfWeek != "*" && date("l", $thisTime) != $dayOfWeek)
        continue;

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

        Comment

        Working...