diff --git a/core/includes/common.inc b/core/includes/common.inc
index 9601c76..af57937 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -1833,41 +1833,65 @@ function format_size($size, $langcode = NULL) {
 /**
  * Formats a time interval with the requested granularity.
  *
- * @param $interval
+ * @param number $interval
  *   The length of the interval in seconds.
- * @param $granularity
+ * @param number $granularity
  *   How many different units to display in the string.
- * @param $langcode
+ * @param text $langcode
  *   Optional language code to translate to a language other than
  *   what is used to display the page.
  *
- * @return
+ * @return string
  *   A translated string representation of the interval.
  */
 function format_interval($interval, $granularity = 2, $langcode = NULL) {
+  // Prepare variables.
+  $date_format = DateTime::ISO8601;
+  $now = time();
+  // Add 'ago' to past intervals.
+  $append = $interval < 0 ? ' ago' : '';
+  // Create a default response of 0 seconds.
+  $default = t("0 sec$append", array(), array('langcode' => $langcode));
+
+  // Create the current date's components and $interval's objects.
+  $dt_now = new DateTime(date($date_format, $now));
+  $dt_then = new DateTime(date($date_format, $now + abs((int) $interval)));
+  if ($dt_now === FALSE || $dt_then === FALSE) {
+    // If we can't parse the date then return the default.
+    return $default;
+  }
+
+  // What is the interval?
+  $dt_diff = $dt_now->diff($dt_then);
   $units = array(
-    '1 year|@count years' => 31536000,
-    '1 month|@count months' => 2592000,
-    '1 week|@count weeks' => 604800,
-    '1 day|@count days' => 86400,
-    '1 hour|@count hours' => 3600,
-    '1 min|@count min' => 60,
-    '1 sec|@count sec' => 1
+    '1 year|@count years' => $dt_diff->y,
+    '1 month|@count months' => $dt_diff->m,
+    '1 week|@count weeks' => 0,
+    '1 day|@count days' => $dt_diff->d,
+    '1 hour|@count hours' => $dt_diff->h,
+    '1 min|@count min' => $dt_diff->i,
+    '1 sec|@count sec' => $dt_diff->s,
   );
-  $output = '';
+  // Week is now a special case.
+  $units['1 week|@count weeks'] = floor($units['1 day|@count days'] / 7);
+  $units['1 day|@count days'] = $units['1 day|@count days'] % 7;
+
+  // Produce the output based on the granularity.
+  $output_set = array();
   foreach ($units as $key => $value) {
     $key = explode('|', $key);
-    if ($interval >= $value) {
-      $output .= ($output ? ' ' : '') . format_plural(floor($interval / $value), $key[0], $key[1], array(), array('langcode' => $langcode));
-      $interval %= $value;
+    if ($value > 0) {
+      $output_set[] = format_plural($value, $key[0], $key[1], array(), array('langcode' => $langcode));
       $granularity--;
-    }
-
-    if ($granularity == 0) {
-      break;
+      if ($granularity == 0) {
+        break;
+      }
     }
   }
-  return $output ? $output : t('0 sec', array(), array('langcode' => $langcode));
+  $output = empty($output_set) ? $default : implode(' ', $output_set) . $append;
+
+  // Return the pretty interval.
+  return $output;
 }
 
 /**
