Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 297819

wrapper class for PHP's DatePeriod

$
0
0

Problem/Motivation

Date objects in Drupal are of type DrupalDateTime, which inherits from DateTimePlus, which is a wrapper around PHP's native DateTime class.
PHP also has a DatePeriod class. I think it would be useful to also wrap this class creating a DatePeriodPlus and a DrupalDatePeriod. This way the date range field can return a DrupalDatePeriod class as value, like the date field returns an DateTimePlus object. Since all the logic to create DrupalDateTime objects is already in core this class can take advantage of that and also create a period of any of the formats provided by this class, since a period contains a start, end date and an interval.

Proposed resolution

I propose 2 new classes DrupalDatePeriod and DatePeriodPlus. DatePeriodPlus would have a constructor that take 2 dates in any format supported by DateTimePlus, an interval (string or class) default to one day (P1D), the timezone and settings.


/**
   * Constructs a date period object set to a requested date and timezone.
   *
   * @param mixed $date
   *   A /DateTime object, DateTimePlus object, date array, timestamp or NULL.
   *   NULL will default to today.
   * @param mixed $date2
   *   A /DateTime object, DateTimePlus object, date array, timestamp or NULL.
   *   NULL will default to today.
   * @param mixed $interval
   *   (optional) A \DateInterval object, interval string or NULL. NULL uses the
   *   default interval of one day (P1D).
   * @param mixed $timezone
   *   (optional) \DateTimeZone object, time zone string or NULL. NULL uses the
   *   default system time zone. Defaults to NULL. Note that the $timezone
   *   parameter and the current timezone are ignored when the $date
   *   and $date2 parameter either is a \DateTime or \DateTimePlus object.
   * @param array $settings
   *   (optional) Keyed array of settings. Defaults to empty array.
   *   - langcode: (optional) String two letter language code used to control
   *     the result of the format(). Defaults to NULL.
   *   - debug: (optional) Boolean choice to leave debug values in the
   *     date object for debugging purposes. Defaults to FALSE.
   */
  public function __construct($date = NULL, $date2 = NULL, $interval = NULL, $timezone = NULL, array $settings = []) {
    $prepared_timezone = $this->prepareTimezone($timezone);

    // Massage the input values if necessary.
    $prepared_date = $this->prepareDateTime($date, $prepared_timezone, $settings);
    $prepared_date2 = $this->prepareDateTime($date2, $prepared_timezone, $settings);

    $prepared_interval = $this->prepareInterval($interval);

    try {
      $this->errors = [];

      if (!$prepared_date) {
        $this->errors = 'No valid date provided';
      }

      if (!$prepared_date2) {
        $this->errors = 'No valid date2 provided';
      }

      if (empty($this->errors)) {
        $prepared_date_plus = DateTimePlus::createFromDateTime($prepared_date);
        $prepared_date2_plus = DateTimePlus::createFromDateTime($prepared_date2);

        array_merge($this->errors, $prepared_date_plus->getErrors());
        array_merge($this->errors, $prepared_date2_plus->getErrors());

        if (empty($this->errors)) {
          $this->datePeriodObject = new \DatePeriod($prepared_date, $prepared_interval, $prepared_date2);
        }
      }
    }
    catch (\Exception $e) {
      $this->errors[] = $e->getMessage();
    }
  }
/**
   * Prepare the dates.
   *
   * @param mixed $date
   *   A /DateTime object, DateTimePlus object, date array, timestamp or NULL.
   *   NULL will default to today.
   * @param mixed $timezone
   *   A /DateTime object, DateTimePlus object, date array, timestamp or NULL.
   *   NULL will default to today.
   * @param array $settings
   *   (optional) Keyed array of settings. Defaults to empty array.
   *   - langcode: (optional) String two letter language code used to control
   *     the result of the format(). Defaults to NULL.
   *   - debug: (optional) Boolean choice to leave debug values in the
   *     date object for debugging purposes. Defaults to FALSE.
   *
   * @return \DateTime
   *   A php date time object.
   */
  protected function prepareDateTime($date, $timezone, array $settings = []) {
    // If the input is a DateTime object, use it.
    if ($date instanceof \DateTime) {
      return $date;
    }

    // If the input is a DateTimePlus object, get the php datetime object.
    if ($date instanceof DateTimePlus) {
      return $date->getPhpDateTime();
    }

    if (is_array($date)) {
      $date_time_plus = DateTimePlus::createFromArray($date, $timezone, $settings);
      return $date_time_plus->getPhpDateTime();
    }

    if (is_numeric($date)) {
      $date_time_plus = DateTimePlus::createFromTimestamp($date, $timezone, $settings);
      return $date_time_plus->getPhpDateTime();
    }

    $date_time_plus = new DateTimePlus($date, $timezone, $settings);
    return $date_time_plus->getPhpDateTime();
  }

Remaining tasks

  • Agree this is a good idea
  • Make sure https://www.drupal.org/node/2906229 (getPhpDateTime() method) is provided by core
  • Finetune\Rework\Review provided "proof of concept" patch to a fully working version
  • Extend the DrupalDatePeriod with a format function
  • Provide tests
  • Later on the date range field can implement return this class as a computed value

User interface changes

None

API changes

New classes DrupalDatePeriod and DatePeriodPlus

Data model changes

None


Viewing all articles
Browse latest Browse all 297819

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>