Validation icon indicating copy to clipboard operation
Validation copied to clipboard

v::date() is useless in some cases

Open badmansan opened this issue 4 years ago • 2 comments

Hi all. Try this code:

$date = '2021-03-123:12:01';
$format = 'Y-m-d H:i:s';

var_dump(Validator::date($format)->validate($date));

var_dump(date_parse_from_format($format, $date));

$dt = new DateTimeImmutable($date, new DateTimeZone('UTC'));
var_dump($dt);
var_dump($dt->format($format));

Expected validate result: false Instead we got: true

This is because of validate via date_parse_from_format() Yes, theoretically the date 2021-03-0123:12:01 is valid. Both date_parse_from_format() & DateTimeImmutable recognize it correctly. Both dates 2021-03-01 23:12:01 & 2021-03-0123:12:01 are correct in terms of both functions.

But we can't use that date directly. For example, if we try to insert it to db, we got error (something like date/time field value out of range).

So we must use new DateTimeImmutable('2021-03-0123:12:01')), check result, than use ->format('Y-m-d H:i:s') to get date in db format. But in this case the ::date() validator is useless because of this if

public function validate($input)
{
	if ($input instanceof DateTimeInterface
		|| $input instanceof DateTime) {
		return true;
	}

Move on. The date 21-3-123:12:01 is valid too:

var_dump(Validator::date('Y-m-d H:i:s')->validate('21-3-123:12:01'));

date_parse_from_format() & DateTimeImmutable recognize it as 2021-03-12 03:12:01 Is it valid? We can't now. Date 21-3-12 3:12:01 or 21-3-1 23:12:01 may be implied. Need a space to know for sure. Or (and this is the only true way) we need to use the specified format.

So, what conclusion have I come to. ::date() validator MUST check strict compliance with the format, otherwise the programmer has to do it. So, in fact, it is useless. I'm right?

badmansan avatar Feb 26 '20 20:02 badmansan

Hi, when a validation done on a on a string as input with no format specified the validation provides wrong result. For example try var_dump(Validator::date()->validate("a")); var_dump(Validator::date()->validate("0000"));

Expected result: false Instead we got: true

navin-raj avatar Mar 28 '20 16:03 navin-raj

Hi, when a validation done on a on a string as input with no format specified the validation provides wrong result. For example try var_dump(Validator::date()->validate("a")); var_dump(Validator::date()->validate("0000"));

Expected result: false Instead we got: true

@henriquemoody, I may be mistaken but I don't know if this is actually a bug, when a non-scalar value is passed to the validation method, the strtostring function is used to check the value.

Follows the types of format supported by the strtostring function

https://www.php.net/manual/en/datetime.formats.php

dcorrea777 avatar May 19 '20 01:05 dcorrea777

This has been fixed on the upcoming 2.3 release.

var_dump(Validator::date('Y-m-d H:i:s')->validate('21-3-123:12:01'));

This should now evaluate to bool(false). I'll close this as soon as this version hits packagist.

alganet avatar Feb 19 '23 18:02 alganet

The version 2.3 was released about a week ago.

This issue has been fixed, although it came with a trade-off (of course). I wrote something on the documentation of the DateTime rule to try to make it a bit clearer: https://respect-validation.readthedocs.io/en/2.3/rules/DateTime/#formats

Thank you for reporting! 🐼

henriquemoody avatar Feb 04 '24 15:02 henriquemoody