diff --git a/date_api/date_api.module b/date_api/date_api.module index ca80f919f..1285b480f 100644 --- a/date_api/date_api.module +++ b/date_api/date_api.module @@ -1934,7 +1934,7 @@ function date_format_interval($date, $granularity = 2, $display_ago = TRUE) { * A translated string representation of the interval. */ function _date_format_interval($start_date, $end_date, $granularity = 2) { - $diff = $end_date->diff($start_date); + $diff = $start_date->diff($end_date); // As DateTime doesn't support weeks, calculate them and set the remaining // days. diff --git a/date_api/tests/DateApiTestCase.test b/date_api/tests/DateApiTestCase.test index 7f6bb5b65..789d96aae 100644 --- a/date_api/tests/DateApiTestCase.test +++ b/date_api/tests/DateApiTestCase.test @@ -464,6 +464,82 @@ class DateApiTestCase extends DrupalWebTestCase { $this->assertEqual('1980-01-01', $obj->format('Y-m-d')); } + /** + * Test the date_format_interval() function. + */ + public function testDateInterval() { + // Return values expected from date_format_interval(), keyed by input to + // strtotime(). + $expected_intervals = array( + // Any interval that contains fractions of a day (e.g. 1 hour) will fail + // if the current time is that interval before midnight (e.g. 23:00:00). + // This is due to the constructor of DateObject considering any date with + // a time of 00:00:00 as "dateOnly", resulting in a "1 day" interval + // instead of "1 hour" as the times are ignored. + '+ 5 min' => '5 min', + '+ 1 hour' => '1 hour', + '+ 2 hours' => '2 hours', + '+ 1 day' => '1 day', + '+ 1 week' => '1 week', + '+ 1 week 3 days' => '1 week 3 days', + '+ 1 week 5 days' => '1 week 5 days', + '+ 1 week 6 days' => '1 week 6 days', + '+ 2 weeks' => '2 weeks', + '+ 2 weeks 1 day' => '2 weeks 1 day', + '+ 2 weeks 2 days' => '2 weeks 2 days', + '+ 1 month' => '1 month', + '+ 1 month 1 week 1 day' => '1 month 1 week 1 day', + '+ 1 month 1 week 2 days' => '1 month 1 week 2 days', + '+ 1 month 1 week 6 days' => '1 month 1 week 6 days', + '+ 1 month 2 weeks 1 day' => '1 month 2 weeks 1 day', + '+ 1 month 2 weeks 2 days' => '1 month 2 weeks 2 days', + '+ 1 month 3 weeks 6 days' => '1 month 3 weeks 6 days', + '+ 2 months' => '2 months', + '+ 3 months' => '3 months', + '+ 11 months' => '11 months', + '+ 12 months' => '1 year', + '+ 3 months 3 days' => '3 months 3 days', + '+ 1 year' => '1 year', + '+ 1 year 1 month 1 week 1 day' => '1 year 1 month 1 week 1 day', + '+ 1 year 2 months 3 weeks 4 days 5 hours 6 min 7 sec' => '1 year 2 months 3 weeks 4 days 5 hours 6 min 7 sec', + '+ 3 years 3 months 3 weeks 3 days 3 hours 3 min 3 sec' => '3 years 3 months 3 weeks 3 days 3 hours 3 min 3 sec', + '+ 100 years' => '100 years', + '- 1 hour' => '1 hour ago', + '- 1 day' => '1 day ago', + '- 1 week' => '1 week ago', + '- 2 weeks' => '2 weeks ago', + '- 1 month' => '1 month ago', + '- 2 months' => '2 months ago', + '- 1 year' => '1 year ago', + '- 100 years' => '100 years ago', + ); + + // Change timezones used by PHP and Drupal functions to UTC so we don't have + // to deal with daylight savings time offsets that occur if intervals + // include a DST change. + $old_timezone_php = date_default_timezone_get(); + $old_timezone_drupal = variable_get('date_default_timezone'); + variable_set('date_default_timezone', 'UTC'); + date_default_timezone_set('UTC'); + + foreach ($expected_intervals as $input => $expected) { + // Use REQUEST_TIME like date_format_interval() as time() could be some + // seconds off. + $end_date = new DateObject($timestamp = strtotime($input, REQUEST_TIME)); + $formatted = date_format_interval($end_date, 7); + + // Start and end of interval formatted for output. + $now = (new DateObject(REQUEST_TIME))->format(DateTimeInterface::ATOM); + $end = $end_date->format(DateTimeInterface::ATOM); + + $this->assertEqual($expected, $formatted, "Test formatted interval now/$now $input (= $end): should be '$expected', found '$formatted'."); + } + + // Reset timezones to previous values. + date_default_timezone_set($old_timezone_php); + variable_set('date_default_timezone', $old_timezone_drupal); + } + /** * Tear down tests. */