diff --git a/core/lib/Drupal/Component/Datetime/DateTimePlus.php b/core/lib/Drupal/Component/Datetime/DateTimePlus.php index b00124b..3af5156 100644 --- a/core/lib/Drupal/Component/Datetime/DateTimePlus.php +++ b/core/lib/Drupal/Component/Datetime/DateTimePlus.php @@ -105,6 +105,84 @@ class DateTimePlus extends \DateTime { */ protected $errors = array(); + static $intlExtentionExists = NULL; + + /** + * Creates a date object from an input date object. + */ + static public function createFromDateTime(\DateTime $datetime, $settings = array()) { + return new static($datetime->format(static::FORMAT), $datetime->getTimezone(), $settings); + } + + /** + * Creates a date object from an array of date parts. + * + * Converts the input value into an ISO date, forcing a full ISO + * date even if some values are missing. + */ + static public function createFromArray(array $date_parts, $timezone = NULL, $settings = array()) { + $date_parts = static::prepareArray($date_parts, TRUE); + if (static::checkArray($date_parts)) { + // Even with validation, we can end up with a value that the + // parent class won't handle, like a year outside the range + // of -9999 to 9999, which will pass checkdate() but + // fail to construct a date object. + $iso_date = static::arrayToISO($date_parts); + return new static($iso_date, $timezone, $settings); + } + else { + throw new \Exception('The array contains invalid values.'); + } + } + + /** + * Creates a date object from timestamp input. + * + * The timezone of a timestamp is always UTC. The timezone for a + * timestamp indicates the timezone used by the format() method. + */ + static public function createFromTimestamp($timestamp, $timezone = NULL, $settings = array()) { + $datetime = new static('', $timezone, $settings); + $datetime->setTimestamp($timestamp); + return $datetime; + } + + /** + * Creates a date object from an input format. + */ + static public function createFromFormat($format, $time, $timezone = NULL, $settings = array()) { + if (!isset($settings['validate_format'])) { + $settings['validate_format'] = TRUE; + } + + // Tries to create a date from the format and use it if possible. + // A regular try/catch won't work right here, if the value is + // invalid it doesn't return an exception. + $datetimeplus = new static('', $timezone, $settings); + + + $date = \DateTime::createFromFormat($format, $time, $datetimeplus->getTimezone()); + if (!$date instanceOf \DateTime) { + throw new \Exception('The date cannot be created from a format.'); + } + else { + $datetimeplus->setTimestamp($date->getTimestamp()); + $datetimeplus->setTimezone($date->getTimezone()); + + // The createFromFormat function is forgiving, it might + // create a date that is not exactly a match for the provided + // value, so test for that. For instance, an input value of + // '11' using a format of Y (4 digits) gets created as + // '0011' instead of '2011'. + // Use the parent::format() because we do not want to use + // the IntlDateFormatter here. + if ($settings['validate_format'] && $date->format($format) != $time) { + throw new \Exception('The created date does not match the input value.'); + } + } + return $datetimeplus; + } + /** * Constructs a date object set to a requested date and timezone. * @@ -115,12 +193,6 @@ class DateTimePlus extends \DateTime { * @param mixed $timezone * PHP DateTimeZone object, string or NULL allowed. * Defaults to NULL. - * @param string $format - * PHP date() type format for parsing the input. This is recommended - * for specialized input with a known format. If provided the - * date will be created using the createFromFormat() method. - * Defaults to NULL. - * @see http://us3.php.net/manual/en/datetime.createfromformat.php * @param array $settings * - validate_format: (optional) Boolean choice to validate the * created date using the input format. The format used in @@ -142,66 +214,36 @@ class DateTimePlus extends \DateTime { * - debug: (optional) Boolean choice to leave debug values in the * date object for debugging purposes. Defaults to FALSE. */ - public function __construct($time = 'now', $timezone = NULL, $format = NULL, $settings = array()) { + public function __construct($time = 'now', $timezone = NULL, $settings = array()) { // Unpack settings. - $this->validateFormat = !empty($settings['validate_format']) ? $settings['validate_format'] : TRUE; $this->langcode = !empty($settings['langcode']) ? $settings['langcode'] : NULL; $this->country = !empty($settings['country']) ? $settings['country'] : NULL; $this->calendar = !empty($settings['calendar']) ? $settings['calendar'] : static::CALENDAR; - // Store the original input so it is available for validation. - $this->inputTimeRaw = $time; - $this->inputTimeZoneRaw = $timezone; - $this->inputFormatRaw = $format; - // Massage the input values as necessary. - $this->prepareTime($time); - $this->prepareTimezone($timezone); - $this->prepareFormat($format); - - // Create a date as a clone of an input DateTime object. - if ($this->inputIsObject()) { - $this->constructFromObject(); - } - - // Create date from array of date parts. - elseif ($this->inputIsArray()) { - $this->constructFromArray(); - } + $prepared_time = $this->prepareTime($time); + $prepared_timezone = $this->prepareTimezone($timezone); - // Create a date from a Unix timestamp. - elseif ($this->inputIsTimestamp()) { - $this->constructFromTimestamp(); - } + try { + if (!empty($prepared_time)) { + $test = date_parse($prepared_time); + if (!empty($test['errors'])) { + $this->errors[] = $test['errors']; + } + } - // Create a date from a time string and an expected format. - elseif ($this->inputIsFormat()) { - $this->constructFromFormat(); + if (empty($this->errors)) { + parent::__construct($prepared_time, $prepared_timezone); + } } - - // Create a date from any other input. - else { - $this->constructFallback(); + catch (\Exception $e) { + $this->errors[] = $e->getMessage(); } // Clean up the error messages. $this->checkErrors(); $this->errors = array_unique($this->errors); - - // Now that we've validated the input, clean up the extra values. - if (empty($settings['debug'])) { - unset( - $this->inputTimeRaw, - $this->inputTimeAdjusted, - $this->inputTimeZoneRaw, - $this->inputTimeZoneAdjusted, - $this->inputFormatRaw, - $this->inputFormatAdjusted, - $this->validateFormat - ); - } - } /** @@ -228,7 +270,7 @@ public function __toString() { * or an array of date parts. */ protected function prepareTime($time) { - $this->inputTimeAdjusted = $time; + return $time; } /** @@ -247,12 +289,6 @@ protected function prepareTimezone($timezone) { $timezone_adjusted = $timezone; } - // When the passed-in time is a DateTime object with its own - // timezone, try to use the date's timezone. - elseif (empty($timezone) && $this->inputTimeAdjusted instanceOf \DateTime) { - $timezone_adjusted = $this->inputTimeAdjusted->getTimezone(); - } - // Allow string timezone input, and create a timezone from it. elseif (!empty($timezone) && is_string($timezone)) { $timezone_adjusted = new \DateTimeZone($timezone); @@ -267,7 +303,7 @@ protected function prepareTimezone($timezone) { } // We are finally certain that we have a usable timezone. - $this->inputTimeZoneAdjusted = $timezone_adjusted; + return $timezone_adjusted; } /** @@ -280,179 +316,10 @@ protected function prepareTimezone($timezone) { * A PHP format string. */ protected function prepareFormat($format) { - $this->inputFormatAdjusted = $format; + return $format; } - /** - * Checks whether input is a DateTime object. - * - * @return boolean - * TRUE if the input time is a DateTime object. - */ - public function inputIsObject() { - return $this->inputTimeAdjusted instanceOf \DateTime; - } - /** - * Creates a date object from an input date object. - */ - protected function constructFromObject() { - try { - $this->inputTimeAdjusted = $this->inputTimeAdjusted->format(static::FORMAT); - parent::__construct($this->inputTimeAdjusted, $this->inputTimeZoneAdjusted); - } - catch (\Exception $e) { - $this->errors[] = $e->getMessage(); - } - } - - /** - * Checks whether input time seems to be a timestamp. - * - * Providing an input format will prevent ISO values without separators - * from being mis-interpreted as timestamps. Providing a format can also - * avoid interpreting a value like '2010' with a format of 'Y' as a - * timestamp. The 'U' format indicates this is a timestamp. - * - * @return boolean - * TRUE if the input time is a timestamp. - */ - public function inputIsTimestamp() { - return is_numeric($this->inputTimeAdjusted) && (empty($this->inputFormatAdjusted) || $this->inputFormatAdjusted == 'U'); - } - - /** - * Creates a date object from timestamp input. - * - * The timezone of a timestamp is always UTC. The timezone for a - * timestamp indicates the timezone used by the format() method. - */ - protected function constructFromTimestamp() { - try { - parent::__construct('', $this->inputTimeZoneAdjusted); - $this->setTimestamp($this->inputTimeAdjusted); - } - catch (\Exception $e) { - $this->errors[] = $e->getMessage(); - } - } - - /** - * Checks if input is an array of date parts. - * - * @return boolean - * TRUE if the input time is a DateTime object. - */ - public function inputIsArray() { - return is_array($this->inputTimeAdjusted); - } - - /** - * Creates a date object from an array of date parts. - * - * Converts the input value into an ISO date, forcing a full ISO - * date even if some values are missing. - */ - protected function constructFromArray() { - try { - parent::__construct('', $this->inputTimeZoneAdjusted); - $this->inputTimeAdjusted = static::prepareArray($this->inputTimeAdjusted, TRUE); - if (static::checkArray($this->inputTimeAdjusted)) { - // Even with validation, we can end up with a value that the - // parent class won't handle, like a year outside the range - // of -9999 to 9999, which will pass checkdate() but - // fail to construct a date object. - $this->inputTimeAdjusted = static::arrayToISO($this->inputTimeAdjusted); - parent::__construct($this->inputTimeAdjusted, $this->inputTimeZoneAdjusted); - } - else { - throw new \Exception('The array contains invalid values.'); - } - } - catch (\Exception $e) { - $this->errors[] = $e->getMessage(); - } - } - - /** - * Checks if input is a string with an expected format. - * - * @return boolean - * TRUE if the input time is a string with an expected format. - */ - public function inputIsFormat() { - return is_string($this->inputTimeAdjusted) && !empty($this->inputFormatAdjusted); - } - - /** - * Creates a date object from an input format. - */ - protected function constructFromFormat() { - // Tries to create a date from the format and use it if possible. - // A regular try/catch won't work right here, if the value is - // invalid it doesn't return an exception. - try { - parent::__construct('', $this->inputTimeZoneAdjusted); - $date = parent::createFromFormat($this->inputFormatAdjusted, $this->inputTimeAdjusted, $this->inputTimeZoneAdjusted); - if (!$date instanceOf \DateTime) { - throw new \Exception('The date cannot be created from a format.'); - } - else { - $this->setTimestamp($date->getTimestamp()); - $this->setTimezone($date->getTimezone()); - - try { - // The createFromFormat function is forgiving, it might - // create a date that is not exactly a match for the provided - // value, so test for that. For instance, an input value of - // '11' using a format of Y (4 digits) gets created as - // '0011' instead of '2011'. - // Use the parent::format() because we do not want to use - // the IntlDateFormatter here. - if ($this->validateFormat && parent::format($this->inputFormatAdjusted) != $this->inputTimeRaw) { - throw new \Exception('The created date does not match the input value.'); - } - } - catch (\Exception $e) { - $this->errors[] = $e->getMessage(); - } - } - } - catch (\Exception $e) { - $this->errors[] = $e->getMessage(); - } - } - - /** - * Creates a date when none of the other methods are appropriate. - * - * Fallback construction for values that don't match any of the - * other patterns. Lets the parent dateTime attempt to turn this string - * into a valid date. - */ - protected function constructFallback() { - - try { - // One last test for invalid input before we try to construct - // a date. If the input contains totally bogus information - // it will blow up badly if we pass it to the constructor. - // The date_parse() function will tell us if the input - // makes sense. - if (!empty($this->inputTimeAdjusted)) { - $test = date_parse($this->inputTimeAdjusted); - if (!empty($test['errors'])) { - $this->errors[] = $test['errors']; - } - } - - if (empty($this->errors)) { - parent::__construct($this->inputTimeAdjusted, $this->inputTimeZoneAdjusted); - } - } - catch (\Exception $e) { - $this->errors[] = $e->getMessage(); - } - } /** * Examines getLastErrors() to see what errors to report. @@ -655,7 +522,14 @@ public function canUseIntl($calendar = NULL, $langcode = NULL, $country = NULL) $country = !empty($country) ? $country : $this->country; $calendar = !empty($calendar) ? $calendar : $this->calendar; - return class_exists('IntlDateFormatter') && !empty($calendar) && !empty($langcode) && !empty($country); + return $this->intlDateFormatterExists() && !empty($calendar) && !empty($langcode) && !empty($country); + } + + public static function intlDateFormatterExists() { + if (static::$intlExtentionExists === NULL) { + static::$intlExtentionExists = class_exists('IntlDateFormatter'); + } + return static::$intlExtentionExists; } /** diff --git a/core/lib/Drupal/Core/Datetime/Date.php b/core/lib/Drupal/Core/Datetime/Date.php index 5567331..3378593 100644 --- a/core/lib/Drupal/Core/Datetime/Date.php +++ b/core/lib/Drupal/Core/Datetime/Date.php @@ -39,6 +39,9 @@ class Date { */ protected $languageManager; + protected $country = NULL; + protected $dateFormats = array(); + /** * Constructs a Date object. * @@ -96,20 +99,26 @@ public function format($timestamp, $type = 'medium', $format = '', $timezone = N $langcode = $this->languageManager->getLanguage(Language::TYPE_INTERFACE)->id; } + $settings['country'] = !empty($settings['country']) ? $settings['country'] : $this->country(); + // Create a DrupalDateTime object from the timestamp and timezone. - $date = new DrupalDateTime($timestamp, $this->timezones[$timezone]); + $create_settings = array( + 'langcode' => $langcode, + 'country' => $settings['country'] + ); + $date = DrupalDateTime::createFromTimestamp($timestamp, $this->timezones[$timezone], $create_settings); // Find the appropriate format type. $key = $date->canUseIntl() ? DrupalDateTime::INTL : DrupalDateTime::PHP; // If we have a non-custom date format use the provided date format pattern. - if ($date_format = $this->dateFormatStorage->load($type)) { + if ($date_format = $this->dateFormat($type)) { $format = $date_format->getPattern($key); } // Fall back to medium if a format was not found. if (empty($format)) { - $format = $this->dateFormatStorage->load('fallback')->getPattern($key); + $format = $this->dateFormat('fallback')->getPattern($key); } // Call $date->format(). @@ -120,4 +129,18 @@ public function format($timestamp, $type = 'medium', $format = '', $timezone = N return Xss::filter($date->format($format, $settings)); } + protected function dateFormat($format) { + if (!isset($this->dateFormats[$format])) { + $this->dateFormats[$format] = $this->dateFormatStorage->load($format); + } + return $this->dateFormats[$format]; + } + + protected function country() { + if ($this->country === NULL) { + $this->country = config('system.date')->get('country.default'); + } + return $this->country; + } + } diff --git a/core/lib/Drupal/Core/Datetime/DrupalDateTime.php b/core/lib/Drupal/Core/Datetime/DrupalDateTime.php index 0a283ac..18545b4 100644 --- a/core/lib/Drupal/Core/Datetime/DrupalDateTime.php +++ b/core/lib/Drupal/Core/Datetime/DrupalDateTime.php @@ -29,13 +29,6 @@ class DrupalDateTime extends DateTimePlus { * @param mixed $timezone * PHP DateTimeZone object, string or NULL allowed. * Defaults to NULL. - * @param string $format - * PHP date() type format for parsing the input. This is recommended - * to use things like negative years, which php's parser fails on, or - * any other specialized input with a known format. If provided the - * date will be created using the createFromFormat() method. - * Defaults to NULL. - * @see http://us3.php.net/manual/en/datetime.createfromformat.php * @param array $settings * - validate_format: (optional) Boolean choice to validate the * created date using the input format. The format used in @@ -57,14 +50,18 @@ class DrupalDateTime extends DateTimePlus { * - debug: (optional) Boolean choice to leave debug values in the * date object for debugging purposes. Defaults to FALSE. */ - public function __construct($time = 'now', $timezone = NULL, $format = NULL, $settings = array()) { - + public function __construct($time = 'now', $timezone = NULL, $settings = array()) { // We can set the langcode and country using Drupal values. - $settings['langcode'] = !empty($settings['langcode']) ? $settings['langcode'] : language(Language::TYPE_INTERFACE)->id; - $settings['country'] = !empty($settings['country']) ? $settings['country'] : config('system.date')->get('country.default'); + if (!isset($settings['langcode'])) { + $settings['langcode'] = language(Language::TYPE_INTERFACE)->id; + } + + if (!isset($settings['country'])) { + $settings['country'] = config('system.date')->get('country.default'); + } // Instantiate the parent class. - parent::__construct($time, $timezone, $format, $settings); + parent::__construct($time, $timezone, $settings); } @@ -79,7 +76,7 @@ protected function prepareTimezone($timezone) { if (empty($timezone) && !empty($user_timezone)) { $timezone = $user_timezone; } - parent::prepareTimezone($timezone); + return parent::prepareTimezone($timezone); } /** diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/DateTimeIso8601.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/DateTimeIso8601.php index 906b4eb..629d675 100644 --- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/DateTimeIso8601.php +++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/DateTimeIso8601.php @@ -29,7 +29,13 @@ class DateTimeIso8601 extends String implements DateTimeInterface { */ public function getDateTime() { if ($this->value) { - return new DrupalDateTime($this->value); + if (is_array($this->value)) { + $datetime = DrupalDateTime::createFromArray($this->value); + } + else { + $datetime = new DrupalDateTime($this->value); + } + return $datetime; } } diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module index fdee1a6..15d02e4 100644 --- a/core/modules/datetime/datetime.module +++ b/core/modules/datetime/datetime.module @@ -249,9 +249,14 @@ function datetime_field_load($entity_type, $entities, $field, $instances, $langc $value = isset($item['value']) ? $item['value'] : NULL; if (!empty($value)) { $storage_format = $field['settings']['datetime_type'] == 'date' ? DATETIME_DATE_STORAGE_FORMAT: DATETIME_DATETIME_STORAGE_FORMAT; - $date = new DrupalDateTime($value, DATETIME_STORAGE_TIMEZONE, $storage_format); - if ($date instanceOf DrupalDateTime && !$date->hasErrors()) { - $items[$id][$delta]['date'] = $date; + try { + $date = DrupalDateTime::createFromFormat($storage_format, $value, DATETIME_STORAGE_TIMEZONE); + if ($date instanceOf DrupalDateTime && !$date->hasErrors()) { + $items[$id][$delta]['date'] = $date; + } + } + catch (\Exception $e) { + // TODO: Handle this. } } } @@ -599,11 +604,17 @@ function form_type_datetime_value($element, $input = FALSE) { $time_input .= ':00'; } - $date = new DrupalDateTime(trim($date_input . ' ' . $time_input), $timezone, trim($date_format . ' ' . $time_format)); + try { + $date = DrupalDateTime::createFromFormat(trim($date_format . ' ' . $time_format), trim($date_input . ' ' . $time_input), $timezone); + } + catch (\Exception $e) { + $date = NULL; + } + $input = array( 'date' => $date_input, 'time' => $time_input, - 'object' => $date instanceOf DrupalDateTime && !$date->hasErrors() ? $date : NULL, + 'object' => $date, ); } else { @@ -928,7 +939,7 @@ function form_type_datelist_value($element, $input = FALSE, &$form_state = array unset($input['ampm']); } $timezone = !empty($element['#date_timezone']) ? $element['#date_timezone'] : NULL; - $date = new DrupalDateTime($input, $timezone); + $date = DrupalDateTime::createFromArray($input, $timezone); if ($date instanceOf DrupalDateTime && !$date->hasErrors()) { date_increment_round($date, $increment); } @@ -1136,5 +1147,5 @@ function datetime_form_node_form_alter(&$form, &$form_state, $form_id) { */ function datetime_node_prepare_form(NodeInterface $node, $form_display, $operation, array &$form_state) { // Prepare the 'Authored on' date to use datetime. - $node->date = new DrupalDateTime($node->created); + $node->date = DrupalDateTime::createFromTimestamp($node->created); } diff --git a/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php b/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php index f780877..ed5fc72 100644 --- a/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php +++ b/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php @@ -51,6 +51,28 @@ public function testDates($input, $timezone, $expected) { } /** + * Test creating dates from string and array input. + * + * @param mixed $input + * Input argument for DateTimePlus. + * @param string $timezone + * Timezone argument for DateTimePlus. + * @param string $expected + * Expected output from DateTimePlus::format(). + * + * @dataProvider providerTestDateArrays + */ + public function testDateArrays($input, $timezone, $expected) { + $date = DateTimePlus::createFromArray($input, $timezone); + $value = $date->format('c'); + + if (is_array($input)) { + $input = var_export($input, TRUE); + } + $this->assertEquals($expected, $value, sprintf("Test new DateTimePlus(%s, %s): should be %s, found %s.", $input, $timezone, $expected, $value)); + } + + /** * Test creating dates from timestamps, and manipulating timezones. * * @param mixed $input @@ -76,12 +98,25 @@ public function testDates($input, $timezone, $expected) { * - 'expected_transform_offset' - Expected output from * DateTimePlus::getOffset(), after timezone transform. * + * @dataProvider providerTestTimestamp + */ + public function testTimestamp($input, array $initial, array $transform) { + // Initialize a new date object. + $date = DateTimePlus::createFromTimestamp($input, $initial['timezone']); + $this->assertDateTimestamp($date, $input, $initial, $transform); + } + + /** * @dataProvider providerTestDateTimestamp */ public function testDateTimestamp($input, array $initial, array $transform) { // Initialize a new date object. $date = new DateTimePlus($input, $initial['timezone']); + $this->assertDateTimestamp($date, $input, $initial, $transform); + } + + public function assertDateTimestamp($date, $input, $initial, $transform) { // Check format. $value = $date->format($initial['format']); $this->assertEquals($initial['expected_date'], $value, sprintf("Test new DateTimePlus(%s, %s): should be %s, found %s.", $input, $initial['timezone'], $initial['expected_date'], $value)); @@ -126,7 +161,7 @@ public function testDateTimestamp($input, array $initial, array $transform) { * @dataProvider providerTestDateFormat */ public function testDateFormat($input, $timezone, $format, $format_date, $expected) { - $date = new DateTimePlus($input, $timezone, $format); + $date = DateTimePlus::createFromFormat($format, $input, $timezone); $value = $date->format($format_date); $this->assertEquals($expected, $value, sprintf("Test new DateTimePlus(%s, %s, %s): should be %s, found %s.", $input, $timezone, $format, $expected, $value)); } @@ -144,10 +179,10 @@ public function testDateFormat($input, $timezone, $format, $format_date, $expect * Message to print if no errors are thrown by the invalid dates. * * @dataProvider providerTestInvalidDates + * @expectedException \Exception */ public function testInvalidDates($input, $timezone, $format, $message) { - $date = new DateTimePlus($input, $timezone, $format); - $this->assertNotEquals(count($date->getErrors()), 0, $message); + $date = DateTimePlus::createFromFormat($format, $input, $timezone); } /** @@ -172,6 +207,31 @@ public function testDateTimezone($input, $timezone, $expected_timezone, $message } /** + * Test that DrupalDateTime can detect the right timezone to use. + * When specified or not. + * + * @param mixed $input + * Input argument for DateTimePlus. + * @param mixed $timezone + * Timezone argument for DateTimePlus. + * @param string $expected_timezone + * Expected timezone returned from DateTimePlus::getTimezone::getName(). + * @param string $message + * Message to print on test failure. + */ + public function testDateTimezoneWithDateTimeObject() { + // Create a date object with another date object. + $input = new DateTimePlus('now', 'Pacific/Midway'); + $timezone = NULL; + $expected_timezone = 'Pacific/Midway'; + $message = 'DateTimePlus uses the specified timezone if provided.'; + + $date = DateTimePlus::createFromDateTime($input, $timezone); + $timezone = $date->getTimezone()->getName(); + $this->assertEquals($timezone, $expected_timezone, $message); + } + + /** * Provide data for date tests. * * @return array @@ -195,7 +255,20 @@ public function providerTestDates() { array('2009-03-07 10:30', 'Australia/Canberra', '2009-03-07T10:30:00+11:00'), // Same during daylight savings time. array('2009-06-07 10:30', 'Australia/Canberra', '2009-06-07T10:30:00+10:00'), + ); + } + /** + * Provide data for date tests. + * + * @return array + * An array of arrays, each containing the input parameters for + * DateTimePlusTest::testDates(). + * + * @see DateTimePlusTest::testDates(). + */ + public function providerTestDateArrays() { + return array( // Array input. // Create date object from date array, date only. array(array('year' => 2010, 'month' => 2, 'day' => 28), 'America/Chicago', '2010-02-28T00:00:00-06:00'), @@ -259,6 +332,24 @@ public function providerTestInvalidDates() { array('0000-75-00T15:30:00', NULL, 'Y-m-d\TH:i:s', "0000-75-00T15:30:00 contains an invalid month and did not produce errors."), // Test for invalid year. array('11-08-01T15:30:00', NULL, 'Y-m-d\TH:i:s', "11-08-01T15:30:00 contains an invalid year and did not produce errors."), + + ); + } + + /** + * Provide data for testInvalidDates. + * + * @return array + * An array of arrays, each containing: + * - 'input' - Input for DateTimePlus. + * - 'timezone' - Timezone for DateTimePlus. + * - 'format' - Format for DateTimePlus. + * - 'message' - Message to display on failure. + * + * @see testInvalidDateArrays + */ + public function providerTestInvalidDateArrays() { + return array( // Test for invalid year from date array. 10000 as a year will // create an exception error in the PHP DateTime object. array(array('year' => 10000, 'month' => 7, 'day' => 8, 'hour' => 8, 'minute' => 0, 'second' => 0), 'America/Chicago', NULL, "array('year' => 10000, 'month' => 7, 'day' => 8, 'hour' => 8, 'minute' => 0, 'second' => 0) contains an invalid year and did not produce errors."), @@ -304,15 +395,15 @@ public function providerTestDateTimezone() { } /** - * Provide data for testDateTimestamp. + * Provide data for testTimestamp. * * @return array * An array of arrays, each containing the arguments required for - * self::testDateTimestamp(). + * self::testTimestamp(). * - * @see testDateTimestamp() + * @see testTimestamp() */ - public function providerTestDateTimestamp() { + public function providerTestTimestamp() { return array( // Create date object from a unix timestamp and display it in // local time. @@ -352,6 +443,20 @@ public function providerTestDateTimestamp() { 'expected_offset' => 0, ), ), + ); + } + + /** + * Provide data for testDateTimestamp. + * + * @return array + * An array of arrays, each containing the arguments required for + * self::testDateTimestamp(). + * + * @see testDateTimestamp() + */ + public function providerTestDateTimestamp() { + return array( // Create date object from datetime string in UTC, and convert // it to a local date. array(