diff --git a/library/Zend/Date.php b/library/Zend/Date.php index 48bc906f9b..0f7a564668 100644 --- a/library/Zend/Date.php +++ b/library/Zend/Date.php @@ -1274,6 +1274,20 @@ private function _assign($calc, $date, $comp = 0, $dst = false) return $this->getUnixTimestamp(); } + private function _getExtendMonthOffset($hour, $minute, $second, $month, $day, $year) + { + if (self::$_options['extend_month'] === false) { + $tempDate = new Zend_Date($this->mktime($hour, $minute, $second, $month, $day, $year, false)); + $tempDate->setTimezone($this->getTimezone()); + $mday = (int)$tempDate->get('d'); + + if ($mday != $day) { + return ($mday < $day) ? -$mday : ($mday - $day); + } + } + + return 0; + } /** * Calculates the date or object @@ -1635,21 +1649,11 @@ private function _calculate($calc, $date, $part, $locale) if ($calc == 'add') { $date += $found; $calc = 'set'; - if (self::$_options['extend_month'] == false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } + $fixday = $this->_getExtendMonthOffset($hour, $minute, $second, $date, $day, $year); } else if ($calc == 'sub') { $date = $month - $found; $calc = 'set'; - if (self::$_options['extend_month'] == false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } + $fixday = $this->_getExtendMonthOffset($hour, $minute, $second, $date, $day, $year); } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); @@ -1666,21 +1670,11 @@ private function _calculate($calc, $date, $part, $locale) if ($calc == 'add') { $date += $month; $calc = 'set'; - if (self::$_options['extend_month'] == false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } + $fixday = $this->_getExtendMonthOffset($hour, $minute, $second, $date, $day, $year); } else if ($calc == 'sub') { $date = $month - $date; $calc = 'set'; - if (self::$_options['extend_month'] == false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } + $fixday = $this->_getExtendMonthOffset($hour, $minute, $second, $date, $day, $year); } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); @@ -1708,21 +1702,11 @@ private function _calculate($calc, $date, $part, $locale) if ($calc == 'add') { $date += $found; $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } + $fixday = $this->_getExtendMonthOffset($hour, $minute, $second, $date, $day, $year); } else if ($calc == 'sub') { $date = $month - $found; $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } + $fixday = $this->_getExtendMonthOffset($hour, $minute, $second, $date, $day, $year); } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); @@ -1739,21 +1723,11 @@ private function _calculate($calc, $date, $part, $locale) if ($calc === 'add') { $date += $month; $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } + $fixday = $this->_getExtendMonthOffset($hour, $minute, $second, $date, $day, $year); } else if ($calc === 'sub') { $date = $month - $date; $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } + $fixday = $this->_getExtendMonthOffset($hour, $minute, $second, $date, $day, $year); } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), @@ -1787,21 +1761,11 @@ private function _calculate($calc, $date, $part, $locale) if ($calc === 'add') { $date += $found; $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } + $fixday = $this->_getExtendMonthOffset($hour, $minute, $second, $date, $day, $year); } else if ($calc === 'sub') { $date = $month - $found; $calc = 'set'; - if (self::$_options['extend_month'] === false) { - $parts = $this->getDateParts($this->mktime($hour, $minute, $second, $date, $day, $year, false)); - if ($parts['mday'] != $day) { - $fixday = ($parts['mday'] < $day) ? -$parts['mday'] : ($parts['mday'] - $day); - } - } + $fixday = $this->_getExtendMonthOffset($hour, $minute, $second, $date, $day, $year); } return $this->_assign($calc, $this->mktime(0, 0, 0, $date, $day + $fixday, $year, true), $this->mktime(0, 0, 0, $month, $day, $year, true), $hour); diff --git a/tests/Zend/DateTest.php b/tests/Zend/DateTest.php index 90604b3941..b2c52f809e 100644 --- a/tests/Zend/DateTest.php +++ b/tests/Zend/DateTest.php @@ -4380,6 +4380,17 @@ public function testSubMonth() $this->assertSame('2019-12-01T04:00:00+05:00', $date->get(Zend_Date::W3C)); $date->subMonth(12); $this->assertSame('2018-12-01T04:00:00+05:00', $date->get(Zend_Date::W3C)); + + $oldzone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + + // "2016-05-01T00:00:00+04:00" + $date = new Zend_Date(1462046400, $locale); + $date->setTimezone('Asia/Muscat'); + + $date->subMonth(1); + $this->assertSame('2016-04-01T00:00:00+04:00', $date->get(Zend_Date::W3C)); + date_default_timezone_set($oldzone); } /**