/** * Get the timestamp of the next upcoming Nth day of month. * * @param int $curdate The current occurrence's timestamp * @param int|array $days_of_week Index(-es) of the possible day(s)-of-week the next instance may land on * @param int|array $weeks_of_month Index(-es) of the possible week(s) of the month the next instance may land on * @param int|array $months_of_year Index(-es) of the possible month(s) of the year the next instance may land on * * @return int|false The timestamp of the next occurrence on the nth day of the month or false */ private function getNthDayOfMonth($curdate, $days_of_week, $weeks_of_month, $months_of_year) { // Cast to arrays for consistency $days_of_week = (array) $days_of_week; $weeks_of_month = (array) $weeks_of_month; $months_of_year = (array) $months_of_year; // Obtain the hour, minute and second of $curdate for later comparison $cur_hour = (int) date('G', $curdate); $cur_minute = (int) date('i', $curdate); $cur_second = (int) date('s', $curdate); // Sort and rotate the arrays to give us a sensible starting point $this->sort_and_rotate_int_array($days_of_week, (int) date('N', $curdate)); $this->sort_and_rotate_int_array($months_of_year, (int) date('n', $curdate)); sort($weeks_of_month); $weeks_of_month = array_map('intval', $weeks_of_month); // The next occurence must take place this year or the next applicable year $year = (int) date('Y', $curdate); $years = array($year, $year + $this->years_between); // Examine each possible year and month foreach ($years as $year) { foreach ($months_of_year as $month) { // If we are behind $curdate's month and year then keep advancing if ($year <= date('Y', $curdate) && $month < date('n', $curdate)) { continue; } foreach ($weeks_of_month as $nth_week) { foreach ($days_of_week as $day) { // Determine the date of the first of these days (ie, the date of the first Tuesday this month) $start_of_month = mktime(0, 0, 0, $month, 1, $year); $first_date = Tribe__Date_Utils::get_first_day_of_week_in_month($start_of_month, $day); $day_of_month = (int) date('j', $first_date); // Add the relevant number of weeks $week = $nth_week > 0 ? $nth_week : abs($nth_week); $direction = $nth_week > 0 ? 1 : -1; $day_of_month = date('j', Tribe__Date_Utils::get_weekday_timestamp($day, $week, $month, $year, $direction)); // Form a timestamp representing this day of the week in the appropriate week of the month $timestamp = mktime($cur_hour, $cur_minute, $cur_second, $month, $day_of_month, $year); // If we got a valid timestamp that is ahead of $curdate, we have a winner if ($timestamp && $timestamp > $curdate) { return $timestamp; } } } } } // No match? return false; }