Commit 95ed8ce2 authored by alexpott's avatar alexpott
Browse files

Issue #2704457 by thtas, mpdonadio: Fix DrupalDateTime::diff()

parent 6347dec5
......@@ -294,6 +294,30 @@ public function __call($method, $args) {
return call_user_func_array(array($this->dateTimeObject, $method), $args);
}
/**
* Returns the difference between two DateTimePlus objects.
*
* @param \Drupal\Component\Datetime\DateTimePlus|\DateTime $datetime2
* The date to compare to.
* @param bool $absolute
* Should the interval be forced to be positive?
*
* @return \DateInterval
* A DateInterval object representing the difference between the two dates.
*
* @throws \BadMethodCallException
* If the input isn't a DateTime or DateTimePlus object.
*/
public function diff($datetime2, $absolute = FALSE) {
if ($datetime2 instanceof DateTimePlus) {
$datetime2 = $datetime2->dateTimeObject;
}
if (!($datetime2 instanceof \DateTime)) {
throw new \BadMethodCallException(sprintf('Method %s expects parameter 1 to be a \DateTime or \Drupal\Component\Datetime\DateTimePlus object', __METHOD__));
}
return $this->dateTimeObject->diff($datetime2, $absolute);
}
/**
* Implements the magic __callStatic method.
*
......
......@@ -55,6 +55,42 @@ public function testDateArrays($input, $timezone, $expected) {
$this->assertEquals($expected, $value, sprintf("Test new DateTimePlus(%s, %s): should be %s, found %s.", $input, $timezone, $expected, $value));
}
/**
* Test date diffs.
*
* @param mixed $input1
* A DateTimePlus object.
* @param mixed $input2
* Date argument for DateTimePlus::diff method.
* @param bool $absolute
* Absolute flag for DateTimePlus::diff method.
* @param \DateInterval $expected
* The expected result of the DateTimePlus::diff operation.
*
* @dataProvider providerTestDateDiff
*/
public function testDateDiff($input1, $input2, $absolute, \DateInterval $expected) {
$interval = $input1->diff($input2, $absolute);
$this->assertEquals($interval, $expected);
}
/**
* Test date diff exception caused by invalid input.
*
* @param mixed $input1
* A DateTimePlus object.
* @param mixed $input2
* Date argument for DateTimePlus::diff method.
* @param bool $absolute
* Absolute flag for DateTimePlus::diff method.
*
* @dataProvider providerTestInvalidDateDiff
*/
public function testInvalidDateDiff($input1, $input2, $absolute) {
$this->setExpectedException(\BadMethodCallException::class, 'Method Drupal\Component\Datetime\DateTimePlus::diff expects parameter 1 to be a \DateTime or \Drupal\Component\Datetime\DateTimePlus object');
$interval = $input1->diff($input2, $absolute);
}
/**
* Test creating dates from invalid array input.
*
......@@ -528,4 +564,106 @@ public function providerTestDateTimestamp() {
);
}
/**
* Provides data for date tests.
*
* @return array
* An array of arrays, each containing the input parameters for
* DateTimePlusTest::testDateDiff().
*
* @see DateTimePlusTest::testDateDiff()
*/
public function providerTestDateDiff() {
$empty_interval = new \DateInterval('PT0S');
$positive_19_hours = new \DateInterval('PT19H');
$positive_18_hours = new \DateInterval('PT18H');
$positive_1_hour = new \DateInterval('PT1H');
$negative_1_hour = new \DateInterval('PT1H');
$negative_1_hour->invert = 1;
return array(
// There should be a 19 hour time interval between
// new years in Sydney and new years in LA in year 2000.
array(
'input2' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('Australia/Sydney')),
'input1' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles')),
'absolute' => FALSE,
'expected' => $positive_19_hours,
),
// In 1970 Sydney did not observe daylight savings time
// So there is only a 18 hour time interval.
array(
'input2' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('Australia/Sydney')),
'input1' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles')),
'absolute' => FALSE,
'expected' => $positive_18_hours,
),
array(
'input1' => DateTimePlus::createFromFormat('U', 3600, new \DateTimeZone('America/Los_Angeles')),
'input2' => DateTimePlus::createFromFormat('U', 0, new \DateTimeZone('UTC')),
'absolute' => FALSE,
'expected' => $negative_1_hour,
),
array(
'input1' => DateTimePlus::createFromFormat('U', 3600),
'input2' => DateTimePlus::createFromFormat('U', 0),
'absolute' => FALSE,
'expected' => $negative_1_hour,
),
array(
'input1' => DateTimePlus::createFromFormat('U', 3600),
'input2' => \DateTime::createFromFormat('U', 0),
'absolute' => FALSE,
'expected' => $negative_1_hour,
),
array(
'input1' => DateTimePlus::createFromFormat('U', 3600),
'input2' => DateTimePlus::createFromFormat('U', 0),
'absolute' => TRUE,
'expected' => $positive_1_hour,
),
array(
'input1' => DateTimePlus::createFromFormat('U', 3600),
'input2' => \DateTime::createFromFormat('U', 0),
'absolute' => TRUE,
'expected' => $positive_1_hour,
),
array(
'input1' => DateTimePlus::createFromFormat('U', 0),
'input2' => DateTimePlus::createFromFormat('U', 0),
'absolute' => FALSE,
'expected' => $empty_interval,
),
);
}
/**
* Provides data for date tests.
*
* @return array
* An array of arrays, each containing the input parameters for
* DateTimePlusTest::testInvalidDateDiff().
*
* @see DateTimePlusTest::testInvalidDateDiff()
*/
public function providerTestInvalidDateDiff() {
return array(
array(
'input1' => DateTimePlus::createFromFormat('U', 3600),
'input2' => '1970-01-01 00:00:00',
'absolute' => FALSE,
),
array(
'input1' => DateTimePlus::createFromFormat('U', 3600),
'input2' => NULL,
'absolute' => FALSE,
),
);
}
}
<?php
namespace Drupal\Tests\Core\Datetime;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\Core\Datetime\DrupalDateTime
* @group Datetime
*/
class DrupalDateTimeTest extends UnitTestCase {
/**
* Test date diffs.
*
* @param mixed $input1
* A DrupalDateTime object.
* @param mixed $input2
* Date argument for DrupalDateTime::diff method.
* @param bool $absolute
* Absolute flag for DrupalDateTime::diff method.
* @param \DateInterval $expected
* The expected result of the DrupalDateTime::diff operation.
*
* @dataProvider providerTestDateDiff
*/
public function testDateDiff($input1, $input2, $absolute, \DateInterval $expected) {
$interval = $input1->diff($input2, $absolute);
$this->assertEquals($interval, $expected);
}
/**
* Test date diff exception caused by invalid input.
*
* @param mixed $input1
* A DateTimePlus object.
* @param mixed $input2
* Date argument for DateTimePlus::diff method.
* @param bool $absolute
* Absolute flag for DateTimePlus::diff method.
*
* @dataProvider providerTestInvalidDateDiff
*/
public function testInvalidDateDiff($input1, $input2, $absolute) {
$this->setExpectedException(\BadMethodCallException::class, 'Method Drupal\Component\Datetime\DateTimePlus::diff expects parameter 1 to be a \DateTime or \Drupal\Component\Datetime\DateTimePlus object');
$interval = $input1->diff($input2, $absolute);
}
/**
* Provides data for date tests.
*
* @return array
* An array of arrays, each containing the input parameters for
* DrupalDateTimeTest::testDateDiff().
*
* @see DrupalDateTimeTest::testDateDiff()
*/
public function providerTestDateDiff() {
$settings = ['langcode' => 'en'];
$utc_tz = new \DateTimeZone('UTC');
$empty_interval = new \DateInterval('PT0S');
$positive_19_hours = new \DateInterval('PT19H');
$positive_18_hours = new \DateInterval('PT18H');
$positive_1_hour = new \DateInterval('PT1H');
$negative_1_hour = new \DateInterval('PT1H');
$negative_1_hour->invert = 1;
return array(
// There should be a 19 hour time interval between
// new years in Sydney and new years in LA in year 2000.
array(
'input2' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('Australia/Sydney'), $settings),
'input1' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles'), $settings),
'absolute' => FALSE,
'expected' => $positive_19_hours,
),
// In 1970 Sydney did not observe daylight savings time
// So there is only a 18 hour time interval.
array(
'input2' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('Australia/Sydney'), $settings),
'input1' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles'), $settings),
'absolute' => FALSE,
'expected' => $positive_18_hours,
),
array(
'input1' => DrupalDateTime::createFromFormat('U', 3600, new \DateTimeZone('America/Los_Angeles'), $settings),
'input2' => DrupalDateTime::createFromFormat('U', 0, $utc_tz, $settings),
'absolute' => FALSE,
'expected' => $negative_1_hour,
),
array(
'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
'input2' => DrupalDateTime::createFromFormat('U', 0, $utc_tz, $settings),
'absolute' => FALSE,
'expected' => $negative_1_hour,
),
array(
'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
'input2' => \DateTime::createFromFormat('U', 0),
'absolute' => FALSE,
'expected' => $negative_1_hour,
),
array(
'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
'input2' => DrupalDateTime::createFromFormat('U', 0, $utc_tz, $settings),
'absolute' => TRUE,
'expected' => $positive_1_hour,
),
array(
'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
'input2' => \DateTime::createFromFormat('U', 0),
'absolute' => TRUE,
'expected' => $positive_1_hour,
),
array(
'input1' => DrupalDateTime::createFromFormat('U', 0, $utc_tz, $settings),
'input2' => DrupalDateTime::createFromFormat('U', 0, $utc_tz, $settings),
'absolute' => FALSE,
'expected' => $empty_interval,
),
);
}
/**
* Provides data for date tests.
*
* @return array
* An array of arrays, each containing the input parameters for
* DateTimePlusTest::testInvalidDateDiff().
*
* @see DateTimePlusTest::testInvalidDateDiff()
*/
public function providerTestInvalidDateDiff() {
$settings = ['langcode' => 'en'];
$utc_tz = new \DateTimeZone('UTC');
return array(
array(
'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
'input2' => '1970-01-01 00:00:00',
'absolute' => FALSE,
),
array(
'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
'input2' => NULL,
'absolute' => FALSE,
),
);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment