diff --git a/date.field.inc b/date.field.inc
index 46ea317..9947178 100644
--- a/date.field.inc
+++ b/date.field.inc
@@ -320,7 +320,6 @@ function date_field_widget_info() {
  * Implements hook_field_load().
  */
 function date_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
-  $timezone_db = date_get_timezone_db($field['settings']['tz_handling']);
   $db_format = date_type_format($field['type']);
   $process = date_process_values($field);
   foreach ($entities as $id => $entity) {
@@ -328,7 +327,7 @@ function date_field_load($entity_type, $entities, $field, $instances, $langcode,
       // If the file does not exist, mark the entire item as empty.
       if (is_array($item)) {
         $timezone = isset($item['timezone']) ? $item['timezone'] : '';
-        $item['timezone'] = date_get_timezone($field['settings']['tz_handling'], $timezone);
+        $timezone_db = date_get_timezone_db($field['settings']['tz_handling'], $timezone);
         $item['timezone_db'] = $timezone_db;
         $item['date_type'] = $field['type'];
         if (!empty($field['settings']['cache_enabled']) && ($delta < $field['settings']['cache_count'] || $field['settings']['cache_count'] == 0)) {
@@ -405,7 +404,7 @@ function date_field_presave($entity_type, $entity, $field, $instance, $langcode,
     $timezone = isset($item['timezone']) ? $item['timezone'] : '';
     if (is_array($item)) {
       $items[$delta]['timezone'] = date_get_timezone($field['settings']['tz_handling'], $timezone);
-      $items[$delta]['timezone_db'] = date_get_timezone_db($field['settings']['tz_handling']);
+      $items[$delta]['timezone_db'] = date_get_timezone_db($field['settings']['tz_handling'], $timezone);
       $items[$delta]['date_type'] = $field['type'];
     }
   }
diff --git a/date.install b/date.install
index 23fb07e..87dc862 100644
--- a/date.install
+++ b/date.install
@@ -192,3 +192,56 @@ function date_update_7004() {
   drupal_set_message(t('Date text widgets have been updated to use an increment of 1.'));
 }
 
+/**
+ * Convert date fields with setting "date's timezone" from UTC to the selected timezone
+ */
+function date_update_7005() {
+  // Select date fields.
+  $query = db_select('field_config', 'fc', array('fetch' => PDO::FETCH_ASSOC));
+  $query->fields('fc');
+  $query->condition(db_or()->condition('fc.type', 'date')->condition('fc.type', 'datetime'));
+  $results = $query->execute();
+
+  // Find the ones that have tz_handling = date.
+  foreach ($results as $record) {
+    $config = unserialize($record['data']);
+    if ($config['settings']['tz_handling'] == 'date') {
+      $field_name = $record['field_name'];
+      $date_format = '';
+      switch($record['type']) {
+        case 'datetime':
+          $date_format = DATE_FORMAT_DATETIME;
+          break;
+        case 'date':
+          $date_format = DATE_FORMAT_ISO;
+          break;
+      }
+      $query2 = db_select('field_data_'.$field_name, 'fd', array('fetch' => PDO::FETCH_ASSOC));
+      $query2->fields('fd');
+      $results2 = $query2->execute();
+      foreach ($results2 as $record2) {
+        $timezone = $record2[$field_name.'_timezone'];
+        $value = new DateObject($record2[$field_name.'_value'], 'UTC');
+        $value->limitGranularity($config['settings']['granularity']);
+        date_timezone_set($value, timezone_open($timezone));
+        $fields = array(
+          $field_name.'_value' => $value->format($date_format),
+        );
+        if (isset($record2[$field_name.'_value2'])) {
+          $value2 = new DateObject($record2[$field_name.'_value2'], 'UTC');
+          $value->limitGranularity($config['settings']['granularity']);
+          date_timezone_set($value2, timezone_open($timezone));
+          $fields[$field_name.'_value2'] = $value2->format($date_format);
+        }
+        db_update('field_data_'.$field_name)
+          ->fields($fields)
+          ->condition('entity_id', $record2['entity_id'])
+          ->condition('revision_id', $record2['revision_id'])
+          ->condition('delta', $record2['delta'])
+          ->execute();
+      }
+    }
+  }
+  field_cache_clear();
+}
+
diff --git a/date.module b/date.module
index 91c0b65..089534b 100644
--- a/date.module
+++ b/date.module
@@ -210,8 +210,9 @@ function date_formatter_process($formatter, $entity_type, $entity, $field, $inst
   $field_name = $field['field_name'];
   $format = date_formatter_format($formatter, $settings, $granularity, $langcode);
   $timezone = isset($item['timezone']) ? $item['timezone'] : '';
-  $timezone = date_get_timezone($field['settings']['tz_handling'], $timezone);
-  $timezone_db = date_get_timezone_db($field['settings']['tz_handling']);
+  $timezone = date_get_timezone($field['settings']['tz_handling']);
+  $timezone_db = isset($item['timezone_db']) ? $item['timezone_db'] : '';
+  $timezone_db = date_get_timezone_db($field['settings']['tz_handling'], $timezone_db);
   $db_format = date_type_format($field['type']);
   $process = date_process_values($field);
   foreach ($process as $processed) {
diff --git a/date_admin.inc b/date_admin.inc
index 0e32fc5..23b229d 100644
--- a/date_admin.inc
+++ b/date_admin.inc
@@ -553,7 +553,7 @@ function date_field_settings_validate(&$form, &$form_state) {
     form_set_value($form['timezone_db'], '', $form_state);
   }
   else {
-    form_set_value($form['timezone_db'], date_get_timezone_db($field['settings']['tz_handling']), $form_state);
+    form_set_value($form['timezone_db'], date_get_timezone_db($field['settings']['tz_handling'], $form['timezone_db']), $form_state);
   }
 
   if ($field['settings']['tz_handling'] != 'none' && !in_array('hour', array_filter($field['settings']['granularity']))) {
diff --git a/date_elements.inc b/date_elements.inc
index 6908d96..d55a3ec 100644
--- a/date_elements.inc
+++ b/date_elements.inc
@@ -158,7 +158,7 @@ function date_local_date($item, $timezone, $field, $instance, $part = 'value') {
   }
   */
 
-  $date = new DateObject($value, date_get_timezone_db($field['settings']['tz_handling']));
+  $date = new DateObject($value, date_get_timezone_db($field['settings']['tz_handling'], $timezone));
   $date->limitGranularity($field['settings']['granularity']);
   if (empty($date)) {
     return NULL;
@@ -525,7 +525,7 @@ function date_combo_validate($element, &$form_state) {
   elseif (!form_get_errors()) {
 
     $timezone = !empty($item[$tz_field]) ? $item[$tz_field] : $element['#date_timezone'];
-    $timezone_db = date_get_timezone_db($field['settings']['tz_handling']);
+    $timezone_db = date_get_timezone_db($field['settings']['tz_handling'], $timezone);
     $element[$from_field]['#date_timezone'] = $timezone;
     $from_date = date_input_date($field, $instance, $element[$from_field], $posted[$from_field]);
 
diff --git a/date_repeat_field/date_repeat_field.module b/date_repeat_field/date_repeat_field.module
index 9e5c8c1..854ef73 100644
--- a/date_repeat_field/date_repeat_field.module
+++ b/date_repeat_field/date_repeat_field.module
@@ -434,14 +434,14 @@ function date_repeat_build_dates($rrule = NULL, $rrule_values = NULL, $field, $i
   // adjusted back to UTC, but we want localtime dates to do
   // things like '+1 Tuesday', so adjust back to localtime.
   $timezone = date_get_timezone($field['settings']['tz_handling'], $item['timezone']);
-  $timezone_db = date_get_timezone_db($field['settings']['tz_handling']);
+  $timezone_db = date_get_timezone_db($field['settings']['tz_handling'], $timezone);
   $start = new DateObject($item['value'], $timezone_db, date_type_format($field['type']));
   $start->limitGranularity($field['settings']['granularity']);
   if ($timezone != $timezone_db) {
     date_timezone_set($start, timezone_open($timezone));
   }
   if (!empty($item['value2']) && $item['value2'] != $item['value']) {
-    $end = new DateObject($item['value2'], date_get_timezone_db($field['settings']['tz_handling']), date_type_format($field['type']));
+    $end = new DateObject($item['value2'], date_get_timezone_db($field['settings']['tz_handling'], $timezone), date_type_format($field['type']));
     $end->limitGranularity($field['settings']['granularity']);
     date_timezone_set($end, timezone_open($timezone));
   }
diff --git a/tests/date_timezone.test b/tests/date_timezone.test
index ddbdcef..f65fdc3 100644
--- a/tests/date_timezone.test
+++ b/tests/date_timezone.test
@@ -54,6 +54,7 @@ class DateTimezoneTestCase extends DateFieldBasic {
    * @todo.
    */
   public function dateForm($field_name, $field_type, $max_granularity, $tz_handling) {
+    global $user;
     variable_set('date_format_long', 'D, m/d/Y - H:i:s');
     $edit = array();
     $edit['title'] = $this->randomName(8);
@@ -83,6 +84,12 @@ class DateTimezoneTestCase extends DateFieldBasic {
         $edit[$field_name . '[und][0][value][date]'] = '10/07/2010 - 10:30';
         $edit[$field_name . '[und][0][value2][date]'] = '10/07/2010 - 11:30';
         $should_be = 'Thu, 10/07/2010 - 10:30 to 11:30';
+        // Makes sure the timezone conversion is handled properly with date fields: see https://www.drupal.org/node/998076
+        if ($tz_handling == 'date') {
+          $edit[$field_name . '[und][0][timezone][timezone]'] = 'Asia/Hong_Kong'; // UTC + 8
+          $user->timezone = 'Europe/Berlin'; // UTC + 2
+          $should_be = 'Thu, 10/07/2010 - 04:30 to 05:30';
+        }
         break;
       case 'second':
         $edit[$field_name . '[und][0][value][date]'] = '10/07/2010 - 10:30:30';
