namespace Drupal\Tests\Component\Datetime;
-use Drupal\Tests\UnitTestCase;
use Drupal\Component\Datetime\DateTimePlus;
+use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass \Drupal\Component\Datetime\DateTimePlus
* @group Datetime
*/
-class DateTimePlusTest extends UnitTestCase {
+class DateTimePlusTest extends TestCase {
/**
* Test creating dates from string and array input.
* @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');
+ if (method_exists($this, 'expectException')) {
+ $this->expectException(\BadMethodCallException::class);
+ $this->expectExceptionMessage('Method Drupal\Component\Datetime\DateTimePlus::diff expects parameter 1 to be a \DateTime or \Drupal\Component\Datetime\DateTimePlus object');
+ }
+ else {
+ $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);
}
* @dataProvider providerTestInvalidDateArrays
*/
public function testInvalidDateArrays($input, $timezone, $class) {
- $this->setExpectedException($class);
+ if (method_exists($this, 'expectException')) {
+ $this->expectException($class);
+ }
+ else {
+ $this->setExpectedException($class);
+ }
$this->assertInstanceOf(
'\Drupal\Component\DateTimePlus',
DateTimePlus::createFromArray($input, $timezone)
* Assertion helper for testTimestamp and testDateTimestamp since they need
* different dataProviders.
*
- * @param DateTimePlus $date
+ * @param \Drupal\Component\Datetime\DateTimePlus $date
* DateTimePlus to test.
* @input mixed $input
* The original input passed to the test method.
* @dataProvider providerTestInvalidDates
*/
public function testInvalidDates($input, $timezone, $format, $message, $class) {
- $this->setExpectedException($class);
+ if (method_exists($this, 'expectException')) {
+ $this->expectException($class);
+ }
+ else {
+ $this->setExpectedException($class);
+ }
DateTimePlus::createFromFormat($format, $input, $timezone);
}
* @see DateTimePlusTest::testDates()
*/
public function providerTestDates() {
- return [
+ $dates = [
// String input.
// Create date object from datetime string.
['2009-03-07 10:30', 'America/Chicago', '2009-03-07T10:30:00-06:00'],
// Same during daylight savings time.
['2009-06-07 10:30', 'Australia/Canberra', '2009-06-07T10:30:00+10:00'],
];
+
+ // On 32-bit systems, timestamps are limited to 1901-2038.
+ if (PHP_INT_SIZE > 4) {
+ // Create a date object in the distant past.
+ // @see https://www.drupal.org/node/2795489#comment-12127088
+ if (version_compare(PHP_VERSION, '5.6.15', '>=')) {
+ $dates[] = ['1809-02-12 10:30', 'America/Chicago', '1809-02-12T10:30:00-06:00'];
+ }
+ // Create a date object in the far future.
+ $dates[] = ['2345-01-02 02:04', 'UTC', '2345-01-02T02:04:00+00:00'];
+ }
+
+ return $dates;
}
/**
* @see DateTimePlusTest::testDates()
*/
public function providerTestDateArrays() {
- return [
+ $dates = [
// Array input.
// Create date object from date array, date only.
[['year' => 2010, 'month' => 2, 'day' => 28], 'America/Chicago', '2010-02-28T00:00:00-06:00'],
// Create date object from date array with hour.
[['year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 10], 'Europe/Berlin', '2010-02-28T10:00:00+01:00'],
];
+
+ // On 32-bit systems, timestamps are limited to 1901-2038.
+ if (PHP_INT_SIZE > 4) {
+ // Create a date object in the distant past.
+ // @see https://www.drupal.org/node/2795489#comment-12127088
+ if (version_compare(PHP_VERSION, '5.6.15', '>=')) {
+ $dates[] = [['year' => 1809, 'month' => 2, 'day' => 12], 'America/Chicago', '1809-02-12T00:00:00-06:00'];
+ }
+ // Create a date object in the far future.
+ $dates[] = [['year' => 2345, 'month' => 1, 'day' => 2], 'UTC', '2345-01-02T00:00:00+00:00'];
+ }
+
+ return $dates;
}
/**
public function testValidateFormat() {
// Check that an input that does not strictly follow the input format will
// produce the desired date. In this case the year string '11' doesn't
- // precisely match the 'Y' formater parameter, but PHP will parse it
+ // precisely match the 'Y' formatter parameter, but PHP will parse it
// regardless. However, when formatted with the same string, the year will
// be output with four digits. With the ['validate_format' => FALSE]
// $settings, this will not thrown an exception.
// Parse the same date with ['validate_format' => TRUE] and make sure we
// get the expected exception.
- $this->setExpectedException(\UnexpectedValueException::class);
+ if (method_exists($this, 'expectException')) {
+ $this->expectException(\UnexpectedValueException::class);
+ }
+ else {
+ $this->setExpectedException(\UnexpectedValueException::class);
+ }
$date = DateTimePlus::createFromFormat('Y-m-d H:i:s', '11-03-31 17:44:00', 'UTC', ['validate_format' => TRUE]);
}
+ /**
+ * Tests setting the default time for date-only objects.
+ */
+ public function testDefaultDateTime() {
+ $utc = new \DateTimeZone('UTC');
+
+ $date = DateTimePlus::createFromFormat('Y-m-d H:i:s', '2017-05-23 22:58:00', $utc);
+ $this->assertEquals('22:58:00', $date->format('H:i:s'));
+ $date->setDefaultDateTime();
+ $this->assertEquals('12:00:00', $date->format('H:i:s'));
+ }
+
+ /**
+ * Tests that object methods are chainable.
+ *
+ * @covers ::__call
+ */
+ public function testChainable() {
+ $date = new DateTimePlus('now', 'Australia/Sydney');
+
+ $date->setTimestamp(12345678);
+ $rendered = $date->render();
+ $this->assertEquals('1970-05-24 07:21:18 Australia/Sydney', $rendered);
+
+ $date->setTimestamp(23456789);
+ $rendered = $date->setTimezone(new \DateTimeZone('America/New_York'))->render();
+ $this->assertEquals('1970-09-29 07:46:29 America/New_York', $rendered);
+
+ $date = DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-05-24 07:21:18', new \DateTimeZone('Australia/Sydney'))
+ ->setTimezone(new \DateTimeZone('America/New_York'));
+ $rendered = $date->render();
+ $this->assertInstanceOf(DateTimePlus::class, $date);
+ $this->assertEquals(12345678, $date->getTimestamp());
+ $this->assertEquals('1970-05-23 17:21:18 America/New_York', $rendered);
+ }
+
+ /**
+ * Tests that non-chainable methods work.
+ *
+ * @covers ::__call
+ */
+ public function testChainableNonChainable() {
+ $datetime1 = new DateTimePlus('2009-10-11 12:00:00');
+ $datetime2 = new DateTimePlus('2009-10-13 12:00:00');
+ $interval = $datetime1->diff($datetime2);
+ $this->assertInstanceOf(\DateInterval::class, $interval);
+ $this->assertEquals('+2 days', $interval->format('%R%a days'));
+ }
+
+ /**
+ * Tests that chained calls to non-existent functions throw an exception.
+ *
+ * @covers ::__call
+ */
+ public function testChainableNonCallable() {
+ if (method_exists($this, 'expectException')) {
+ $this->expectException(\BadMethodCallException::class);
+ $this->expectExceptionMessage('Call to undefined method Drupal\Component\Datetime\DateTimePlus::nonexistent()');
+ }
+ else {
+ $this->setExpectedException(\BadMethodCallException::class, 'Call to undefined method Drupal\Component\Datetime\DateTimePlus::nonexistent()');
+ }
+ $date = new DateTimePlus('now', 'Australia/Sydney');
+ $date->setTimezone(new \DateTimeZone('America/New_York'))->nonexistent();
+ }
+
+ /**
+ * @covers ::getPhpDateTime
+ */
+ public function testGetPhpDateTime() {
+ $new_york = new \DateTimeZone('America/New_York');
+ $berlin = new \DateTimeZone('Europe/Berlin');
+
+ // Test retrieving a cloned copy of the wrapped \DateTime object, and that
+ // altering it does not change the DateTimePlus object.
+ $datetimeplus = DateTimePlus::createFromFormat('Y-m-d H:i:s', '2017-07-13 22:40:00', $new_york, ['langcode' => 'en']);
+ $this->assertEquals(1500000000, $datetimeplus->getTimestamp());
+ $this->assertEquals('America/New_York', $datetimeplus->getTimezone()->getName());
+
+ $datetime = $datetimeplus->getPhpDateTime();
+ $this->assertInstanceOf('DateTime', $datetime);
+ $this->assertEquals(1500000000, $datetime->getTimestamp());
+ $this->assertEquals('America/New_York', $datetime->getTimezone()->getName());
+
+ $datetime->setTimestamp(1400000000)->setTimezone($berlin);
+ $this->assertEquals(1400000000, $datetime->getTimestamp());
+ $this->assertEquals('Europe/Berlin', $datetime->getTimezone()->getName());
+ $this->assertEquals(1500000000, $datetimeplus->getTimestamp());
+ $this->assertEquals('America/New_York', $datetimeplus->getTimezone()->getName());
+ }
+
}