diff --git a/modules/comment/comment.module b/modules/comment/comment.module
index 60a9ca4..589a578 100644
--- a/modules/comment/comment.module
+++ b/modules/comment/comment.module
@@ -1089,6 +1089,10 @@ function comment_links($comment, $node) {
  *   An array in the format expected by drupal_render().
  */
 function comment_view_multiple($comments, $node, $view_mode = 'full', $weight = 0, $langcode = NULL) {
+  if (!isset($langcode)) {
+    $langcode = $GLOBALS['language_content']->language;
+  }
+
   field_attach_prepare_view('comment', $comments, $view_mode, $langcode);
   entity_prepare_view('comment', $comments, $langcode);
 
diff --git a/modules/field/field.api.php b/modules/field/field.api.php
index fae598d..cab9874 100644
--- a/modules/field/field.api.php
+++ b/modules/field/field.api.php
@@ -355,8 +355,14 @@ function hook_field_load($entity_type, $entities, $field, $instances, $langcode,
  *   The language associated to $items.
  * @param $items
  *   $entity->{$field['field_name']}, or an empty array if unset.
- */
-function hook_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
+ * @param $requested_language
+ *   The language originally requested, it may be different from $langcode as a
+ *   field value for this language may not be available. In the case of
+ *   untranslatable fields $langcode will always be LANGUAGE_NONE, this value
+ *   can be used instead to provide a localized version of the current field,
+ *   e.g. a date formatted with the current locale settings.
+ */
+function hook_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $requested_language) {
   // Sample code from image.module: if there are no images specified at all,
   // use the default image.
   foreach ($entities as $id => $entity) {
@@ -961,6 +967,12 @@ function hook_field_formatter_info_alter(&$info) {
  *   Array of field values for the entities, keyed by entity ID.
  * @param $displays
  *   Array of display settings to use for each entity, keyed by entity ID.
+ * @param $requested_language
+ *   The language originally requested, it may be different from $langcode as a
+ *   field value for this language may not be available. In the case of
+ *   untranslatable fields $langcode will always be LANGUAGE_NONE, this value
+ *   can be used instead to provide a localized version of the current field,
+ *   e.g. a date formatted with the current locale settings.
  *
  * @return
  *   Changes or additions to field values are done by altering the $items
@@ -1026,12 +1038,18 @@ function hook_field_formatter_prepare_view($entity_type, $entities, $field, $ins
  *   definitions. The array notably contains the following keys and values;
  *   - type: The name of the formatter to use.
  *   - settings: The array of formatter settings.
+ * @param $requested_language
+ *   The language originally requested, it may be different from $langcode as a
+ *   field value for this language may not be available. In the case of
+ *   untranslatable fields $langcode will always be LANGUAGE_NONE, this value
+ *   can be used instead to provide a localized version of the current field,
+ *   e.g. a date formatted with the current locale settings.
  *
  * @return
  *   A renderable array for the $items, as an array of child elements keyed
  *   by numeric indexes starting from 0.
  */
-function hook_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
+function hook_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display, $requested_language) {
   $element = array();
   $settings = $display['settings'];
 
diff --git a/modules/field/field.attach.inc b/modules/field/field.attach.inc
index 4ca15f5..e4abd4b 100644
--- a/modules/field/field.attach.inc
+++ b/modules/field/field.attach.inc
@@ -1080,6 +1080,7 @@ function field_attach_delete_revision($entity_type, $entity) {
  *   is provided the current language is used.
  */
 function field_attach_prepare_view($entity_type, $entities, $view_mode, $langcode = NULL) {
+  $langcode = field_valid_language($langcode, FALSE);
   $options = array('language' => array());
 
   // To ensure hooks are only run once per entity, only process items without
@@ -1102,11 +1103,11 @@ function field_attach_prepare_view($entity_type, $entities, $view_mode, $langcod
 
   $null = NULL;
   // First let the field types do their preparation.
-  _field_invoke_multiple('prepare_view', $entity_type, $prepare, $null, $null, $options);
+  _field_invoke_multiple('prepare_view', $entity_type, $prepare, $null, $langcode, $options);
   // Then let the formatters do their own specific massaging.
   // field_default_prepare_view() takes care of dispatching to the correct
   // formatters according to the display settings for the view mode.
-  _field_invoke_multiple_default('prepare_view', $entity_type, $prepare, $view_mode, $null, $options);
+  _field_invoke_multiple_default('prepare_view', $entity_type, $prepare, $view_mode, $langcode, $options);
 }
 
 /**
@@ -1158,12 +1159,12 @@ function field_attach_prepare_view($entity_type, $entities, $view_mode, $langcod
 function field_attach_view($entity_type, $entity, $view_mode, $langcode = NULL) {
   // Determine the actual language to display for each field, given the
   // languages available in the field data.
+  $langcode = field_valid_language($langcode, FALSE);
   $display_language = field_language($entity_type, $entity, NULL, $langcode);
   $options = array('language' => $display_language);
 
   // Invoke field_default_view().
-  $null = NULL;
-  $output = _field_invoke_default('view', $entity_type, $entity, $view_mode, $null, $options);
+  $output = _field_invoke_default('view', $entity_type, $entity, $view_mode, $langcode, $options);
 
   // Add custom weight handling.
   list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
diff --git a/modules/field/field.default.inc b/modules/field/field.default.inc
index a10d138..1cf4151 100644
--- a/modules/field/field.default.inc
+++ b/modules/field/field.default.inc
@@ -134,8 +134,11 @@ function field_default_insert($entity_type, $entity, $field, $instance, $langcod
  *   - the name of a view mode
  *   - or an array of display settings to use for display, as found in the
  *     'display' entry of $instance definitions.
+ * @param $requested_language
+ *   The language originally requested, it may be different from $langcode as a
+ *   field value for this language may not be available.
  */
-function field_default_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $display) {
+function field_default_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $display, $requested_language) {
   // Group entities, instances and items by formatter module.
   $modules = array();
   foreach ($instances as $id => $instance) {
@@ -162,7 +165,7 @@ function field_default_prepare_view($entity_type, $entities, $field, $instances,
     // Invoke hook_field_formatter_prepare_view().
     $function = $module . '_field_formatter_prepare_view';
     if (function_exists($function)) {
-      $function($entity_type, $grouped_entities[$module], $field, $grouped_instances[$module], $langcode, $grouped_items[$module], $grouped_displays[$module]);
+      $function($entity_type, $grouped_entities[$module], $field, $grouped_instances[$module], $langcode, $grouped_items[$module], $grouped_displays[$module], $requested_language);
     }
   }
 }
@@ -188,8 +191,11 @@ function field_default_prepare_view($entity_type, $entities, $field, $instances,
  *   - the name of a view mode;
  *   - or an array of custom display settings, as found in the 'display' entry
  *     of $instance definitions.
+ * @param $requested_language
+ *   The language originally requested, it may be different from $langcode as a
+ *   field value for this language may not be available.
  */
-function field_default_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
+function field_default_view($entity_type, $entity, $field, $instance, $langcode, $items, $display, $requested_language) {
   list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
 
   $addition = array();
@@ -208,7 +214,7 @@ function field_default_view($entity_type, $entity, $field, $instance, $langcode,
     // performance impact on pages with many fields and values.
     $function = $display['module'] . '_field_formatter_view';
     if (function_exists($function)) {
-      $elements = $function($entity_type, $entity, $field, $instance, $langcode, $items, $display);
+      $elements = $function($entity_type, $entity, $field, $instance, $langcode, $items, $display, $requested_language);
 
       if ($elements) {
         $info = array(
@@ -219,6 +225,7 @@ function field_default_view($entity_type, $entity, $field, $instance, $langcode,
           '#label_display' => $display['label'],
           '#view_mode' => $view_mode,
           '#language' => $langcode,
+          '#requested_language' => $requested_language,
           '#field_name' => $field['field_name'],
           '#field_type' => $field['type'],
           '#field_translatable' => $field['translatable'],
@@ -226,7 +233,7 @@ function field_default_view($entity_type, $entity, $field, $instance, $langcode,
           '#bundle' => $bundle,
           '#object' => $entity,
           '#items' => $items,
-          '#formatter' => $display['type']
+          '#formatter' => $display['type'],
         );
 
         $addition[$field['field_name']] = array_merge($info, $elements);
diff --git a/modules/field/field.module b/modules/field/field.module
index e9dbc65..2f48cfc 100644
--- a/modules/field/field.module
+++ b/modules/field/field.module
@@ -880,20 +880,19 @@ function field_view_field($entity_type, $entity, $field_name, $display = array()
     // languages available in the field data.
     $display_language = field_language($entity_type, $entity, $field_name, $langcode);
     $options = array('field_name' => $field_name, 'language' => $display_language);
-    $null = NULL;
 
     // Invoke prepare_view steps if needed.
     if (empty($entity->_field_view_prepared)) {
       list($id) = entity_extract_ids($entity_type, $entity);
 
       // First let the field types do their preparation.
-      _field_invoke_multiple('prepare_view', $entity_type, array($id => $entity), $display, $null, $options);
+      _field_invoke_multiple('prepare_view', $entity_type, array($id => $entity), $display, $langcode, $options);
       // Then let the formatters do their own specific massaging.
-      _field_invoke_multiple_default('prepare_view', $entity_type, array($id => $entity), $display, $null, $options);
+      _field_invoke_multiple_default('prepare_view', $entity_type, array($id => $entity), $display, $langcode, $options);
     }
 
     // Build the renderable array.
-    $result = _field_invoke_default('view', $entity_type, $entity, $display, $null, $options);
+    $result = _field_invoke_default('view', $entity_type, $entity, $display, $langcode, $options);
 
     // Invoke hook_field_attach_view_alter() to let other modules alter the
     // renderable array, as in a full field_attach_view() execution.
diff --git a/modules/node/node.module b/modules/node/node.module
index 2dd1926..879857f 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -2514,6 +2514,9 @@ function node_feed($nids = FALSE, $channel = array()) {
  *   An array in the format expected by drupal_render().
  */
 function node_view_multiple($nodes, $view_mode = 'teaser', $weight = 0, $langcode = NULL) {
+  if (!isset($langcode)) {
+    $langcode = $GLOBALS['language_content']->language;
+  }
   field_attach_prepare_view('node', $nodes, $view_mode, $langcode);
   entity_prepare_view('node', $nodes, $langcode);
   $build = array();
