[WIP] Let a clock decide what "now" means during a validation - #1834
Draft
alganet wants to merge 1 commit into
Draft
[WIP] Let a clock decide what "now" means during a validation#1834alganet wants to merge 1 commit into
alganet wants to merge 1 commit into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1834 +/- ##
============================================
+ Coverage 97.12% 97.22% +0.10%
- Complexity 1069 1105 +36
============================================
Files 198 199 +1
Lines 2505 2597 +92
============================================
+ Hits 2433 2525 +92
Misses 72 72 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
A value the user gives is rarely a complete instant. "3 days ago" counts back from now, "10:00" means today at ten, a format without a year borrows the current one, and a comparison against "18 years ago" has to work out when that was. PHP completes each of those from the system clock, which it reads afresh every time, so no two values in the same validation are measured from quite the same moment. A value sitting exactly on a boundary then falls to whichever side the microseconds landed on: "7 years ago" counts as six years, because it is resolved a moment after the time it is measured against was read, and the count of years rounds the shortfall down. Introduce a PSR-20 clock, taken by every validator that needs to know the time: DateTimeDiff, the comparisons, Between, DateTime, LeapDate, LeapYear and Time. The clock is read where PHP read the system one and no more often, so a system clock, which is what a validator falls back to and what the container names by default, answers exactly as before, six years included. Name FrozenClock in the container instead and every chain builds one for itself, hands it to the validators it creates, attributes included, and holds it still while the validation runs, taking the time again on the next run so that a chain kept around never reports a stale one. Every validator of a chain then agrees on what "now" is, and "7 years ago" becomes the seven years it says it is. CanResolveDateTime completes a value the way PHP does, asking the clock where PHP asks the system: never for a value naming a full calendar date, and otherwise only once the value has been parsed. Validators receive the clock as the parameter they declare, so the fluent API is untouched, generated mixins and documented signatures included.
alganet
force-pushed
the
feat/psr20-clock
branch
from
August 16, 2026 03:38
373d17d to
082a90d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A value the user gives is rarely a complete instant. "3 days ago" counts back from now, "10:00" means today at ten, a format without a year borrows the current one, and a comparison against "18 years ago" has to work out when that was. PHP completes each of those from the system clock, which it reads afresh every time, so no two values in the same validation are measured from quite the same moment. A value sitting exactly on a boundary then falls to whichever side the microseconds landed on: "7 years ago" counts as six years, because it is resolved a moment after the time it is measured against was read, and the count of years rounds the shortfall down.
Introduce a PSR-20 clock, taken by every validator that needs to know the time: DateTimeDiff, the comparisons, Between, DateTime, LeapDate, LeapYear and Time. The clock is read where PHP read the system one and no more often, so a system clock, which is what a validator falls back to and what the container names by default, answers exactly as before, six years included.
Name FrozenClock in the container instead and every chain builds one for itself, hands it to the validators it creates, attributes included, and holds it still while the validation runs, taking the time again on the next run so that a chain kept around never reports a stale one. Every validator of a chain then agrees on what "now" is, and "7 years ago" becomes the seven years it says it is.
CanResolveDateTime completes a value the way PHP does, asking the clock where PHP asks the system: never for a value naming a full calendar date, and otherwise only once the value has been parsed. Validators receive the clock as the parameter they declare, so the fluent API is untouched, generated mixins and documented signatures included.