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 0000000000000000000000000000000000000000..b197f17f60f6c7dc8a6bb737211726bfed61a618 --- /dev/null +++ b/core/modules/migrate/src/Plugin/migrate/process/FormatDate.php @@ -0,0 +1,113 @@ +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'] : []; + + // Attempts to transform the supplied date using the defined input format. + // DateTimePlus::createFromFormat can throw exceptions, so we need to + // explicitly check for problems. + try { + $transformed = DateTimePlus::createFromFormat($fromFormat, $value, $timezone, $settings)->format($toFormat); + } + catch (\InvalidArgumentException $e) { + throw new MigrateException(sprintf('Format date plugin could not transform "%s" using the format "%s". Error: %s', $value, $fromFormat, $e->getMessage()), $e->getCode(), $e); + } + catch (\UnexpectedValueException $e) { + throw new MigrateException(sprintf('Format date plugin could not transform "%s" using the format "%s". Error: %s', $value, $fromFormat, $e->getMessage()), $e->getCode(), $e); + } + + 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 0000000000000000000000000000000000000000..c1e0c631bd2eb886381205986407a9326799b77e --- /dev/null +++ b/core/modules/migrate/tests/src/Unit/process/FormatDateTest.php @@ -0,0 +1,124 @@ + '', + '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". Error: The date cannot be created from a format.'); + $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 + * + * @param $configuration + * The configuration of the migration process plugin. + * @param $value + * The source value for the migration process plugin. + * @param $expected + * The expected value of the migration process plugin. + */ + public function testTransform($configuration, $value, $expected) { + $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 [ + 'datetime_date' => [ + 'configuration' => [ + 'from_format' => 'm/d/Y', + 'to_format' => 'Y-m-d', + ], + 'value' => '01/05/1955', + 'expected' => '1955-01-05', + ], + 'datetime_datetime' => [ + 'configuration' => [ + 'from_format' => 'm/d/Y H:i:s', + 'to_format' => 'Y-m-d\TH:i:s', + ], + 'value' => '01/05/1955 10:43:22', + 'expected' => '1955-01-05T10:43:22', + ], + 'empty_values' => [ + 'configuration' => [ + 'from_format' => 'm/d/Y', + 'to_format' => 'Y-m-d', + ], + 'value' => '', + 'expected' => '', + ], + 'timezone' => [ + 'configuration' => [ + 'from_format' => 'Y-m-d\TH:i:sO', + 'to_format' => 'Y-m-d\TH:i:s', + 'timezone' => 'America/Managua', + ], + 'value' => '2004-12-19T10:19:42-0600', + 'expected' => '2004-12-19T10:19:42', + ], + ]; + } + +}