I have as scenario where the $string
variable sent to DateTime::modify($string)
is read from a database edited by users, how can i validate that $string
is a proper string for DateTime::modify()
?

- 21,025
- 5
- 26
- 57

- 437
- 1
- 6
- 17
-
May this link will help you. http://stackoverflow.com/questions/16075159/check-if-a-string-is-a-valid-date-using-datetime-tryparse – Ravi Hirani Jan 20 '16 at 12:15
-
@RaviHirani Your link regards a C# question which is similar but I'm not sure the implementation suggested there can be done with PHP? – FroboZ Jan 20 '16 at 12:18
4 Answers
try this function for validating time stamp string based on the format
function validateDate($date, $format = 'Y-m-d H:i:s')
{
$d = DateTime::createFromFormat($format, $date);
return $d && $d->format($format) == $date;
}

- 1
- 1

- 1,554
- 13
- 33
-
I am using this function to check the format of the date before applying the modify function for it. I need to validate the string that modifies a correctly formated date the string should be validated to be a string that DateTime::modify() can understand. – FroboZ Jan 20 '16 at 12:07
-
-
-
@systemovich to make sure you are able to construct proper timestamp from sent string which ensure a proper string – Sivagopal Manpragada Jan 28 '16 at 09:37
It's generally best practice to check the user input before it is saved to the database so you can be confident of it on the way out.
You could use a try/catch block as well:
try {
$date = new DateTime('2016-12-12');
$date->modify('+1 dayBLA');
echo $date->format('Y-m-d');
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
EDIT: after looking at this, if the string passed to modify
is invalid (not the date string as I originally supposed), your code will throw a Warning
not an exception.
You may be able to trigger a Warning
to temporarily be treated like an exception with set_error_handler
.
function warning_handler($errno, $errstr, $errfile, $errline, array $errcontext) {
throwErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler('warning_handler', E_WARNING);
try {
$date = new DateTime('2016-12-12');
$date->modify('+1 daybla');
echo $date->format('Y-m-d');
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
restore_error_handler();
However, this is starting to look a bit nasty. It might be cleaner (in your code, not your logs probably) to compare the date before and after the modify
method is called to see if they are different.
$date = new DateTime('2016-12-12');
$origDate = clone $date; //I believe this will get you an independent object
$date->modify('+1 daybla');
if ($origDate == $date) {
echo "Bad value passed to modify, probably a warning in the logs :(";
}

- 17,195
- 8
- 42
- 58
-
I agree the input should be checked before being entered into the database and I do but I want to validate on this end as well if possible- just in case. I tried adding a try and catch as you suggested but this still raises a warning when modify fails? – FroboZ Jan 20 '16 at 12:13
-
I was just noticing that too - after looking around I'm not seeing a great way to do this. Obviously a regex on the string you are passing to `modify` would be best, but the strings that method takes seem to be hugely disparate. Maybe you could solve by being more restrictive about the user input e.g. three inputs: 1) `+`/`-`, 2) `hour`/`day` 3) count (an int). I edited the answer with a few other options you can try - good luck! – pherris Jan 20 '16 at 12:34
You could do something like this, and call it before you pass the string into your actual date:
function modifyIsValid($modifyString) {
$d = new DateTime();
$isValid = $d->modify($modifyString);
if ($isValid === false) {
return false;
}
return true;
}
->modify()
returns false is the string passed is not valid, although it will also throw up an E_Warning
which is not ideal.
$d = new DateTime();
$string = 'not a valid modifier';
if (modifyIsValid($string)) {
// Continue
} else {
// Print a friendly error message.
}
You can find more information about it in the manual: http://php.net/manual/en/datetime.modify.php
Hope it helps.

- 2,606
- 1
- 12
- 20
-
This looks like a good way to validate the string but I need to handle the warning, would this be a scenario where it's maybe okay to simply suppress the warning? – FroboZ Jan 20 '16 at 12:15
-
@ChristopherKarlsson That could be one potential way of getting rid of the error, afterall even you are supressing the error, you are still handling it so it should be fine. The other way to perform the check would most likely to use regex to validate the string against all the valid formats found here: http://php.net/manual/en/datetime.formats.php – Mikey Jan 20 '16 at 12:20
-
I will accept this answer because it seems to be the closest you can get to do a clean validation even if it raises a warning, I will handle the warning as suggested in @pherris answer. – FroboZ Jan 20 '16 at 13:04
Bit late to the party here, this works perfectly for me...
function isDateModifyValid($String)
{
if (strlen($String) == 0) { return false; }
$now = new \DateTime(null, new \DateTimeZone("UTC"));
$rtn = false; // Default return value
@$now->modify($String) && $rtn = true;
// If modify($string) fails, $rtn won't set to true, else $rtn will set to true
// ^ ^ @ suppress error
return $rtn;
}
//TEST DATA
foreach (array("+1 hour", "+2 hour, -5 minutes", "12:00", "dsfv", "13:00, + 1 hour", "Yesterday, 12:00", "Neext weeekc", "Next month") as $testString)
{
if (isDateModifyValid($testString))
{
echo "VALID ::: $testString\n";
} else {
echo "INVALID ::: $testString\n";
}
}
VALID ::: +1 hour
VALID ::: +2 hour, -5 minutes
VALID ::: 12:00
INVALID ::: dsfv
VALID ::: 13:00, + 1 hour
VALID ::: Yesterday, 12:00
INVALID ::: Neext weeekc
VALID ::: Next month

- 4,671
- 7
- 34
- 55