You are here

public function ApStyleDateFormatter::formatRange in AP Style Date 8

Format a timestamp to an AP style date format.

Parameters

array $timestamps: The start and end timestamps to convert.

array $options: An array of options that affect how the date string is formatted.

mixed $timezone: \DateTimeZone object, time zone string or NULL. NULL uses the default system time zone. Defaults to NULL.

string $langcode: The language code.

Return value

string The formatted date string.

File

src/ApStyleDateFormatter.php, line 228

Class

ApStyleDateFormatter
Services for formatting date types using AP Style Date rules.

Namespace

Drupal\date_ap_style

Code

public function formatRange(array $timestamps, array $options = [], $timezone = NULL, $langcode = NULL) {
  if (empty($options)) {
    $options = $this
      ->getOptions();
  }
  if (empty($langcode)) {
    $langcode = $this->languageManager
      ->getCurrentLanguage()
      ->getId();
  }

  // If no timezone is specified, use the user's if available, or the site
  // or system default.
  if (empty($timezone)) {
    $timezone = date_default_timezone_get();
  }

  // Create a DrupalDateTime object from the timestamp and timezone.
  $datetime_settings = [
    'langcode' => $langcode,
  ];
  $date_output = '';
  $time_output = '';
  if (!empty($timestamps)) {

    // Create a DrupalDateTime object from the timestamp and timezone.
    $start_stamp = DrupalDateTime::createFromTimestamp($timestamps['start'], $timezone, $datetime_settings);
    $now = new DrupalDateTime('now', $timezone, $datetime_settings);
    if (!empty($timestamps['end']) or $timestamps['end'] != 0) {
      $end_stamp = DrupalDateTime::createFromTimestamp($timestamps['end'], $timezone, $datetime_settings);
    }
    else {
      $end_stamp = $start_stamp;
    }
    $format_start_date = '';
    $format_end_date = '';
    $time_start = '';
    $time_end = '';
    $time_start_string = '';
    $time_end_string = '';
    if ($start_stamp
      ->format('Y-m-d') == $end_stamp
      ->format('Y-m-d')) {

      // The Y-M-D is identical.
      $format_start_date = $this
        ->formatMonth($start_stamp) . ' j';

      // Display Y if not equal to current year or option set to always show
      // year.
      if (isset($options['always_display_year']) && $options['always_display_year'] || $start_stamp
        ->format('Y') != $now
        ->format('Y')) {
        $format_start_date .= ', Y';
      }
    }
    elseif ($start_stamp
      ->format('Y-m') == $end_stamp
      ->format('Y-m')) {

      // The Y-M is identical, but different D.
      $format_start_date = $this
        ->formatMonth($start_stamp) . ' j';
      $format_end_date = 'j';

      // Display Y if end_time year not equal to current year.
      if (isset($options['always_display_year']) && $options['always_display_year'] || $end_stamp
        ->format('Y') != $now
        ->format('Y')) {
        $format_end_date .= ', Y';
      }
    }
    elseif ($start_stamp
      ->format('Y') == $end_stamp
      ->format('Y')) {

      // The Y is identical, but different M-D.
      $format_start_date = $this
        ->formatMonth($start_stamp) . ' j';
      $format_end_date = $this
        ->formatMonth($end_stamp) . ' j';

      // Display Y if end_time year not equal to current year.
      if (isset($options['always_display_year']) && $options['always_display_year'] || $end_stamp
        ->format('Y') != $now
        ->format('Y')) {
        $format_end_date .= ', Y';
      }
    }
    elseif ($start_stamp
      ->format('m-d') == $end_stamp
      ->format('m-d')) {

      // The M-D is identical, but different Y.
      $format_start_date = $this
        ->formatMonth($start_stamp) . ' j, Y';
      $format_end_date = 'Y';
    }
    elseif ($start_stamp
      ->format('d') == $end_stamp
      ->format('d')) {
      $format_start_date = $this
        ->formatMonth($start_stamp) . ' j';
      $format_end_date = $this
        ->formatMonth($end_stamp) . ' j';
    }
    else {

      // All three are different.
      $format_start_date = $this
        ->formatMonth($start_stamp) . ' j, Y';
      $format_end_date = $this
        ->formatMonth($end_stamp) . ' j, Y';
    }
    if (isset($options['display_time']) && $options['display_time']) {
      if (isset($options['use_all_day']) && $options['use_all_day'] && ($start_stamp
        ->format('H:i') == '00:00' || $start_stamp
        ->format('gia') == $end_stamp
        ->format('gia'))) {
        $time_output = $this
          ->t('All Day');
      }
      else {
        $capital = isset($options['capitalize_noon_and_midnight']) && $options['capitalize_noon_and_midnight'];

        // Don't display the minutes if it's the top of the hour.
        $time_start = $start_stamp
          ->format('i') == '00' ? 'g' : 'g:i';

        // If same start/end meridians and different start/end time,
        // don't include meridian in start.
        $time_start .= $start_stamp
          ->format('a') == $end_stamp
          ->format('a') && $start_stamp
          ->format('gia') != $end_stamp
          ->format('gia') ? '' : ' a';

        // Set preformatted start and end times based on.
        // Replace 12:00 am with Midnight & 12:00 pm with Noon.
        switch ($start_stamp
          ->format('H:i')) {
          case '00:00':
            $time_start_string = $this
              ->t('midnight');
            if ($capital) {
              $time_start_string = ucfirst($time_start_string);
            }
            break;
          case '12:00':
            $time_start_string = $this
              ->t('noon');
            if ($capital) {
              $time_start_string = ucfirst($time_start_string);
            }
            break;
        }
        if ($start_stamp
          ->format('Hi') != $end_stamp
          ->format('Hi')) {
          $time_end = $end_stamp
            ->format('i') == '00' ? 'g a' : 'g:i a';
          switch ($end_stamp
            ->format('H:i')) {
            case '00:00':
              $time_end_string = $this
                ->t('midnight');
              if ($capital) {
                $time_end_string = ucfirst($time_end_string);
              }
              break;
            case '12:00':
              $time_end_string = $this
                ->t('noon');
              if ($capital) {
                $time_end_string = ucfirst($time_end_string);
              }
              break;
          }
        }
        if (!empty($time_start)) {
          $time_output .= $time_start_string ?: $start_stamp
            ->format($time_start);
        }
        if (!empty($time_end)) {
          $time_output .= isset($options['separator']) && $options['separator'] == 'endash' ? ' – ' : ' to ';
          $time_output .= $time_end_string ?: $end_stamp
            ->format($time_end);
        }
        $time_output = str_replace([
          'am',
          'pm',
        ], [
          'a.m.',
          'p.m.',
        ], $time_output);
      }
    }
    $date_output = $start_stamp
      ->format($format_start_date);
    if (!empty($format_end_date)) {
      $date_output .= (isset($options['separator']) && $options['separator'] == 'endash' ? ' – ' : ' to ') . $end_stamp
        ->format($format_end_date);
    }
    if (!empty($time_output) && isset($options['time_before_date']) && $options['time_before_date']) {
      $output = $time_output . ', ' . $date_output;
    }
    elseif (!empty($time_output)) {
      $output = $date_output . ', ' . $time_output;
    }
    else {
      $output = $date_output;
    }
    return $output;
  }
  return '';
}