Skip to content

fix(date-time): Reject impossible dates in DateTimeDiff with a format - #1884

Open
zigzagdev wants to merge 2 commits into
Respect:mainfrom
zigzagdev:fix/date-time-diff-invalid-date
Open

zigzagdev wants to merge 2 commits into
Respect:mainfrom
zigzagdev:fix/date-time-diff-invalid-date

Conversation

@zigzagdev

Copy link
Copy Markdown

Summary

DateTimeDiff now rejects impossible dates when a format is given, the same way Date and the other date validators do.

Motivation

When a format is given, DateTimeDiff passes the input straight to DateTimeImmutable::createFromFormat().
That function silently rolls impossible dates over, therefore 2023-02-30 with Y-m-d is compared as 2023-03-02 instead of being rejected.

(new DateTimeDiff('years', new LessThan(10), 'Y-m-d'))->evaluate('2023-02-30')->hasPassed; // true

DateTimeDiff already uses the CanValidateDateTime trait, but only for getExceptionalFormats(), that is why it never ran the isDateTime() check that the other validators use.

What I have done

In createDateTimeObject(), the input is now checked with isDateTime() before createFromFormat() is called.
Input that fails this check is treated as not a date, so the existing TEMPLATE_WRONG_FORMAT message is used.

Test Plans

Added the following cases to DateTimeDiffTest.

  • Invalid: Y-m-d with 2023-02-30, and c with 2023-02-30T00:00:00+00:00
  • Valid: Y-m-d with the leap day 2024-02-29, and c with 2020-01-01T00:00:00+00:00

Test Results

$ vendor/bin/phpunit --testsuite=unit --filter DateTimeDiffTest --testdox
PHPUnit 12.5.33 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.5.12
Configuration: /tmp/app/phpunit.xml.dist

Time: 00:00.076, Memory: 40.00 MB

Date Time Diff (Respect\Validation\Validators\DateTimeDiff)
 ✔ Should validate valid input with data set "years + DateTime"
 ✔ Should validate valid input with data set "years + string"
 ✔ Should validate valid input with data set "years + string + format"
 ✔ Should validate valid input with data set "years + leap day + format"
 ✔ Should validate valid input with data set "years + string + exceptional format"
 ✔ Should validate valid input with data set "years + string + format + now"
 ...
 ✔ Should validate invalid input with data set "invalid date, with failing rule"
 ✔ Should validate invalid input with data set "impossible date, with passing rule"
 ✔ Should validate invalid input with data set "impossible date in exceptional format, with passing rule"
 ✔ Should validate invalid input with data set "null"
 ...
 ✔ Is should throw an exception when type is not valid

OK (40 tests, 41 assertions)

$ vendor/bin/phpunit --testsuite=unit
PHPUnit 12.5.33 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.5.12
Configuration: /tmp/app/phpunit.xml.dist

Time: 00:00.774, Memory: 50.00 MB

OK (3899 tests, 4104 assertions)

createFromFormat() silently rolls impossible dates over, so "2023-02-30"
for "Y-m-d" was compared as 2023-03-02. The input is now checked with
isDateTime() first, matching how Date and the other validators behave.
Cover "2023-02-30" with "Y-m-d" and "c", which must be rejected, plus a
leap day and an exceptional format that must still pass.
@codecov

codecov Bot commented Oct 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.14%. Comparing base (ecccef1) to head (30f0472).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #1884      +/-   ##
============================================
- Coverage     97.18%   97.14%   -0.04%     
- Complexity     1096     1097       +1     
============================================
  Files           198      198              
  Lines          2555     2557       +2     
============================================
+ Hits           2483     2484       +1     
- Misses           72       73       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant