mirror of
https://github.com/Respect/Validation.git
synced 2024-06-04 23:02:16 +02:00
Create "Date" rule
This commit is contained in:
parent
c80524b457
commit
0db1cd6e1b
45
docs/Date.md
Normal file
45
docs/Date.md
Normal file
|
@ -0,0 +1,45 @@
|
|||
# Date
|
||||
|
||||
- `Date()`
|
||||
- `Date(string $format)`
|
||||
|
||||
Validates if input is a date. The `$format` argument should be in accordance to
|
||||
PHP's [date()](http://php.net/date) function, but only those are allowed:
|
||||
|
||||
Format | Description | Values
|
||||
--------|-----------------------------------------------------------------------|-------------------------
|
||||
`d` | Day of the month, 2 digits with leading zeros | 01 to 31
|
||||
`j` | Day of the month without leading zeros | 1 to 31
|
||||
`S` | English ordinal suffix for the day of the month, 2 characters | st, nd, rd or th
|
||||
`F` | A full textual representation of a month, such as January or March | January to December
|
||||
`m` | Numeric representation of a month, with leading zeros | 01 to 12
|
||||
`M` | A short textual representation of a month, three letters | Jan to Dec
|
||||
`n` | Numeric representation of a month, without leading zeros | 1 to 12
|
||||
`Y` | A full numeric representation of a year, 4 digits | Examples: 1988 or 2017
|
||||
`y` | A two digit representation of a year | Examples: 88 or 17
|
||||
|
||||
|
||||
When a `$format` is not given its default value is `Y-m-d`.
|
||||
|
||||
```php
|
||||
v::date()->validate('2017-12-31'); // true
|
||||
v::date()->validate('2020-02-29'); // true
|
||||
v::date()->validate('2019-02-29'); // false
|
||||
v::date('m/d/y')->validate('12/31/17'); // true
|
||||
v::date('F jS, Y')->validate('May 1st, 2017'); // true
|
||||
v::date('Ydm')->validate(20173112); // true
|
||||
```
|
||||
|
||||
## Changelog
|
||||
|
||||
Version | Description
|
||||
--------|-------------
|
||||
2.0.0 | Created
|
||||
|
||||
***
|
||||
See also:
|
||||
|
||||
- [DateTime](DateTime.md)
|
||||
- [MinimumAge](MinimumAge.md)
|
||||
- [LeapDate](LeapDate.md)
|
||||
- [LeapYear](LeapYear.md)
|
|
@ -130,6 +130,7 @@
|
|||
|
||||
- [Age](Age.md)
|
||||
- [Between](Between.md)
|
||||
- [Date](Date.md)
|
||||
- [DateTime](DateTime.md)
|
||||
- [LeapDate](LeapDate.md)
|
||||
- [LeapYear](LeapYear.md)
|
||||
|
@ -237,6 +238,7 @@
|
|||
- [Cpf](Cpf.md)
|
||||
- [CreditCard](CreditCard.md)
|
||||
- [CurrencyCode](CurrencyCode.md)
|
||||
- [Date](Date.md)
|
||||
- [DateTime](DateTime.md)
|
||||
- [Digit](Digit.md)
|
||||
- [Directory](Directory.md)
|
||||
|
|
46
library/Exceptions/DateException.php
Normal file
46
library/Exceptions/DateException.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Respect/Validation.
|
||||
*
|
||||
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||
*
|
||||
* For the full copyright and license information, please view the "LICENSE.md"
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Respect\Validation\Exceptions;
|
||||
|
||||
/**
|
||||
* @author Bruno Luiz da Silva <contato@brunoluiz.net>
|
||||
* @author Henrique Moody <henriquemoody@gmail.com>
|
||||
*/
|
||||
final class DateException extends ValidationException
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $defaultTemplates = [
|
||||
self::MODE_DEFAULT => [
|
||||
self::STANDARD => '{{name}} must be a valid date in the format {{sample}}',
|
||||
],
|
||||
self::MODE_NEGATIVE => [
|
||||
self::STANDARD => '{{name}} must not be a valid date in the format {{sample}}',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function configure($name, array $params = [])
|
||||
{
|
||||
$params['sample'] = date(
|
||||
$params['format'],
|
||||
strtotime('2005-12-30')
|
||||
);
|
||||
|
||||
return parent::configure($name, $params);
|
||||
}
|
||||
}
|
64
library/Rules/Date.php
Normal file
64
library/Rules/Date.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Respect/Validation.
|
||||
*
|
||||
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||
*
|
||||
* For the full copyright and license information, please view the "LICENSE.md"
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Respect\Validation\Rules;
|
||||
|
||||
use function date_parse_from_format;
|
||||
use function is_scalar;
|
||||
use function preg_match;
|
||||
use function sprintf;
|
||||
use Respect\Validation\Exceptions\ComponentException;
|
||||
|
||||
/**
|
||||
* Validates if input is a date.
|
||||
*
|
||||
* @author Bruno Luiz da Silva <contato@brunoluiz.net>
|
||||
* @author Henrique Moody <henriquemoody@gmail.com>
|
||||
*/
|
||||
final class Date extends AbstractRule
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $format;
|
||||
|
||||
/**
|
||||
* Initializes the rule.
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
* @throws ComponentException
|
||||
*/
|
||||
public function __construct(string $format = 'Y-m-d')
|
||||
{
|
||||
if (!preg_match('/^[djSFmMnYy\W]+$/', $format)) {
|
||||
throw new ComponentException(sprintf('"%s" is not a valid date format', $format));
|
||||
}
|
||||
|
||||
$this->format = $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate($input): bool
|
||||
{
|
||||
if (!is_scalar($input)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$info = date_parse_from_format($this->format, (string) $input);
|
||||
|
||||
return 0 === $info['error_count'] && 0 === $info['warning_count'];
|
||||
}
|
||||
}
|
|
@ -51,6 +51,7 @@ use Respect\Validation\Rules\Key;
|
|||
* @method static Validator currencyCode()
|
||||
* @method static Validator cpf()
|
||||
* @method static Validator creditCard(string $brand = null)
|
||||
* @method static Validator date(string $format = 'Y-m-d')
|
||||
* @method static Validator dateTime(string $format = null)
|
||||
* @method static Validator digit(string $additionalChars = null)
|
||||
* @method static Validator directory()
|
||||
|
|
37
tests/integration/rules/date.phpt
Normal file
37
tests/integration/rules/date.phpt
Normal file
|
@ -0,0 +1,37 @@
|
|||
--FILE--
|
||||
<?php
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use Respect\Validation\Exceptions\DateException;
|
||||
use Respect\Validation\Exceptions\NestedValidationException;
|
||||
use Respect\Validation\Validator as v;
|
||||
|
||||
try {
|
||||
v::date()->check('2018-01-29T08:32:54+00:00');
|
||||
} catch (DateException $exception) {
|
||||
echo $exception->getMessage().PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
v::not(v::date())->check('2018-01-29');
|
||||
} catch (DateException $exception) {
|
||||
echo $exception->getMessage().PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
v::date()->assert('2018-01-29T08:32:54+00:00');
|
||||
} catch (NestedValidationException $exception) {
|
||||
echo $exception->getFullMessage().PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
v::not(v::date('d/m/Y'))->assert('29/01/2018');
|
||||
} catch (NestedValidationException $exception) {
|
||||
echo $exception->getFullMessage().PHP_EOL;
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
"2018-01-29T08:32:54+00:00" must be a valid date in the format "2005-12-30"
|
||||
"2018-01-29" must not be a valid date in the format "2005-12-30"
|
||||
- "2018-01-29T08:32:54+00:00" must be a valid date in the format "2005-12-30"
|
||||
- "29/01/2018" must not be a valid date in the format "30/12/2005"
|
91
tests/unit/Rules/DateTest.php
Normal file
91
tests/unit/Rules/DateTest.php
Normal file
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Respect/Validation.
|
||||
*
|
||||
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||
*
|
||||
* For the full copyright and license information, please view the "LICENSE.md"
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Respect\Validation\Rules;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use Respect\Validation\Exceptions\ComponentException;
|
||||
use Respect\Validation\Test\RuleTestCase;
|
||||
|
||||
/**
|
||||
* @group rule
|
||||
*
|
||||
* @covers \Respect\Validation\Rules\Date
|
||||
*
|
||||
* @author Bruno Luiz da Silva <contato@brunoluiz.net>
|
||||
* @author Henrique Moody <henriquemoody@gmail.com>
|
||||
*/
|
||||
final class DateTest extends RuleTestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerForValidInput(): array
|
||||
{
|
||||
return [
|
||||
[new Date(), '2017-12-31'],
|
||||
[new Date('m/d/y'), '12/31/17'],
|
||||
[new Date('F jS, Y'), 'May 1st, 2017'],
|
||||
[new Date('Ydm'), 20173112],
|
||||
[new Date(), '2020-02-29'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function providerForInvalidInput(): array
|
||||
{
|
||||
return [
|
||||
[new Date(), '1988-02-30'],
|
||||
[new Date('d/m/y'), '12/31/17'],
|
||||
[new Date(), '2019-02-29'],
|
||||
[new Date(), new DateTime()],
|
||||
[new Date(), new DateTimeImmutable()],
|
||||
[new Date(), ''],
|
||||
];
|
||||
}
|
||||
|
||||
public function validFormatsProvider(): array
|
||||
{
|
||||
return [
|
||||
['Y-m-d H:i:s'],
|
||||
['c'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*
|
||||
* @dataProvider validFormatsProvider
|
||||
*/
|
||||
public function shouldThrowAnExceptionWhenFormatIsNotValid(string $format): void
|
||||
{
|
||||
$this->expectException(ComponentException::class);
|
||||
|
||||
new Date($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function shouldPassFormatToParameterToException(): void
|
||||
{
|
||||
$format = 'F jS, Y';
|
||||
$equals = new Date($format);
|
||||
$exception = $equals->reportError('input');
|
||||
|
||||
self::assertSame($format, $exception->getParam('format'));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue