date_ap_style-8.x-1.x-dev/tests/src/Kernel/ApStyleDateFormatterTest.php

tests/src/Kernel/ApStyleDateFormatterTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\date_ap_style\Kernel;

use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\date_ap_style\ApStyleDateFormatter;
use Drupal\KernelTests\KernelTestBase;

/**
 * Kernel tests for the ApStyleDateFormatter covering all scenarios.
 */
class ApStyleDateFormatterTest extends KernelTestBase {

  /**
   * The language manager service.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;

  /**
   * The configuration service.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The ApStyleDateFormatter instance.
   *
   * @var \Drupal\date_ap_style\ApStyleDateFormatter
   */
  protected $dateFormatter;

  /**
   * {@inheritdoc}
   */
  protected static $modules = ['system', 'date_ap_style'];

  /**
   * Set up the test environment.
   */
  protected function setUp(): void {
    parent::setUp();

    // Retrieve the necessary services from the container.
    $this->languageManager = $this->container->get('language_manager');
    $this->configFactory = $this->container->get('config.factory');

    // Create the ApStyleDateFormatter instance using real services.
    $this->dateFormatter = new ApStyleDateFormatter($this->languageManager, $this->configFactory);
  }

  /**
   * Test out-of-the-box formatter.
   */
  public function testBasicFormat(): void {
    $options = [];
    $date = new DrupalDateTime('2017-06-22 00:00:00');
    $date = $date->getTimestamp();
    $result = $this->dateFormatter->formatTimestamp($date, $options);

    $this->assertEquals('June 22, 2017', $result);
  }

  /**
   * Test Appropriately Return Year.
   *
   * AP rules state when in the current year, don't show the year. So we need
   * to test a date in the current year that is also not the current month. Also
   * test date for current year that should not show date.
   */
  public function testDisplayYear(): void {
    $options = ['always_display_year' => TRUE];
    $currentDate = new DrupalDateTime();
    $currentYear = $currentDate->format('Y');
    $currentMonth = (int) $currentDate->format('m');

    // Initialize the test date.
    if ($currentMonth === 2) {
      $testDate = (clone $currentDate)->modify('+6 months');
    }
    else {
      $testDate = new DrupalDateTime("{$currentYear}-02-01");
    }

    // Get the timestamp for the test date.
    $timestamp = $testDate->getTimestamp();

    // Format the test date to "M. d, Y" (e.g., "Feb. 2, 2024").
    $formattedTestDateYear = $testDate->format('M. j, Y');
    $formattedTestDate = $testDate->format('M. j');

    // Format the test date for assertion or further testing.
    $show_year = $this->dateFormatter->formatTimestamp($timestamp, $options);
    $no_year = $this->dateFormatter->formatTimestamp($timestamp);

    // Example assertions for when to display year.
    $this->assertEquals($formattedTestDateYear, $show_year);
    $this->assertEquals($formattedTestDate, $no_year);
  }

  /**
   * Tests format for today.
   *
   * Tests use_today, cap_today and additionally with display_time.
   */
  public function testUseToday(): void {
    $options = ['use_today' => TRUE, 'cap_today' => TRUE];
    $today = new DrupalDateTime('today');
    $today->setTime(13, 30);
    $today = $today->getTimestamp();

    $result = $this->dateFormatter->formatTimestamp($today, $options);
    $this->assertEquals('Today', $result);

    $options = ['use_today' => TRUE, 'cap_today' => TRUE, 'display_time' => TRUE];
    $result = $this->dateFormatter->formatTimestamp($today, $options);
    $this->assertEquals('Today, 1:30 p.m.', $result);
  }

  /**
   * Test day of week with time for date in current week.
   */
  public function testUseDayOfWeek(): void {
    $options = ['display_day' => TRUE, 'display_time' => TRUE];
    $testDate = new DrupalDateTime();

    // Check if today is Friday.
    // 5 represents Friday.
    if ($testDate->format('N') == 5) {
      // If today is Friday, set the date to this Saturday.
      // Move to Saturday.
      $testDate->modify('+1 day');
    }
    $testDay = $testDate->format('l');
    $testDate->setTime(13, 0);
    $testDate = $testDate->getTimestamp();
    $testDay .= ', 1 p.m.';

    $result = $this->dateFormatter->formatTimestamp($testDate, $options);
    $this->assertEquals($testDay, $result);
  }

  /**
   * Tests format with month_only option enabled.
   */
  public function testMonthOnly(): void {
    $options = ['month_only' => TRUE];
    $date = new DrupalDateTime('2024-02-15 00:00:00');
    $date = $date->getTimestamp();
    $result = $this->dateFormatter->formatTimestamp($date, $options);
    $this->assertEquals('Feb.', $result);
  }

  /**
   * Tests hide date (show time only).
   */
  public function testHideDate(): void {
    $options = ['hide_date' => TRUE, 'display_time' => TRUE];
    $date = new DrupalDateTime('2024-08-22 17:21:00');
    $date = $date->getTimestamp();
    $result = $this->dateFormatter->formatTimestamp($date, $options);
    $this->assertEquals('5:21 p.m.', $result);
  }

  /**
   * Test time before date.
   */
  public function testTimeBeforeDate(): void {
    $options = ['time_before_date' => TRUE, 'display_time' => TRUE];
    $date = new DrupalDateTime('2012-01-10 12:00:00');
    $date = $date->getTimestamp();
    $result = $this->dateFormatter->formatTimestamp($date, $options);
    $this->assertEquals('12 p.m., Jan. 10, 2012', $result);
  }

  /**
   * Tests format with display_noon_and_midnight option enabled.
   */
  public function testDisplayNoonAndMidnight(): void {
    $options = [
      'display_time' => TRUE,
      'display_noon_and_midnight' => TRUE,
      'capitalize_noon_and_midnight' => TRUE,
    ];
    $start = new DrupalDateTime('2023-12-15 12:00:00');
    $start = $start->getTimestamp();
    $result = $this->dateFormatter->formatTimestamp($start, $options);
    $this->assertEquals('Dec. 15, 2023, Noon', $result);

    $start = new DrupalDateTime('2023-12-15 00:00:00');
    $start = $start->getTimestamp();
    $result = $this->dateFormatter->formatTimestamp($start, $options);
    $this->assertEquals('Dec. 15, 2023, Midnight', $result);
  }

  /**
   * Tests format with all day option enabled.
   */
  public function testDisplayAllDay(): void {
    $options = [
      'display_time' => TRUE,
      'use_all_day' => TRUE,
    ];

    $start = new DrupalDateTime('2023-12-15 00:00:00');
    $start = $start->getTimestamp();
    $result = $this->dateFormatter->formatTimestamp($start, $options);
    $this->assertEquals('Dec. 15, 2023, All Day', $result);
  }

  /**
   * Tests basic date range formatting.
   */
  public function testBasicDateRange(): void {
    $start = new DrupalDateTime('2023-12-15 00:00:00');
    $end = new DrupalDateTime('2023-12-20 00:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];
    $result = $this->dateFormatter->formatRange($timestamps);
    $this->assertEquals('Dec. 15 to 20, 2023', $result);
  }

  /**
   * Test month only in range when month and year is the same.
   */
  public function testMonthOnlySameMonthYear(): void {
    $year = (new DrupalDateTime('now'))->format('Y');
    $options = ['month_only' => TRUE];
    $start = new DrupalDateTime("$year-09-01");
    $end = new DrupalDateTime("$year-09-30");

    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Sept.', $result);
  }

  /**
   * Test month only in range when month and year is the same.
   *
   * Test when year is not the current year.
   */
  public function testNonCurrentYearMonthOnlySameMonthYear(): void {
    $year = '2024';
    $options = ['month_only' => TRUE];
    $start = new DrupalDateTime("$year-09-01");
    $end = new DrupalDateTime("$year-09-30");

    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Sept. 2024', $result);
  }

  /**
   * Tests when months are different and year is the same.
   */
  public function testMonthOnlyDifferentMonthsSameYear(): void {
    $year = (new DrupalDateTime('now'))->format('Y');
    $options = ['month_only' => TRUE];
    $start = new DrupalDateTime("$year-09-01");
    $end = new DrupalDateTime("$year-10-01");

    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Sept. to Oct.', $result);
  }

  /**
   * Tests when months are different and year is the same.
   */
  public function testNonCurrentYearMonthOnlyDifferentMonthsSameYear(): void {
    $year = '2024';
    $options = ['month_only' => TRUE];
    $start = new DrupalDateTime("$year-09-01");
    $end = new DrupalDateTime("$year-10-01");

    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Sept. to Oct. 2024', $result);
  }

  /**
   * Tests month only when years are different in range.
   */
  public function testMonthOnlyDifferentYears(): void {
    $options = ['month_only' => TRUE];
    $start = new DrupalDateTime('2022-12-01');
    $end = new DrupalDateTime('2023-01-01');

    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Dec. 2022 to Jan. 2023', $result);
  }

  /**
   * Tests date range with always_display_year enabled using same month.
   */
  public function testAlwaysDisplayYearRange(): void {
    $options = ['always_display_year' => TRUE];
    $currentDate = new DrupalDateTime('first day of this month');
    $currentYear = $currentDate->format('Y');
    $currentMonth = (int) $currentDate->format('m');

    // Initialize the test date.
    if ($currentMonth === 2) {
      $start = (clone $currentDate)->modify('+6 months');
    }
    else {
      $start = new DrupalDateTime("{$currentYear}-02-01");
    }
    $end = (clone $start)->modify('+1 week');

    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $formatted = $start->format('M. j') . ' to ' . $end->format('j, Y');

    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals($formatted, $result);
  }

  /**
   * Tests range format with display_day option enabled.
   *
   * Provided that the start and end dates are the same (i.e., only the times
   * differ), AP style format implies that the day of the week should be
   * displayable, given the following logic:
   * - all references to Associated Press *dates* are treated as separate from
   *   references to Associated Press *times*
   * - On a date range where the start and end date are the same, the *date*
   *   part of the *date and time* would be considered a single value, and
   *   should display the day of the week.
   *
   * See issue: 3167278.
   */
  public function testDisplayDayTimeRange(): void {
    $options = ['display_day' => TRUE, 'display_time' => TRUE];
    $start = new DrupalDateTime();

    // Get the current day of the week (1 = Monday, 7 = Sunday)
    $currentDayOfWeek = $start->format('N');

    // If today is before Saturday, add one day to the current date.
    if ($currentDayOfWeek == 5) {
      $start->modify('-1 day');
    }
    $testDay = $start->format('l');
    $start->setTime(12, 0);
    $end = clone $start;
    $end->setTime(13, 0);
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];
    $result = $this->dateFormatter->formatRange($timestamps, $options);

    $this->assertStringContainsString($testDay, $result);
    $this->assertStringContainsString('12 p.m. to 1 p.m.', $result);
  }

  /**
   * Tests format for today.
   *
   * Tests use_today, cap_today and additionally with display_time.
   */
  public function testUseTodayRange() {
    $options = ['use_today' => TRUE, 'cap_today' => TRUE];
    $today = new DrupalDateTime('today');
    $today->setTime(11, 30);
    $end = (clone $today)->modify('+1 hour');
    $timestamps = [
      'start' => $today->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Today', $result);

    $options = ['use_today' => TRUE, 'cap_today' => TRUE, 'display_time' => TRUE];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Today, 11:30 a.m. to 12:30 p.m.', $result);
  }

  /**
   * Tests same month with different days.
   */
  public function testSameMonthDifferentDays() {
    $start = new DrupalDateTime('2023-09-09 00:00:00');
    $end = new DrupalDateTime('2023-09-20 00:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];
    $result = $this->dateFormatter->formatRange($timestamps);
    $this->assertEquals('Sept. 9 to 20, 2023', $result);
  }

  /**
   * Tests when the date is the same.
   */
  public function testSameDate() {
    $date = new DrupalDateTime('1981-05-07 00:00:00');
    $timestamps = [
      'start' => $date->getTimestamp(),
      'end' => $date->getTimestamp(),
    ];
    $result = $this->dateFormatter->formatRange($timestamps);
    $this->assertEquals('May 7, 1981', $result);
  }

  /**
   * Test the All Day output option on date ranges.
   */
  public function testDisplayAllDayRange() {
    $options = [
      'display_time' => TRUE,
      'use_all_day' => TRUE,
    ];

    $start = new DrupalDateTime('2023-12-15 00:00:00');
    $end = new DrupalDateTime('2023-12-15 11:59:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Dec. 15, 2023, All Day', $result);
  }

  /**
   * Tests format with display_time and time_before_date enabled.
   */
  public function testTimeBeforeDateRange() {
    $options = ['display_time' => TRUE, 'time_before_date' => TRUE];
    $start = new DrupalDateTime('2023-12-15 10:00:00');
    $end = new DrupalDateTime('2023-12-15 11:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('10 to 11 a.m., Dec. 15, 2023', $result);
  }

  /**
   * Tests format with hide_date and display_time enabled.
   */
  public function testHideDateRange() {
    $options = ['hide_date' => TRUE, 'display_time' => TRUE];
    $start = new DrupalDateTime('2024-12-15 10:00:00');
    $end = new DrupalDateTime('2024-12-15 11:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('10 to 11 a.m.', $result);
  }

  /**
   * Tests format with display_noon_and_midnight option enabled.
   */
  public function testDisplayNoonAndMidnightRange() {
    $options = [
      'display_time' => TRUE,
      'display_noon_and_midnight' => TRUE,
      'capitalize_noon_and_midnight' => TRUE,
    ];
    $start = new DrupalDateTime('2023-12-15 12:00:00');
    $start = $start->getTimestamp();
    $result = $this->dateFormatter->formatRange(['start' => $start, 'end' => $start], $options);
    $this->assertEquals('Dec. 15, 2023, Noon', $result);

    $start = new DrupalDateTime('2023-12-15 00:00:00');
    $start = $start->getTimestamp();
    $result = $this->dateFormatter->formatRange(['start' => $start, 'end' => $start], $options);
    $this->assertEquals('Dec. 15, 2023, Midnight', $result);
  }

  /**
   * Tests format with display_noon_and_midnight option disabled.
   */
  public function testDisplayNoonAndMidnightDisabledRange() {
    $options = [
      'display_time' => TRUE,
      'display_noon_and_midnight' => FALSE,
    ];
    $start = (new DrupalDateTime('2023-12-15 09:00:00'))->getTimestamp();
    $end = (new DrupalDateTime('2023-12-15 12:00:00'))->getTimestamp();
    $result = $this->dateFormatter->formatRange(['start' => $start, 'end' => $end], $options);
    $this->assertEquals('Dec. 15, 2023, 9 a.m. to 12 p.m.', $result);

    $start = (new DrupalDateTime('2023-12-15 09:00:00'))->getTimestamp();
    $end = (new DrupalDateTime('2023-12-16 00:00:00'))->getTimestamp();
    $result = $this->dateFormatter->formatRange(['start' => $start, 'end' => $end], $options);
    $this->assertEquals('Dec. 15 to 16, 2023, 9 a.m. to 12 a.m.', $result);

    $start = (new DrupalDateTime('2023-12-15 12:00:00'))->getTimestamp();
    $end = (new DrupalDateTime('2023-12-15 15:00:00'))->getTimestamp();
    $result = $this->dateFormatter->formatRange(['start' => $start, 'end' => $end], $options);
    $this->assertEquals('Dec. 15, 2023, 12 p.m. to 3 p.m.', $result);

    $start = (new DrupalDateTime('2023-12-15 00:00:00'))->getTimestamp();
    $end = (new DrupalDateTime('2023-12-15 03:00:00'))->getTimestamp();
    $result = $this->dateFormatter->formatRange(['start' => $start, 'end' => $end], $options);
    $this->assertEquals('Dec. 15, 2023, 12 a.m. to 3 a.m.', $result);
  }

  /**
   * Tests format with different separators.
   */
  public function testSeparatorHandling() {
    $options = ['separator' => 'endash'];
    $start = new DrupalDateTime('2012-01-10 00:00:00');
    $end = new DrupalDateTime('2012-01-20 00:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Jan. 10 &ndash; 20, 2012', $result);

    $options = ['separator' => 'to'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Jan. 10 to 20, 2012', $result);

    $options = ['separator' => 'hyphen'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Jan. 10-20, 2012', $result);
  }

  /**
   * Tests separator handling with different month ranges.
   */
  public function testSeparatorHandlingDifferentMonths() {
    // Test range spanning different months.
    $start = new DrupalDateTime('2012-01-25 00:00:00');
    $end = new DrupalDateTime('2012-02-05 00:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $options = ['separator' => 'endash'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Jan. 25 &ndash; Feb. 5, 2012', $result);

    $options = ['separator' => 'to'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Jan. 25 to Feb. 5, 2012', $result);

    $options = ['separator' => 'hyphen'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Jan. 25-Feb. 5, 2012', $result);
  }

  /**
   * Tests separator handling with different year ranges.
   */
  public function testSeparatorHandlingDifferentYears() {
    // Test range spanning different years.
    $start = new DrupalDateTime('2012-12-28 00:00:00');
    $end = new DrupalDateTime('2013-01-05 00:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $options = ['separator' => 'endash'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Dec. 28, 2012 &ndash; Jan. 5, 2013', $result);

    $options = ['separator' => 'to'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Dec. 28, 2012 to Jan. 5, 2013', $result);

    $options = ['separator' => 'hyphen'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Dec. 28, 2012-Jan. 5, 2013', $result);
  }

  /**
   * Tests separator handling with time ranges.
   */
  public function testSeparatorHandlingWithTime() {
    $start = new DrupalDateTime('2012-01-10 09:30:00');
    $end = new DrupalDateTime('2012-01-10 17:45:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $options = ['display_time' => TRUE, 'separator' => 'endash'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Jan. 10, 2012, 9:30 a.m. &ndash; 5:45 p.m.', $result);

    $options = ['display_time' => TRUE, 'separator' => 'to'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Jan. 10, 2012, 9:30 a.m. to 5:45 p.m.', $result);

    $options = ['display_time' => TRUE, 'separator' => 'hyphen'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Jan. 10, 2012, 9:30 a.m.-5:45 p.m.', $result);
  }

  /**
   * Tests separator handling with time before date option.
   */
  public function testSeparatorHandlingTimeBeforeDate() {
    $start = new DrupalDateTime('2012-01-10 09:30:00');
    $end = new DrupalDateTime('2012-01-10 17:45:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $options = ['display_time' => TRUE, 'time_before_date' => TRUE, 'separator' => 'endash'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('9:30 a.m. &ndash; 5:45 p.m., Jan. 10, 2012', $result);

    $options = ['display_time' => TRUE, 'time_before_date' => TRUE, 'separator' => 'to'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('9:30 a.m. to 5:45 p.m., Jan. 10, 2012', $result);

    $options = ['display_time' => TRUE, 'time_before_date' => TRUE, 'separator' => 'hyphen'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('9:30 a.m.-5:45 p.m., Jan. 10, 2012', $result);
  }

  /**
   * Tests format for same day, same meridian, different start/end time.
   */
  public function testSameDaySameMeridianDifferentTimes() {
    $options = ['display_time' => TRUE, 'time_before_date' => TRUE];

    // Set up a date range on the same day with the same meridian.
    // 10:00 AM.
    $start = new DrupalDateTime('2023-12-15 10:00:00');
    // 11:00 AM
    $end = new DrupalDateTime('2023-12-15 11:00:00');

    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    // Format the date range.
    $result = $this->dateFormatter->formatRange($timestamps, $options);

    // Assert that the formatted result omits the meridian from the start time.
    $this->assertEquals('10 to 11 a.m., Dec. 15, 2023', $result);
  }

  /**
   * Tests hyphen separator for compact academic/fiscal year ranges.
   */
  public function testHyphenSeparatorAcademicYearRanges() {
    $start = new DrupalDateTime('2023-09-15 00:00:00');
    $end = new DrupalDateTime('2024-06-15 00:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $options = ['separator' => 'hyphen'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Sept. 15, 2023-June 15, 2024', $result);

    // Compare with other separators.
    $options = ['separator' => 'to'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Sept. 15, 2023 to June 15, 2024', $result);

    $options = ['separator' => 'endash'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Sept. 15, 2023 &ndash; June 15, 2024', $result);
  }

  /**
   * Tests hyphen separator for short date ranges.
   */
  public function testHyphenSeparatorHeadlineFormat() {
    $start = new DrupalDateTime('2023-09-10 00:00:00');
    $end = new DrupalDateTime('2023-09-15 00:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $options = ['separator' => 'hyphen'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Sept. 10-15, 2023', $result);

    // Compare with other separators - hyphen is most space-efficient.
    $options = ['separator' => 'to'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Sept. 10 to 15, 2023', $result);
  }

  /**
   * Tests hyphen separator for time ranges in schedules/timetables.
   */
  public function testHyphenSeparatorScheduleTimeRanges() {
    $start = new DrupalDateTime('2023-12-15 09:00:00');
    $end = new DrupalDateTime('2023-12-15 17:30:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $options = ['display_time' => TRUE, 'separator' => 'hyphen'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Dec. 15, 2023, 9 a.m.-5:30 p.m.', $result);

    $options = ['display_time' => TRUE, 'separator' => 'to'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Dec. 15, 2023, 9 a.m. to 5:30 p.m.', $result);
  }

  /**
   * Tests hyphen separator for month-only ranges in compact formats.
   */
  public function testHyphenSeparatorMonthOnlyRanges() {
    // Month-only ranges.
    $start = new DrupalDateTime('2023-11-01 00:00:00');
    $end = new DrupalDateTime('2024-03-01 00:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $options = ['month_only' => TRUE, 'separator' => 'hyphen'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Nov. 2023-March 2024', $result);

    $options = ['month_only' => TRUE, 'separator' => 'to'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Nov. 2023 to March 2024', $result);
  }

  /**
   * Tests hyphen separator for same meridian time ranges.
   */
  public function testHyphenSeparatorSameMeridianTimeRanges() {
    $start = new DrupalDateTime('2023-12-15 21:00:00');
    $end = new DrupalDateTime('2023-12-15 22:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $options = ['display_time' => TRUE, 'separator' => 'hyphen'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Dec. 15, 2023, 9-10 p.m.', $result);

    $options = ['display_time' => TRUE, 'separator' => 'to'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Dec. 15, 2023, 9 to 10 p.m.', $result);

    $options = ['display_time' => TRUE, 'separator' => 'endash'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Dec. 15, 2023, 9 &ndash; 10 p.m.', $result);

    // Test with morning hours too.
    $start = new DrupalDateTime('2023-12-15 10:00:00');
    $end = new DrupalDateTime('2023-12-15 11:00:00');
    $timestamps = [
      'start' => $start->getTimestamp(),
      'end' => $end->getTimestamp(),
    ];

    $options = ['display_time' => TRUE, 'separator' => 'hyphen'];
    $result = $this->dateFormatter->formatRange($timestamps, $options);
    $this->assertEquals('Dec. 15, 2023, 10-11 a.m.', $result);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc