diff --git a/src/Carbon/Carbon.php b/src/Carbon/Carbon.php index 4068ae811d..2d58016e9b 100644 --- a/src/Carbon/Carbon.php +++ b/src/Carbon/Carbon.php @@ -2801,9 +2801,13 @@ public function diffInMinutes(self $dt = null, $abs = true) public function diffInSeconds(self $dt = null, $abs = true) { $dt = $dt ?: static::now($this->getTimezone()); - $value = $dt->getTimestamp() - $this->getTimestamp(); + $diff = $this->diff($dt); + $value = $diff->days * static::HOURS_PER_DAY * static::MINUTES_PER_HOUR * static::SECONDS_PER_MINUTE + + $diff->h * static::MINUTES_PER_HOUR * static::SECONDS_PER_MINUTE + + $diff->i * static::SECONDS_PER_MINUTE + + $diff->s; - return $abs ? abs($value) : $value; + return $abs || !$diff->invert ? $value : -$value; } /** @@ -3383,27 +3387,6 @@ public function isBirthday($dt = null) return $this->isSameAs('md', $dt); } - /** - * Consider the timezone when modifying the instance. - * - * @param string $modify - * - * @return static - */ - public function modify($modify) - { - if ($this->local) { - return parent::modify($modify); - } - - $timezone = $this->getTimezone(); - $this->setTimezone('UTC'); - $instance = parent::modify($modify); - $this->setTimezone($timezone); - - return $instance; - } - /** * Return a serialized string of the instance. * diff --git a/tests/Carbon/ModifyNearDSTChangeTest.php b/tests/Carbon/ModifyNearDSTChangeTest.php new file mode 100644 index 0000000000..f28561b8fe --- /dev/null +++ b/tests/Carbon/ModifyNearDSTChangeTest.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Tests\Carbon; + +use Carbon\Carbon; +use Tests\AbstractTestCase; + +class ModifyNearDSTChangeTest extends AbstractTestCase +{ + /** + * Tests transition through DST change hour in non default timezone + * + * @dataProvider getTransitionTests + */ + public function testTransitionInNonDefaultTimezone($dateString, $addHours, $expected) + { + date_default_timezone_set('Europe/london'); + $date = Carbon::parse($dateString, 'America/New_York'); + $date->addHours($addHours); + $this->assertSame($expected, $date->format('c')); + } + + /** + * Tests transition through DST change hour in default timezone + * + * @dataProvider getTransitionTests + */ + public function testTransitionInDefaultTimezone($dateString, $addHours, $expected) + { + date_default_timezone_set('America/New_York'); + $date = Carbon::parse($dateString, 'America/New_York'); + $date->addHours($addHours); + $this->assertSame($expected, $date->format('c')); + } + + public function getTransitionTests() + { + + // arguments: + // - Date string to Carbon::parse in America/New_York. + // - Hours to add + // - Resulting string in 'c' format + $tests = array( + // testForwardTransition + // When standard time was about to reach 2010-03-14T02:00:00-05:00 clocks were turned forward 1 hour to + // 2010-03-14T03:00:00-04:00 local daylight time instead + array('2010-03-14T00:00:00', 24, '2010-03-15T00:00:00-04:00'), + + // testBackwardTransition + // When local daylight time was about to reach 2010-11-07T02:00:00-04:00 clocks were turned backward 1 hour + // to 2010-11-07T01:00:00-05:00 local standard time instead + array('2010-11-07T00:00:00', 24, '2010-11-08T00:00:00-05:00'), + ); + + return $tests; + } +} diff --git a/tests/Carbon/ModifyTest.php b/tests/Carbon/ModifyTest.php index 179590c692..aa86172433 100644 --- a/tests/Carbon/ModifyTest.php +++ b/tests/Carbon/ModifyTest.php @@ -30,5 +30,8 @@ public function testTimezoneModify() $b = $a->copy(); $b->addHours(24); $this->assertSame(24, $a->diffInHours($b)); + $this->assertSame(24, $a->diffInHours($b, false)); + $this->assertSame(24, $b->diffInHours($a)); + $this->assertSame(-24, $b->diffInHours($a, false)); } }