Skip to content

feat(psr20): ban relative date strings in DateTime/DateTimeImmutable constructors - #13

Merged
clementvtrd merged 5 commits into
mainfrom
chore/init-github-spec-kit-correctly
Jul 27, 2026
Merged

feat(psr20): ban relative date strings in DateTime/DateTimeImmutable constructors#13
clementvtrd merged 5 commits into
mainfrom
chore/init-github-spec-kit-correctly

Conversation

@clementvtrd

@clementvtrd clementvtrd commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Extends Psr20Rule to flag all relative date string literals passed to new DateTime / new DateTimeImmutable, not only 'now' and the empty constructor
  • Absolute date strings (e.g. '2023-01-15') and variable arguments remain allowed — no false positives
  • Compound modifiers (e.g. 'yesterday noon', 'monday 14:00:00') are also caught via \b word boundary matching
  • Error identifier clock.disallowDateTimeNow preserved for backward compatibility with existing @phpstan-ignore suppressions

What triggers the rule now

Keywords: now, yesterday, today, tomorrow, noon, midnight (and with time suffix e.g. 'today midnight')
Day names: mondaysunday (and with time suffix e.g. 'monday 14:00:00')
Signed/unsigned offsets: +1 day, -2 weeks, 0 days
Ago/in expressions: 2 days ago, in 3 weeks
Qualifiers: next Monday, last week, previous year, this month
Day-of-month selectors: first day of this month, last day of January 2023
Clock-relative: back of 10, front of 11

All matching is case-insensitive.

What does NOT trigger the rule

Absolute ISO dates ('2023-01-15', '2023-12-31 23:59:59', '2023-01-15T12:00:00+00:00'), time-only strings ('12:00:00'), variable arguments ($dateString), variadic placeholders (...$args), and non-DateTime/DateTimeImmutable classes.

Test plan

  • docker compose run --rm php composer test — PHPUnit green (22 assertions)
  • docker compose run --rm php composer phpstan — no errors
  • docker compose run --rm php composer cs-check — no style issues
  • CI matrix covers PHP 8.2, 8.3, 8.4, 8.5

🤖 Generated with Claude Code

clementvtrd and others added 3 commits July 22, 2026 16:29
- Introduced a new static method `isRelativeDateString()` in `Psr20Rule` to detect relative date strings.
- Updated `processNode()` to flag any relative date strings passed to `new DateTime` or `new DateTimeImmutable`.
- Added a comprehensive set of regex patterns to identify various relative date formats.
- Extended test cases in `Psr20RuleTest` to cover new relative date scenarios and ensure existing behaviors are preserved.
- Updated the fixture file to include examples of both relative and absolute date strings.
- Revised documentation in `README.md` to reflect changes in the rule's behavior and examples.
…docs

- Add fixture lines for 'TOMORROW' (uppercase, US1/AC6) and new \stdClass()
  (non-clock class must not trigger) with matching test assertions
- Regenerate phpstan baseline (31 errors)
- Update data-model.md to document \b word boundary patterns and explain
  compound modifier rationale (replaces stale $ anchors)
- Update quickstart.md scenario 1 to include compound modifier examples

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread src/Rules/Psr/Psr20Rule.php
Comment thread src/Rules/Psr/Psr20Rule.php
@clementvtrd
clementvtrd requested a review from eexit July 27, 2026 11:26
@clementvtrd
clementvtrd merged commit d2d9255 into main Jul 27, 2026
12 checks passed
@clementvtrd
clementvtrd deleted the chore/init-github-spec-kit-correctly branch July 27, 2026 13:41
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.

2 participants