You are here

function interval_apply_interval in Interval Field 7

Applies the interval values to a given date

Parameters

object $date: A DateTime object to which the interval needs to be applied

array $item: An array of values for the interval item consisting of:

  • interval: the interval (int)
  • period: the interval period

bool $limit: When calling the interval apply function with months or a month multiplier, keep the date in the last day of the month if this was exceeded. Example, with $limit set to TRUE, January 31st +1 month will result in February 28th.

Return value

bool TRUE/FALSE

2 calls to interval_apply_interval()
IntervalUnitTestCase::testInterval in ./interval.test
interval_rules_apply_interval in ./interval.rules.inc
Rules action callback: Apply an interval to a date.

File

./interval.module, line 445
Defines an interval field @copyright Copyright(c) 2011 Rowlands Group @license GPL v2+ http://www.fsf.org/licensing/licenses/gpl.html @author Lee Rowlands leerowlands at rowlandsgroup dot com

Code

function interval_apply_interval($date, $item, $limit = FALSE) {
  if (is_object($date)) {
    $old_date = clone $date;
    $intervals = interval_get_intervals();
    $interval = $intervals[$item['period']];
    $datetime = interval_php_interval($item);
    $date
      ->modify($datetime);

    // "modify()" uses "strtotime()", so is really just adding X seconds. When
    // working with months, this can have counter-intuitive results. $limit is
    // supposed to fix these behaviors:
    if ($limit && $interval['php'] == 'months') {
      $dateinterval = $date
        ->diff($old_date);

      // Assert that the month interval is properly 1 month:
      while ($dateinterval->m < $interval['multiplier']) {

        // We went 30x days but didn't reach the right month: Dec 1 to Dec 31.
        // Appropriate behavior is to go to Jan 1.
        $date
          ->modify("first day of next month");
        $dateinterval = $date
          ->diff($old_date);
      }
      if ($dateinterval->d != 0) {

        // We went too far, which can happen around February. Collapse back to
        // the end of the proper (prior) month.
        $date
          ->modify("last day of last month");
      }
    }
    return TRUE;
  }
  return FALSE;
}