diff --git a/date_api/theme/theme.inc b/date_api/theme/theme.inc
index 0a57ecd..61594ca 100644
--- a/date_api/theme/theme.inc
+++ b/date_api/theme/theme.inc
@@ -194,7 +194,7 @@ function theme_date_calendar_day($variables) {
 function theme_date_time_ago($variables) {
   $start_date = $variables['start_date'];
   $end_date = $variables['end_date'];
-  $use_end_date = isset($variables['use_end_date']) ? $variables['use_end_date'] : false;
+  $use_end_date = isset($variables['use_end_date']) ? $variables['use_end_date'] : FALSE;
   $interval = !empty($variables['interval']) ? $variables['interval'] : 2;
   $display = isset($variables['interval_display']) ? $variables['interval_display'] : 'time ago';
 
@@ -204,42 +204,94 @@ function theme_date_time_ago($variables) {
   }
 
   // We use the end date only when the option is checked.
-  if ($use_end_date){
-    $date = date_format($end_date, DATE_FORMAT_UNIX);
+  if ($use_end_date) {
+    $date = $end_date;
   }
   else {
-    $date = date_format($start_date, DATE_FORMAT_UNIX);
+    $date = $start_date;
   }
 
   // Time to compare dates to.
-
-  $now = date_format(date_now(), DATE_FORMAT_UNIX);
-
-  // Will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence).
-  $time_diff = $now - $date;
+  $now = date_create();
 
   // Uses the same options used by Views format_interval.
   switch ($display) {
     case 'raw time ago':
-      return format_interval($time_diff, $interval);
+      return format_date_interval($date, $now, $interval);
 
     case 'time ago':
-      return t('%time ago', array('%time' => format_interval($time_diff, $interval)));
+      return t('%time ago', array(
+        '%time' => format_date_interval($date, $now, $interval),
+      ));
 
     case 'raw time hence':
-      return format_interval(-$time_diff, $interval);
+      return format_date_interval($now, $date, $interval);
 
     case 'time hence':
-      return t('%time hence', array('%time' => format_interval(-$time_diff, $interval)));
+      return t('%time hence', array(
+        '%time' => format_date_interval($now, $date, $interval),
+      ));
 
     case 'raw time span':
-      return ($time_diff < 0 ? '-' : '') . format_interval(abs($time_diff), $interval);
+      if ($date < $now) {
+        $output = '-' . format_date_interval($now, $date, $interval);
+      }
+      else {
+        $output = '' . format_date_interval($date, $now, $interval);
+      }
+      return $output;
 
     case 'inverse time span':
-      return ($time_diff > 0 ? '-' : '') . format_interval(abs($time_diff), $interval);
+      if ($date < $now) {
+        $output = '' . format_date_interval($now, $date, $interval);
+      }
+      else {
+        $output = '-' . format_date_interval($date, $now, $interval);
+      }
+      return $output;
 
     case 'time span':
-      return t(($time_diff < 0 ? '%time hence' : '%time ago'), array('%time' => format_interval(abs($time_diff), $interval)));
+      if ($date < $now) {
+        $output = t('%time ago', array(
+          '%time' => format_date_interval($date, $now, $interval),
+        ));
+      }
+      else {
+        $output = t('%time hence', array(
+          '%time' => format_date_interval($now, $date, $interval),
+        ));
+      }
+      return $output;
+
+  }
+}
 
+/**
+ * Implementation of date alternative of core format_interval().
+ */
+function format_date_interval($start_date, $end_date, $granularity) {
+  $diff = $end_date->diff($start_date);
+  $units = array(
+    '1 year|@count years' => 'y',
+    '1 month|@count months' => 'm',
+    '1 day|@count days' => 'd',
+    '1 hour|@count hours' => 'h',
+    '1 min|@count min' => 'i',
+    '1 sec|@count sec' => 's',
+  );
+  $output = '';
+  if ($start_date < $end_date) {
+    foreach ($units as $key => $value) {
+      $key = explode('|', $key);
+      if ($diff->{$value}) {
+        $output .= ($output ? ' ' : '') . format_plural($diff->{$value}, $key[0], $key[1], array(), array('langcode' => NULL));
+        $granularity--;
+      }
+
+      if ($granularity == 0) {
+        break;
+      }
+    }
   }
+  return $output ? $output : t('0 sec', array(), array('langcode' => NULL));
 }
