class DateTimeNormalizer

Same name in other branches
  1. 9 core/modules/serialization/src/Normalizer/DateTimeNormalizer.php \Drupal\serialization\Normalizer\DateTimeNormalizer
  2. 8.9.x core/modules/serialization/src/Normalizer/DateTimeNormalizer.php \Drupal\serialization\Normalizer\DateTimeNormalizer
  3. 10 core/modules/serialization/src/Normalizer/DateTimeNormalizer.php \Drupal\serialization\Normalizer\DateTimeNormalizer

Converts values for datetime objects to RFC3339 and from common formats.

@internal

Hierarchy

Expanded class hierarchy of DateTimeNormalizer

1 file declares its use of DateTimeNormalizer
DateTimeNormalizerTest.php in core/modules/serialization/tests/src/Unit/Normalizer/DateTimeNormalizerTest.php

File

core/modules/serialization/src/Normalizer/DateTimeNormalizer.php, line 15

Namespace

Drupal\serialization\Normalizer
View source
class DateTimeNormalizer extends NormalizerBase implements DenormalizerInterface {
    
    /**
     * Allowed datetime formats for the denormalizer.
     *
     * The list is chosen to be unambiguous and language neutral, but also common
     * for data interchange.
     *
     * @var string[]
     *
     * @see http://php.net/manual/en/datetime.createfromformat.php
     */
    protected $allowedFormats = [
        'RFC 3339' => \DateTime::RFC3339,
        'ISO 8601' => \DateTime::ISO8601,
    ];
    
    /**
     * The system's date configuration.
     *
     * @var \Drupal\Core\Config\ImmutableConfig
     */
    protected $systemDateConfig;
    
    /**
     * Constructs a new DateTimeNormalizer instance.
     *
     * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
     *   A config factory for retrieving required config objects.
     */
    public function __construct(ConfigFactoryInterface $config_factory) {
        $this->systemDateConfig = $config_factory->get('system.date');
    }
    
    /**
     * {@inheritdoc}
     */
    public function normalize($datetime, $format = NULL, array $context = []) : array|string|int|float|bool|\ArrayObject|null {
        assert($datetime instanceof DateTimeInterface);
        $drupal_date_time = $datetime->getDateTime();
        if ($drupal_date_time === NULL) {
            return $drupal_date_time;
        }
        return $drupal_date_time->setTimezone($this->getNormalizationTimezone())
            ->format(\DateTime::RFC3339);
    }
    
    /**
     * Gets the timezone to be used during normalization.
     *
     * @see ::normalize
     * @see \Drupal\Core\Datetime\DrupalDateTime::prepareTimezone()
     *
     * @return \DateTimeZone
     *   The timezone to use.
     */
    protected function getNormalizationTimezone() {
        $default_site_timezone = $this->systemDateConfig
            ->get('timezone.default');
        return new \DateTimeZone($default_site_timezone);
    }
    
    /**
     * {@inheritdoc}
     */
    public function denormalize($data, $class, $format = NULL, array $context = []) : mixed {
        // This only knows how to denormalize datetime strings and timestamps. If
        // something else is received, let validation constraints handle this.
        if (!is_string($data) && !is_numeric($data)) {
            return $data;
        }
        // Loop through the allowed formats and create a \DateTime from the
        // input data if it matches the defined pattern. Since the formats are
        // unambiguous (i.e., they reference an absolute time with a defined time
        // zone), only one will ever match.
        $allowed_formats = $context['datetime_allowed_formats'] ?? $this->allowedFormats;
        foreach ($allowed_formats as $format) {
            $date = \DateTime::createFromFormat($format, $data);
            $errors = \DateTime::getLastErrors();
            if ($date !== FALSE && empty($errors['errors']) && empty($errors['warnings'])) {
                return $date;
            }
        }
        $format_strings = [];
        foreach ($allowed_formats as $label => $format) {
            $format_strings[] = "\"{$format}\" ({$label})";
        }
        $formats = implode(', ', $format_strings);
        throw new UnexpectedValueException(sprintf('The specified date "%s" is not in an accepted format: %s.', $data, $formats));
    }
    
    /**
     * {@inheritdoc}
     */
    public function getSupportedTypes(?string $format) : array {
        return [
            DateTimeInterface::class => TRUE,
        ];
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY constant Name of key for bubbling cacheability metadata via serialization context.
DateTimeNormalizer::$allowedFormats protected property Allowed datetime formats for the denormalizer. 2
DateTimeNormalizer::$systemDateConfig protected property The system's date configuration.
DateTimeNormalizer::denormalize public function 2
DateTimeNormalizer::getNormalizationTimezone protected function Gets the timezone to be used during normalization. 1
DateTimeNormalizer::getSupportedTypes public function Overrides NormalizerBase::getSupportedTypes 2
DateTimeNormalizer::normalize public function 1
DateTimeNormalizer::__construct public function Constructs a new DateTimeNormalizer instance.
NormalizerBase::$format protected property List of formats which supports (de-)normalization. 1
NormalizerBase::addCacheableDependency protected function Adds cacheability if applicable.
NormalizerBase::checkFormat protected function Checks if the provided format is supported by this normalizer. 1
NormalizerBase::supportsDenormalization public function Implements \Symfony\Component\Serializer\Normalizer\DenormalizerInterface::supportsDenormalization() 1
NormalizerBase::supportsNormalization public function 1

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.