Tools\Utility\Time::incrementDate PHP Method

incrementDate() public method

Handles month/year increment calculations in a safe way, avoiding the pitfall of "fuzzy" month units.
public incrementDate ( mixed $startDate, integer $years, integer $months, integer $days, string | DateTimeZone | integer | null $timezone = null ) : object
$startDate mixed Either a date string or a DateTime object
$years integer Years to increment/decrement
$months integer Months to increment/decrement
$days integer Days
$timezone string | DateTimeZone | integer | null Timezone string or DateTimeZone object
return object DateTime with incremented/decremented month/year values.
    public function incrementDate($startDate, $years = 0, $months = 0, $days = 0, $timezone = null)
    {
        if (!is_object($startDate)) {
            $startDate = new DateTime($startDate);
            if ($timezone) {
                $startDate->setTimezone($this->safeCreateDateTimeZone($timezone));
            }
        }
        $startingTimeStamp = $startDate->getTimestamp();
        // Get the month value of the given date:
        $monthString = date('Y-m', $startingTimeStamp);
        // Create a date string corresponding to the 1st of the give month,
        // making it safe for monthly/yearly calculations:
        $safeDateString = "first day of {$monthString}";
        // offset is wrong
        $months++;
        // Increment date by given month/year increments:
        $incrementedDateString = "{$safeDateString} {$months} month {$years} year";
        $newTimeStamp = strtotime($incrementedDateString) + $days * DAY;
        $newDate = DateTime::createFromFormat('U', $newTimeStamp);
        return $newDate;
    }

Usage Example

コード例 #1
0
ファイル: TimeTest.php プロジェクト: alescx/cakephp-tools
 /**
  * Currently only works with timezoned localized values, not with UTC!!!
  *
  * @return void
  */
 public function testIncrementDate()
 {
     $timezone = Configure::read('Config.timezone');
     //$timezone = Date$this->Time->timezone();
     Configure::write('Config.timezone', 'Europe/Berlin');
     $phpTimezone = date_default_timezone_get();
     date_default_timezone_set('Europe/Berlin');
     $from = '2012-12-31';
     $Date = $this->Time->incrementDate($from, 0, 0);
     $this->assertSame($from, $Date->format(FORMAT_DB_DATE));
     $from = '2012-12-31';
     $Date = $this->Time->incrementDate($from, 0, 1);
     $this->assertSame('2013-01-31', $Date->format(FORMAT_DB_DATE));
     $from = '2012-12-31';
     $Date = $this->Time->incrementDate($from, 0, 2);
     $this->assertSame('2013-02-28', $Date->format(FORMAT_DB_DATE));
     $from = '2012-12-31';
     $Date = $this->Time->incrementDate($from, 0, 4);
     $this->assertSame('2013-04-30', $Date->format(FORMAT_DB_DATE));
     $from = '2012-12-31';
     $Date = $this->Time->incrementDate($from, 1, 0);
     $this->assertSame('2013-12-31', $Date->format(FORMAT_DB_DATE));
     // from leap year
     $from = '2008-02-29';
     $Date = $this->Time->incrementDate($from, 1, 0);
     $this->assertSame('2009-02-28', $Date->format(FORMAT_DB_DATE));
     // into leap year
     $from = '2007-02-28';
     $Date = $this->Time->incrementDate($from, 1, 0);
     $this->assertSame('2008-02-29', $Date->format(FORMAT_DB_DATE));
     // other direction
     $from = '2012-12-31';
     $Date = $this->Time->incrementDate($from, 0, -1);
     $this->assertSame('2012-11-30', $Date->format(FORMAT_DB_DATE));
     $from = '2012-12-31';
     $Date = $this->Time->incrementDate($from, -1, -1);
     $this->assertSame('2011-11-30', $Date->format(FORMAT_DB_DATE));
     // including days
     $from = '2012-12-31';
     $Date = $this->Time->incrementDate($from, 0, 1, 1);
     $this->assertSame('2013-02-01', $Date->format(FORMAT_DB_DATE));
     // including days
     $from = '2012-12-31';
     $Date = $this->Time->incrementDate($from, 0, 1, 5);
     $this->assertSame('2013-02-05', $Date->format(FORMAT_DB_DATE));
     Configure::write('Config.timezone', $timezone);
     date_default_timezone_set($phpTimezone);
 }