diff --git a/date_migrate/date.migrate.inc b/date_migrate/date.migrate.inc
index 637a626..b66e38c 100644
--- a/date_migrate/date.migrate.inc
+++ b/date_migrate/date.migrate.inc
@@ -57,37 +57,48 @@ class DateMigrateFieldHandler extends MigrateFieldHandler {
       $arguments = array();
     }
 
-    if (isset($arguments['timezone'])) {
-      $default_timezone = $arguments['timezone'];
-    }
-    else {
-      $default_timezone = 'UTC';
-    }
-    if (isset($arguments['timezone_db'])) {
-      $default_timezone_db = $arguments['timezone_db'];
-    }
-    else {
-      $default_timezone_db = NULL;
-    }
-    if (isset($arguments['rrule'])) {
-      $default_rrule = $arguments['rrule'];
-    }
-    else {
-      $default_rrule = NULL;
-    }
     $language = $this->getFieldLanguage($entity, $field_info, $arguments);
 
     // Setup the standard Field API array for saving.
-    $delta = 0;
-    foreach ($values as $from) {
-      // Set defaults.
-      $to = NULL;
-      $timezone = $default_timezone;
-      $timezone_db = $default_timezone_db;
-      $rrule = $default_rrule;
-
-      // Is the value a straight datetime value, or JSON containing a set of
-      // properties?
+    foreach ($values as $delta => $from) {
+      if (!empty($arguments['timezone'])) {
+        if (is_array($arguments['timezone'])) {
+          $timezone = $arguments['timezone'][$delta];
+        }
+        else {
+          $timezone = $arguments['timezone'];
+        }
+      }
+      else {
+        $timezone = 'UTC';
+      }
+
+      if (!empty($arguments['rrule'])) {
+        if (is_array($arguments['rrule'])) {
+          $rrule = $arguments['rrule'][$delta];
+        }
+        else {
+          $rrule = $arguments['rrule'];
+        }
+      }
+      else {
+        $rrule = NULL;
+      }
+
+      if (!empty($arguments['to'])) {
+        if (is_array($arguments['to'])) {
+          $to = $arguments['to'][$delta];
+        }
+        else {
+          $to = $arguments['to'];
+        }
+      }
+      else {
+        $to = NULL;
+      }
+
+      // Legacy support for JSON containing a set of properties - deprecated
+      // now that we have subfields.
       if (!empty($from) && $from{0} == '{') {
         $properties = drupal_json_decode($from);
         $from = $properties['from'];
@@ -98,9 +109,6 @@ class DateMigrateFieldHandler extends MigrateFieldHandler {
         if (!empty($properties['timezone'])) {
           $timezone = $properties['timezone'];
         }
-        if (!empty($properties['timezone_db'])) {
-          $timezone_db = $properties['timezone_db'];
-        }
         if (!empty($properties['rrule'])) {
           $rrule = $properties['rrule'];
         }
@@ -165,11 +173,18 @@ class DateMigrateFieldHandler extends MigrateFieldHandler {
           $return[$language][$delta]['value2'] = $to;
         }
       }
-      $delta++;
     }
     if (!isset($return)) {
       $return = NULL;
     }
     return $return;
   }
+
+  public function fields($migration = NULL) {
+    return array(
+      'timezone' => t('Timezone'),
+      'rrule' => t('Recurring event rule'),
+      'to' => t('End date date'),
+    );
+  }
 }
diff --git a/date_migrate/date_migrate_example/date_migrate_example.migrate.inc b/date_migrate/date_migrate_example/date_migrate_example.migrate.inc
index 491c27f..fd55bd4 100644
--- a/date_migrate/date_migrate_example/date_migrate_example.migrate.inc
+++ b/date_migrate/date_migrate_example/date_migrate_example.migrate.inc
@@ -66,25 +66,30 @@ class DateExampleMigration extends XMLMigration {
 
     // For date ranges, we add the "end" value in prepareRow() below.
     $this->addFieldMapping('field_date_range', 'date_range_from');
+    $this->addFieldMapping('field_date_range:to', 'date_range_to');
 
     // RRULEs on repeat fields are also done in prepareRow().
     $this->addFieldMapping('field_date_repeat', 'date_repeat');
+    $this->addFieldMapping('field_date_repeat:rrule', 'date_repeat_rrule');
 
     $this->addFieldMapping('field_datestamp', 'datestamp')
       ->xpath('datestamp');
     $this->addFieldMapping('field_datestamp_range', 'datestamp_range_from');
+    $this->addFieldMapping('field_datestamp_range:to', 'datestamp_range_to');
 
     // You can specify a timezone to be applied to all values going into the
     // field (Tokyo is UTC+9, no DST)
-    $arguments = DateMigrateFieldHandler::arguments('Asia/Tokyo');
     $this->addFieldMapping('field_datetime', 'datetime')
-      ->xpath('datetime')
-      ->arguments($arguments);
+      ->xpath('datetime');
+    $this->addFieldMapping('field_datetime:timezone')
+      ->defaultValue('Asia/Tokyo');
 
     // You can also get the timezone from the source data - it can be different
     // for each instance of the field. Like To and RRULE values, it is added
     // in prepareRow().
     $this->addFieldMapping('field_datetime_range', 'datetime_range_from');
+    $this->addFieldMapping('field_datetime_range:to', 'datetime_range_to');
+    $this->addFieldMapping('field_datetime_range:timezone', 'datetime_range_timezone');
 
     // Unmapped destination fields.
     $this->addUnmigratedDestinations(array('is_new', 'status', 'promote', 'revision', 'language', 'sticky', 'created', 'changed', 'revision_uid'));
@@ -101,30 +106,18 @@ class DateExampleMigration extends XMLMigration {
     // The date range field can have multiple values.
     $current_row->date_range_from = array();
     foreach ($current_row->xml->date_range as $range) {
-      $date_data = array(
-        'from' => (string) $range->from[0],
-        'to' => (string) $range->to[0],
-      );
-      $current_row->date_range_from[] = drupal_json_encode($date_data);
+      $current_row->date_range_from[] = (string)$range->from[0];
+      $current_row->date_range_to[] = (string)$range->to[0];
     }
 
-    $date_data = array(
-      'from' => (string) $current_row->xml->datestamp_range->from[0],
-      'to' => (string) $current_row->xml->datestamp_range->to[0],
-    );
-    $current_row->datestamp_range_from = drupal_json_encode($date_data);
+    $current_row->datestamp_range_from = (string) $current_row->xml->datestamp_range->from[0];
+    $current_row->datestamp_range_to = (string) $current_row->xml->datestamp_range->to[0];
 
-    $date_data = array(
-      'from' => (string) $current_row->xml->datetime_range->from[0],
-      'to' => (string) $current_row->xml->datetime_range->to[0],
-      'timezone' => (string) $current_row->xml->datetime_range->timezone[0],
-    );
-    $current_row->datetime_range_from = drupal_json_encode($date_data);
+    $current_row->datetime_range_from = (string) $current_row->xml->datetime_range->from[0];
+    $current_row->datetime_range_to = (string) $current_row->xml->datetime_range->to[0];
+    $current_row->datetime_range_timezone = (string) $current_row->xml->datetime_range->timezone[0];
 
-    $date_data = array(
-      'from' => (string) $current_row->xml->date_repeat->date[0],
-      'rrule' => (string) $current_row->xml->date_repeat->rule[0],
-    );
-    $current_row->date_repeat = drupal_json_encode($date_data);
+    $current_row->date_repeat = (string) $current_row->xml->date_repeat->date[0];
+    $current_row->date_repeat_rrule = (string) $current_row->xml->date_repeat->rule[0];
   }
 }
