diff --git a/core/modules/migrate/src/Plugin/migrate/process/FormatDate.php b/core/modules/migrate/src/Plugin/migrate/process/FormatDate.php
new file mode 100644
index 0000000..4ebdef3
--- /dev/null
+++ b/core/modules/migrate/src/Plugin/migrate/process/FormatDate.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace Drupal\migrate\Plugin\migrate\process;
+
+use Drupal\Component\Datetime\DateTimePlus;
+use Drupal\migrate\MigrateException;
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\Row;
+
+/**
+ * This plugin applies date storage formats from \DateTime::createFromFormat.
+ *
+ * @MigrateProcessPlugin(
+ *   id = "format_date"
+ * )
+ *
+ * Available configuration keys
+ *   - from_format: the source format string as accepted by date()
+ *       http://php.net/manual/en/function.date.php
+ *   - to_format: the format string as accepted by date() to apply on source.
+ *   - timezone: @see Drupal\Component\Datetime\DateTimePlus::__construct()
+ *   - settings: @see Drupal\Component\Datetime\DateTimePlus::__construct()
+  *
+ * Example usage for date only fields (DATETIME_DATE_STORAGE_FORMAT):
+ * @code
+ * process:
+ *     field_date:
+ *       plugin: format_date
+ *       from_format: 'm/d/Y'
+ *       to_format: 'Y-m-d'
+ *       source: event_date
+ * @endcode
+ *
+ * Example usage for datetime fields (DATETIME_DATETIME_STORAGE_FORMAT):
+ * @code
+ * process:
+ *     field_time:
+ *       plugin: format_date
+ *       from_format: 'm/d/Y H:i:s'
+ *       to_format: 'Y-m-d\TH:i:s'
+ *       source: event_time
+ * @endcode
+ *
+ */
+class FormatDate extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    if (empty($value)) {
+      return '';
+    }
+
+    // Validate the configuration.
+    if (empty($this->configuration['from_format'])) {
+      throw new MigrateException('Format date plugin is missing from_format configuration.');
+    }
+    if (empty($this->configuration['to_format'])) {
+      throw new MigrateException('Format date plugin is missing to_format configuration.');
+    }
+
+    $fromFormat = $this->configuration['from_format'];
+    $toFormat = $this->configuration['to_format'];
+    $timezone = isset($this->configuration['timezone']) ? $this->configuration['timezone'] : NULL;
+    $settings = isset($this->configuration['settings']) ? $this->configuration['settings'] : [];
+
+    // Attempt to transformed the supplied date using the defined input format.
+    // DateTimePlus::createFromFormat can throw exceptions, so we need to
+    // explicitly check for problems.
+    // @todo Update the exception message we throw based on
+    //   https://www.drupal.org/node/2830079
+    try {
+      $transformed = DateTimePlus::createFromFormat($fromFormat, $value, $timezone, $settings)->format($toFormat);
+    }
+    catch (\Exception $e) {
+      throw new MigrateException(sprintf('Format date plugin could not transform "%s" using the format "%s".', $value, $fromFormat));
+    }
+
+    return $transformed;
+  }
+
+}
+
diff --git a/core/modules/migrate/tests/src/Unit/process/FormatDateTest.php b/core/modules/migrate/tests/src/Unit/process/FormatDateTest.php
new file mode 100644
index 0000000..48a7d88
--- /dev/null
+++ b/core/modules/migrate/tests/src/Unit/process/FormatDateTest.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace Drupal\Tests\migrate\Unit\process;
+
+use Drupal\migrate\MigrateException;
+use Drupal\migrate\Plugin\migrate\process\FormatDate;
+
+/**
+ * Tests the format date process plugin.
+ *
+ * @group migrate
+ * @coversDefaultClass Drupal\migrate\Plugin\migrate\process\FormatDate
+ */
+class FormatDateTest extends MigrateProcessTestCase {
+
+  /**
+   * Tests that missing configuration will throw an exception.
+   */
+  public function testMigrateExceptionMissingFromFormat() {
+    $configuration = [
+      'from_format' => '',
+      'to_format' => 'Y-m-d',
+    ];
+
+    $this->setExpectedException(MigrateException::class, 'Format date plugin is missing from_format configuration.');
+    $this->plugin = new FormatDate($configuration, 'test_format_date', []);
+    $this->plugin->transform('01/05/1955', $this->migrateExecutable, $this->row, 'field_date');
+  }
+
+  /**
+   * Tests that missing configuration will throw an exception.
+   */
+  public function testMigrateExceptionMissingToFormat() {
+    $configuration = [
+      'from_format' => 'm/d/Y',
+      'to_format' => '',
+    ];
+
+    $this->setExpectedException(MigrateException::class, 'Format date plugin is missing to_format configuration.');
+    $this->plugin = new FormatDate($configuration, 'test_format_date', []);
+    $this->plugin->transform('01/05/1955', $this->migrateExecutable, $this->row, 'field_date');
+  }
+
+  /**
+   * Tests that date format mismatches will throw an exception.
+   */
+  public function testMigrateExceptionBadFormat() {
+    $configuration = [
+      'from_format' => 'm/d/Y',
+      'to_format' => 'Y-m-d',
+    ];
+
+    $this->setExpectedException(MigrateException::class, 'Format date plugin could not transform "January 5, 1955" using the format "m/d/Y".');
+    $this->plugin = new FormatDate($configuration, 'test_format_date', []);
+    $this->plugin->transform('January 5, 1955', $this->migrateExecutable, $this->row, 'field_date');
+  }
+
+  /**
+   * Tests transformation.
+   *
+   * @covers ::transform
+   *
+   * @dataProvider datesDataProvider
+   */
+  public function testTransform($fromFormat, $toFormat, $value, $expected) {
+    $configuration = [
+      'from_format' => $fromFormat,
+      'to_format' => $toFormat,
+    ];
+
+    $this->plugin = new FormatDate($configuration, 'test_format_date', []);
+    $actual = $this->plugin->transform($value, $this->migrateExecutable, $this->row, 'field_date');
+
+    $this->assertEquals($expected, $actual);
+  }
+
+  /**
+   * Data provider of test dates.
+   *
+   * @return array
+   *   Array of date formats and actual/expected values.
+   */
+  public function datesDataProvider() {
+    return [
+      ['m/d/Y', 'Y-m-d', '01/05/1955', '1955-01-05'],
+      ['m/d/Y', 'Y-m-d', '', ''],
+      ['m/d/Y H:i:s', 'Y-m-d\TH:i:s', '01/05/1955 10:43:22', '1955-01-05T10:43:22'],
+    ];
+  }
+
+}
