Index: date_api.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/date/date_api.module,v
retrieving revision 1.64.2.5.2.66
diff -u -r1.64.2.5.2.66 date_api.module
--- date_api.module	15 Feb 2009 11:11:06 -0000	1.64.2.5.2.66
+++ date_api.module	16 Feb 2009 19:52:10 -0000
@@ -588,48 +588,67 @@
 }
 
 /**
- * A version of the t() function for date parts that need translation.
- *
- * Run this over results of functions which do no translation of
- * month and day names, like date() and date_format().
- *
+ * A function to translate ambiguous short date strings.
+ * 
+ * Example: Pass in 'Monday', 'day_abbr' and get the translated 
+ * abbreviation for Monday.
+ * 
  * @param string $string
+ * @param string $context
+ * @param int $langcode
  * @return translated value of the string
  */
-function date_t($string) {
-  static $replace;
-  if (empty($replace)) {
-    $replace = array();
-    // Translate the whole name first, then look for abbreviations.
-    $untranslated = date_month_names_untranslated();
-    foreach (date_month_names_translated() as $delta => $month) {
-      $replace[$untranslated[$delta]] = $month;
-      $replace[drupal_substr($untranslated[$delta], 0, 3)] = drupal_substr($month, 0, 3);
-    }
-    $untranslated = date_week_days_untranslated();
-    foreach (date_week_days_translated() as $delta => $day) {
-      $replace[$untranslated[$delta]] = $day;
-      $replace[drupal_substr($untranslated[$delta], 0, 3)] = drupal_substr($day, 0, 3);
-    }
+function date_t($string, $context, $langcode = NULL) {
+  static $replace = array();
+  
+  if (empty($replace[$langcode])) {
+    // The function to create the date string arrays is kept separate
+    // so those arrays can be directly accessed by other functions.
+    date_t_strings($replace, $langcode);
+  }
+  switch ($context) {
+    case 'day_name':
+    case 'day_abbr':
+    case 'day_abbr1':
+    case 'day_abbr2':  
+      $untranslated = array_flip(date_week_days_untranslated());
+      $pos = $untranslated[$string];
+      break;
+    case 'month_name':
+    case 'month_abbr':
+      $untranslated = array_flip(date_month_names_untranslated());
+      $pos = $untranslated[$string];
+      break;  
+    case 'ampm':
+    case 'AMPM':
+      $pos = $string == 'am' || $string == 'AM' ? 0 : 1;
+      break;
+    case 'datetime':
+      $untranslated = array('year', 'month', 'day', 'week', 'hour', 'minute', 'second');  
+      $pos = $untranslated[$string];
+      break;
   }
-  return strtr($string, $replace);
+  return $replace[$langcode][$context][$pos];
 }
 
 /**
- * An override for interval formatting that adds past and future context
- *
- * @param DateTime $date
- * @param integer $granularity
- * @return formatted string
+ * Construct translation arrays from pipe-delimited strings.
+ * 
+ * Combining these strings into a single t() gives them the context needed
+ * for better translation.
  */
-function date_format_interval($date, $granularity = 2) {
-  $interval = time() - date_format($date, 'U');
-  if($interval > 0 ) {
-    return t('!time ago', array('!time' => format_interval($interval, $granularity)));
-  } 
-  else {
-    return format_interval(abs($interval), $granularity);
-  }
+function date_t_strings(&$replace, $langcode) {
+  $replace[$langcode]['day_name'] = explode('|', trim(t('!day-name Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday', array('!day-name' => '')), $langcode));
+  $replace[$langcode]['day_abbr'] = explode('|', trim(t('!day-abbreviation Mon|Tue|Wed|Thu|Fri|Sat|Sun', array('!day-abbreviation' => '')), $langcode));
+  $replace[$langcode]['day_abbr1'] = explode('|', trim(t('!day-abbreviation M|T|W|T|F|S|S', array('!day-abbreviation' => '')), $langcode));
+  $replace[$langcode]['day_abbr2'] = explode('|', trim(t('!day-abbreviation MO|TU|WE|TH|FR|SA|SU', array('!day-abbreviation' => '')), $langcode));
+  $replace[$langcode]['ampm'] = explode('|', trim(t('!ampm-abbreviation am|pm', array('!ampm-abbreviation' => '')), $langcode));
+  $replace[$langcode]['AMPM'] = explode('|', trim(t('!AMPM-abbreviation AM|PM', array('!AMPM-abbreviation' => '')), $langcode));
+  $replace[$langcode]['datetime'] = explode('|', trim(t('!datetime year|month|day|week|hour|minute|second', array('!datetime' => '')), $langcode));
+  
+  // These start with a pipe so the January value will be in position 1 instead of position 0.
+  $replace[$langcode]['month_name'] = explode('|', trim(t('!month-name |January|February|March|April|May|June|July|August|September|October|November|December', array('!month-name' => '')), $langcode));
+  $replace[$langcode]['month_abbr'] = explode('|', trim(t('!month-abbreviation |Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec', array('!month-abbreviation' => '')), $langcode));
 }
 
 /**
@@ -650,8 +669,8 @@
  * @return
  *   A translated date string in the requested format.
  */
-function date_format_date($object, $type = 'medium', $format = '') {
-  if (empty($object)) {
+function date_format_date($date, $type = 'medium', $format = '', $langcode = NULL) {
+  if (empty($date)) {
     return '';
   }
   switch ($type) {
@@ -670,7 +689,79 @@
     default:
       $format = variable_get('date_format_medium', 'D, m/d/Y - H:i');
   }
-  return date_t(date_format($object, $format));
+  $max = strlen($format);
+  $datestring = '';
+  for ($i = 0; $i < $max; $i++) {
+    $c = $format[$i];
+    switch ($c) {
+      // Use date_t() for ambiguous short strings that need translation.
+      // We send long day and month names to date_t(), along with context.
+      case 'l':
+        $datestring .= date_t(date_format($object, 'l'), 'day_name', $langcode);
+        break;
+      case 'D':
+        $datestring .= date_t(date_format($object, 'l'), 'day_abbr', $langcode);
+        break;
+      case 'F':
+        $datestring .= date_t(date_format($date, 'F'), 'month_name', $langcode);
+        break;  
+      case 'M':
+        $datestring .= date_t(date_format($date, 'F'), 'month_abbr', $langcode);
+        break;  
+      case 'A':
+        $datestring .= date_t(date_format($date, 'A'), 'AMPM', $langcode);
+        break;  
+      case 'a':
+        $datestring .= date_t(date_format($date, 'a'), 'ampm', $langcode);
+        break;  
+      // The timezone name translations can use t().  
+      case 'e':
+      case 'T':
+        $datestring .= t($c);
+        break;
+      // Remaining date parts need no translation.
+      case 'O':
+        $datestring .= sprintf('%s%02d%02d', (date_offset_get($date) < 0 ? '-' : '+'), abs(date_offset_get($date) / 3600), abs(date_offset_get($date) % 3600) / 60);
+        break;
+      case 'P':
+        $datestring .= sprintf('%s%02d:%02d', (date_offset_get($date) < 0 ? '-' : '+'), abs(date_offset_get($date) / 3600), abs(date_offset_get($date) % 3600) / 60);
+        break;
+      case 'Z':
+        $datestring .= date_offset_get($date);
+        break;              
+      case '\\':
+        $date .= $format[++$i];
+        break;
+      default:
+        if (strpos('BdgGhHiIjLmnsStTUwWYyz', $c) !== FALSE) {
+          $datestring .= date_format($date, $c);
+        }
+        else if ($c == 'r') {
+          $datestring .= format_date($date, 'custom', 'D, d M Y H:i:s O', $langcode);
+        }
+        else {
+          $datestring .= $c;
+        }
+    }
+  }
+  return $datestring;
+}
+
+/**
+ * An override for interval formatting that adds past and future context
+ *
+ * @param DateTime $date
+ * @param integer $granularity
+ * @return formatted string
+ */
+function date_format_interval($date, $granularity = 2) {
+  $interval = time() - date_format($date, 'U');
+  if($interval > 0 ) {
+    return t('!time ago', array('!time' => format_interval($interval, $granularity)));
+  } 
+  else {
+    return format_interval(abs($interval), $granularity);
+  }
 }
 
 /**

