Problem/Motivation

#date_year_range property handles "0" like relative "+0" / "-0".
In result not year zero is used, but the current year.

Testing to only allow year zero (0):
0:0 // Expected: 0:0, actual: 2026:2026 (current year)
or a range starting in year zero:
0:+50 // Expected: 0:2076, actual: 2026:2076 (current year / current year+50)

Steps to reproduce

See above - to be proven!

Proposed resolution

Write a test to show the issue

Find the bug in

protected static function datetimeRangeYears($string, $date = NULL)

and fix it.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Issue fork drupal-3585723

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

anybody created an issue. See original summary.

anybody’s picture

Issue summary: View changes
anybody’s picture

Title: #date_year_range handles "0" like relative "+0" / "-0" » #date_year_range handles any value < 1000" like relative "+0" / "-0"
Issue tags: +Novice

It's even more weird. Entering any value < 1000 leads to current year. Tested with 0, 1 and 999.
Only setting >= 1000 works as expected using the absolute year.

So first we should have tests for this. Maybe a nice little core testing issue for novice?

anybody’s picture

Title: #date_year_range handles any value < 1000" like relative "+0" / "-0" » #date_year_range does not support years < 1000

Okay, I found the root cause:
datetimeRangeYears() does not support years with < 4 digits:

$year_pattern = '@^[0-9]{4}@';

and then magically handles them like relative dates.

Relative dates should always start with a +/-. So current year should be +0, not 0.
If we can't change that without introducing a regression, we should trigger a deprecation error if someone uses 0 without +/- prefix. Currently it's always treated as current year!

From Drupal 13 on we should then treat 0 as year 0!

anybody’s picture

gwenweb made their first commit to this issue’s fork.

gwenweb’s picture

I took the liberty of adding two small improvements to this MR:

  1. Fixed a typo in the comment: "locig" → "logic". This was causing the spell-checking job to fail in the CI pipeline.
  2. Added a unit test for `datetimeRangeYears()` in a new `DateElementBaseTest` class, covering the main cases including years < 1000, year 0, and relative offsets. The test was missing, which is why the pipeline had no coverage for this fix.

Happy to adjust if anything doesn't match the project's standards — this is my first contribution to Drupal core.

anybody’s picture

Status: Active » Needs review

Thank you very much @gwenweb!

anybody’s picture

Status: Needs review » Needs work

@gwenweb please see the phpcs issues and the failing test:

Drupal\Core\Test\Exception\MissingGroupException: Missing group metadata in test Drupal\Tests\Core\Datetime\Element\DateElementBaseTest::testDatetimeRangeYears in /builds/core/lib/Drupal/Core/Test/PhpUnitTestDiscovery.php:353
Stack trace:
#0 /builds/core/lib/Drupal/Core/Test/PhpUnitTestDiscovery.php(241): Drupal\Core\Test\PhpUnitTestDiscovery->getTestClassInfo(Object(PHPUnit\Framework\TestSuite), 'PHPUnit-Unit')
#1 /builds/core/lib/Drupal/Core/Test/PhpUnitTestDiscovery.php(160): Drupal\Core\Test\PhpUnitTestDiscovery->getTestList(Object(PHPUnit\Framework\TestSuite), NULL)
#2 /builds/core/scripts/run-tests.sh(614): Drupal\Core\Test\PhpUnitTestDiscovery->getTestClasses(NULL, Array, NULL)
#3 /builds/core/scripts/run-tests.sh(214): simpletest_script_get_test_list()
#4 {main}
gwenweb’s picture

Hi, I'm a relatively new contributor and I hope this is helpful. I've updated the merge request !15503 with the following changes:

  • Fix: changed $year_pattern from {4} to {1,4} so that years shorter than 4 digits (e.g. 500, 0, 1) are treated as absolute years rather than falling through to the relative offset logic.
  • Tests: added DateElementBaseTest with 8 data-driven cases covering standard ranges, years < 1000, year zero, single-digit years, and relative offsets (e.g. -5:+5).
  • CI compatibility: replaced @group/@dataProvider docblock annotations with PHP attributes (#[Group], #[DataProvider]), used createStub() instead of createMock() to avoid PHPUnit 12 strict mock notices, and fixed comment line length for PHPCS.

The pipeline now passes all 38 jobs. I'm not very experienced with Drupal core contribution standards, so please let me know if anything needs to be adjusted — I'm happy to make changes based on your feedback.

anybody’s picture

Status: Needs work » Needs review

Thanks @gwenweb LGTM! I added some more test case combinations. Are we missing further? Ready for general review I think.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new1.67 KB

The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

anybody’s picture

Status: Needs work » Needs review

Sorry GitLab had issues...

tstoeckler’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests

Looks great to me, nice fix! 14 test cases for this functionality seems fine to me, I don't think this should be held up on trying to conceive of more cases. Let's ship it! 👍️

alexpott’s picture

Version: main » 11.4.x-dev
Status: Reviewed & tested by the community » Fixed

Committed and pushed 4fd9a4ddd56 to main and 248c3ddb05a to 11.x and 8a52c88ba11 to 11.4.x. Thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • alexpott committed 8a52c88b on 11.4.x
    fix: #3585723 #date_year_range does not support years...

  • alexpott committed 248c3ddb on 11.x
    fix: #3585723 #date_year_range does not support years...

  • alexpott committed 4fd9a4dd on main
    fix: #3585723 #date_year_range does not support years...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.