DateRange formatters should compare rendered dates instead of raw timestamps

Created on 31 October 2016, about 8 years ago
Updated 11 January 2024, 11 months ago

Problem/Motivation

Currently DateRangeCustomFormatter has a logic block:

        if ($start_date->getTimestamp() !== $end_date->getTimestamp()) {
          $elements[$delta] = [
            'start_date' => $this->buildDate($start_date),
            'separator' => ['#plain_text' => ' ' . $separator . ' '],
            'end_date' => $this->buildDate($end_date),
          ];
        }
        else {
          $elements[$delta] = $this->buildDate($start_date);
        }

This is to prevent a date string being duplicated w/ a separator. Since this formatter accepts custom format strings, this can result in weird output like

2016 - 2016

when the format string is 'Y' or anything other than the full granularity of the type.

The DateRangeDefaultFormatter has the same problem, when used with a date format that doesn't display all date components, e.g. `html_year`.

Proposed resolution

Instead of comparing using ->getTimestamp(), use the ->formatDate() method to check the actual rendered string (adjusted for timezone).

Steps to reproduce

  1. Install Drupal 10.1.x-dev (Standard profile) in English language
  2. Enable "Datetime Range" module
  3. Create a new date range field for articles:
    1. Go to Structure > Content types > Article > Create new field
    2. In "Add a new field" select "Date range"
    3. As "Label" set "Date range"
    4. Click "Save and continue"
    5. Click "Save field settings"
  4. Configure either the default or custom date range formatter with a date format that doesn't show all date components:
    1. Go to Structure > Content types > Article > Manage display
    2. Verify that the selected formatter for the "Date range" field is set to "Default".
    3. Expand the formatter settings by clicking on the gear icon to the right of the select field.
    4. As "Date format" select a date format that doesn't show all date components, e.g. "Olivero Medium" or "HTML year".
    5. Click "Update"
    6. Click "Save"
  5. Create a new article with a date time range with two dates where the date components displayed by your selected date formats are equal, but the rest of the components not displayed are not equal:
    1. Go to Content
    2. Click "Add content"
    3. Click "Article"
    4. Enter a title, e.g. "123".
    5. In the "Date range" field, enter 2023-05-08 17:00:00 as "Start date".
    6. In the "Date range" field, enter 2023-05-08 19:30:00 as "End date".
    7. Click "Save"
  6. Verify that on the canonical view of the article, the date range is shown as "8 May, 2023 - 8 May, 2023".
  7. Apply patch.
  8. Clear all caches.
  9. Verify that on the canonical view of the article, the date range is shown as "8 May, 2023".

Actual result

The date range field displays as START DATE SEPRATOR END DATE even though both start date and end date are the same.

Expected result

The date range field displays as START DATE since both dates are equal.

Remaining tasks

User interface changes

API changes

Data model changes

Merge request to commit

MR 5398

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Datetime 

Last updated 3 days ago

Created by

🇺🇸United States mpdonadio Philadelphia/PA/USA (UTC-5)

Live updates comments and jobs are added and updated live.
  • Needs reroll

    The patch will have to be re-rolled with new suggestions/changes described in the comments in the issue.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024