Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/08-list-of-rules-by-category.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@

- [Date](rules/Date.md)
- [DateTime](rules/DateTime.md)
- [DateTimeDiff](rules/DateTimeDiff.md)
- [LeapDate](rules/LeapDate.md)
- [LeapYear](rules/LeapYear.md)
- [MaxAge](rules/MaxAge.md)
Expand Down Expand Up @@ -323,6 +324,7 @@
- [CurrencyCode](rules/CurrencyCode.md)
- [Date](rules/Date.md)
- [DateTime](rules/DateTime.md)
- [DateTimeDiff](rules/DateTimeDiff.md)
- [Decimal](rules/Decimal.md)
- [Digit](rules/Digit.md)
- [Directory](rules/Directory.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/Date.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Version | Description
See also:

- [DateTime](DateTime.md)
- [DateTimeDiff](DateTimeDiff.md)
- [LeapDate](LeapDate.md)
- [LeapYear](LeapYear.md)
- [MaxAge](MaxAge.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/DateTime.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ See also:
- [BetweenExclusive](BetweenExclusive.md)
- [Callback](Callback.md)
- [Date](Date.md)
- [DateTimeDiff](DateTimeDiff.md)
- [LeapDate](LeapDate.md)
- [LeapYear](LeapYear.md)
- [MinAge](MinAge.md)
Expand Down
53 changes: 53 additions & 0 deletions docs/rules/DateTimeDiff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# DateTimeDiff

- `DateTimeDiff(string $type, Validatable $rule)`
- `DateTimeDiff(string $type, Validatable $rule, string $format)`

Validates the difference of date/time against a specific rule.

The `$format` argument should follow PHP's [date()][] function. When the `$format` is not given, this rule accepts
[Supported Date and Time Formats][] by PHP (see [strtotime()][]).

```php
v::dateTimeDiff('years', v::equals(7))->validate('7 years ago'); // true
v::dateTimeDiff('years', v::equals(7))->validate('7 years ago + 1 minute'); // false

v::dateTimeDiff('years', v::greaterThan(18), 'd/m/Y')->validate('09/12/1990'); // true
v::dateTimeDiff('years', v::greaterThan(18), 'd/m/Y')->validate('09/12/2023'); // false

v::dateTimeDiff('months', v::between(1, 18))->validate('5 months ago'); // true
```

The supported types are:

* `years`
* `months`
* `days`
* `hours`
* `minutes`
* `seconds`
* `microseconds`

## Categorization

- Date and Time

## Changelog

| Version | Description |
| ------: |--------------------------------------------|
| 3.0.0 | Created from `Age`, `MinAge`, and `MaxAge` |

***
See also:

- [Date](Date.md)
- [DateTime](DateTime.md)
- [Max](Max.md)
- [Min](Min.md)
- [Time](Time.md)

[date()]: http://php.net/date
[DateTimeInterface]: http://php.net/DateTimeInterface
[strtotime()]: http://php.net/strtotime
[Supported Date and Time Formats]: http://php.net/datetime.formats
1 change: 1 addition & 0 deletions docs/rules/Max.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ See also:

- [Between](Between.md)
- [BetweenExclusive](BetweenExclusive.md)
- [DateTimeDiff](DateTimeDiff.md)
- [GreaterThan](GreaterThan.md)
- [GreaterThanOrEqual](GreaterThanOrEqual.md)
- [IterableType](IterableType.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/Min.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ See also:

- [Between](Between.md)
- [BetweenExclusive](BetweenExclusive.md)
- [DateTimeDiff](DateTimeDiff.md)
- [Each](Each.md)
- [GreaterThan](GreaterThan.md)
- [GreaterThanOrEqual](GreaterThanOrEqual.md)
Expand Down
1 change: 1 addition & 0 deletions docs/rules/Time.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,6 @@ See also:

- [Date](Date.md)
- [DateTime](DateTime.md)
- [DateTimeDiff](DateTimeDiff.md)
- [LeapDate](LeapDate.md)
- [LeapYear](LeapYear.md)
37 changes: 37 additions & 0 deletions library/Helpers/CanExtractRules.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
namespace Respect\Validation\Helpers;

use Respect\Validation\Exceptions\ComponentException;
use Respect\Validation\Rules\Core\Composite;
use Respect\Validation\Rules\Not;
use Respect\Validation\Validatable;
use Respect\Validation\Validator;
use Throwable;

use function array_map;
use function count;
Expand All @@ -37,6 +40,40 @@ private function extractSingle(Validatable $rule, string $class): Validatable
return $rule;
}

private function extractSiblingSuitableRule(Validatable $rule, Throwable $throwable): Validatable
{
$this->assertSingleRule($rule, $throwable);

if ($rule instanceof Validator) {
return $rule->getRules()[0];
}

return $rule;
}

private function assertSingleRule(Validatable $rule, Throwable $throwable): void
{
if ($rule instanceof Not) {
$this->assertSingleRule($rule->getRule(), $throwable);

return;
}

if ($rule instanceof Validator) {
if (count($rule->getRules()) !== 1) {
throw $throwable;
}

$this->assertSingleRule($rule->getRules()[0], $throwable);

return;
}

if ($rule instanceof Composite) {
throw $throwable;
}
}

/**
* @param array<Validatable> $rules
*
Expand Down
14 changes: 10 additions & 4 deletions library/Helpers/CanValidateDateTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ trait CanValidateDateTime
{
private function isDateTime(string $format, string $value): bool
{
$exceptionalFormats = [
'c' => 'Y-m-d\TH:i:sP',
'r' => 'D, d M Y H:i:s O',
];
$exceptionalFormats = $this->getExceptionalFormats();

$format = $exceptionalFormats[$format] ?? $format;

Expand Down Expand Up @@ -75,4 +72,13 @@ private function isDateInformation(array $info): bool

return checkdate($info['month'] ?: 1, 1, $info['year'] ?: 1);
}

/** @return array<string, string> */
private function getExceptionalFormats(): array
{
return [
'c' => 'Y-m-d\TH:i:sP',
'r' => 'D, d M Y H:i:s O',
];
}
}
12 changes: 12 additions & 0 deletions library/Mixins/ChainedKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Respect\Validation\Mixins;

use DateTimeImmutable;
use Respect\Validation\Validatable;

interface ChainedKey
Expand Down Expand Up @@ -107,6 +108,17 @@ public function keyDate(int|string $key, string $format = 'Y-m-d'): ChainedValid

public function keyDateTime(int|string $key, ?string $format = null): ChainedValidator;

/**
* @param "years"|"months"|"days"|"hours"|"minutes"|"seconds"|"microseconds" $type
*/
public function keyDateTimeDiff(
int|string $key,
string $type,
Validatable $rule,
?string $format = null,
?DateTimeImmutable $now = null,
): ChainedValidator;

public function keyDecimal(int|string $key, int $decimals): ChainedValidator;

public function keyDigit(int|string $key, string ...$additionalChars): ChainedValidator;
Expand Down
11 changes: 11 additions & 0 deletions library/Mixins/ChainedNot.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Respect\Validation\Mixins;

use DateTimeImmutable;
use Respect\Validation\Validatable;

interface ChainedNot
Expand Down Expand Up @@ -91,6 +92,16 @@ public function notDate(string $format = 'Y-m-d'): ChainedValidator;

public function notDateTime(?string $format = null): ChainedValidator;

/**
* @param "years"|"months"|"days"|"hours"|"minutes"|"seconds"|"microseconds" $type
*/
public function notDateTimeDiff(
string $type,
Validatable $rule,
?string $format = null,
?DateTimeImmutable $now = null,
): ChainedValidator;

public function notDecimal(int $decimals): ChainedValidator;

public function notDigit(string ...$additionalChars): ChainedValidator;
Expand Down
11 changes: 11 additions & 0 deletions library/Mixins/ChainedNullOr.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Respect\Validation\Mixins;

use DateTimeImmutable;
use Respect\Validation\Validatable;

interface ChainedNullOr
Expand Down Expand Up @@ -91,6 +92,16 @@ public function nullOrDate(string $format = 'Y-m-d'): ChainedValidator;

public function nullOrDateTime(?string $format = null): ChainedValidator;

/**
* @param "years"|"months"|"days"|"hours"|"minutes"|"seconds"|"microseconds" $type
*/
public function nullOrDateTimeDiff(
string $type,
Validatable $rule,
?string $format = null,
?DateTimeImmutable $now = null,
): ChainedValidator;

public function nullOrDecimal(int $decimals): ChainedValidator;

public function nullOrDigit(string ...$additionalChars): ChainedValidator;
Expand Down
12 changes: 12 additions & 0 deletions library/Mixins/ChainedProperty.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Respect\Validation\Mixins;

use DateTimeImmutable;
use Respect\Validation\Validatable;

interface ChainedProperty
Expand Down Expand Up @@ -115,6 +116,17 @@ public function propertyDate(string $propertyName, string $format = 'Y-m-d'): Ch

public function propertyDateTime(string $propertyName, ?string $format = null): ChainedValidator;

/**
* @param "years"|"months"|"days"|"hours"|"minutes"|"seconds"|"microseconds" $type
*/
public function propertyDateTimeDiff(
string $propertyName,
string $type,
Validatable $rule,
?string $format = null,
?DateTimeImmutable $now = null,
): ChainedValidator;

public function propertyDecimal(string $propertyName, int $decimals): ChainedValidator;

public function propertyDigit(string $propertyName, string ...$additionalChars): ChainedValidator;
Expand Down
11 changes: 11 additions & 0 deletions library/Mixins/ChainedUndefOr.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Respect\Validation\Mixins;

use DateTimeImmutable;
use Respect\Validation\Validatable;

interface ChainedUndefOr
Expand Down Expand Up @@ -95,6 +96,16 @@ public function undefOrDate(string $format = 'Y-m-d'): ChainedValidator;

public function undefOrDateTime(?string $format = null): ChainedValidator;

/**
* @param "years"|"months"|"days"|"hours"|"minutes"|"seconds"|"microseconds" $type
*/
public function undefOrDateTimeDiff(
string $type,
Validatable $rule,
?string $format = null,
?DateTimeImmutable $now = null,
): ChainedValidator;

public function undefOrDecimal(int $decimals): ChainedValidator;

public function undefOrDigit(string ...$additionalChars): ChainedValidator;
Expand Down
11 changes: 11 additions & 0 deletions library/Mixins/ChainedValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Respect\Validation\Mixins;

use DateTimeImmutable;
use Respect\Validation\Validatable;

interface ChainedValidator extends
Expand Down Expand Up @@ -100,6 +101,16 @@ public function date(string $format = 'Y-m-d'): ChainedValidator;

public function dateTime(?string $format = null): ChainedValidator;

/**
* @param "years"|"months"|"days"|"hours"|"minutes"|"seconds"|"microseconds" $type
*/
public function dateTimeDiff(
string $type,
Validatable $rule,
?string $format = null,
?DateTimeImmutable $now = null,
): ChainedValidator;

public function decimal(int $decimals): ChainedValidator;

public function digit(string ...$additionalChars): ChainedValidator;
Expand Down
12 changes: 12 additions & 0 deletions library/Mixins/StaticKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Respect\Validation\Mixins;

use DateTimeImmutable;
use Respect\Validation\Validatable;

interface StaticKey
Expand Down Expand Up @@ -111,6 +112,17 @@ public static function keyDate(int|string $key, string $format = 'Y-m-d'): Chain

public static function keyDateTime(int|string $key, ?string $format = null): ChainedValidator;

/**
* @param "years"|"months"|"days"|"hours"|"minutes"|"seconds"|"microseconds" $type
*/
public static function keyDateTimeDiff(
int|string $key,
string $type,
Validatable $rule,
?string $format = null,
?DateTimeImmutable $now = null,
): ChainedValidator;

public static function keyDecimal(int|string $key, int $decimals): ChainedValidator;

public static function keyDigit(int|string $key, string ...$additionalChars): ChainedValidator;
Expand Down
11 changes: 11 additions & 0 deletions library/Mixins/StaticNot.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Respect\Validation\Mixins;

use DateTimeImmutable;
use Respect\Validation\Validatable;

interface StaticNot
Expand Down Expand Up @@ -95,6 +96,16 @@ public static function notDate(string $format = 'Y-m-d'): ChainedValidator;

public static function notDateTime(?string $format = null): ChainedValidator;

/**
* @param "years"|"months"|"days"|"hours"|"minutes"|"seconds"|"microseconds" $type
*/
public static function notDateTimeDiff(
string $type,
Validatable $rule,
?string $format = null,
?DateTimeImmutable $now = null,
): ChainedValidator;

public static function notDecimal(int $decimals): ChainedValidator;

public static function notDigit(string ...$additionalChars): ChainedValidator;
Expand Down
Loading