The situation, I use twig and when a user put by mistake a date like 15.05.20177 (European format, we use only this one) twig can't parse the date.
("DateTime::__construct(): Failed to parse time string (12.04.20177) at position 10 (7): Unexpected character").
I have tried to preg_match, string compare, date compare but nothing works...
if (!preg_match("/^[0-9]{2}.[0-9]{2}.[0-9]{4}$/", $date)) {
throw new RuntimeException("Bug of year 10'000.");
}
or
$dateToCompare = strtotime($date);
$maxDate = strtotime("31.12.9999");
if ($dateToCompare > $maxDate) {
throw new RuntimeException("Bug of year 10'000.");
}
or
if ($date > strtotime("31.12.9999")) {
throw new RuntimeException("Bug of year 10'000.");
}
The fix can be add here:
$this->twig->addFilter(new Twig_SimpleFilter('date', function($date, $formatOrOptions = null, $timezone = null) {
// Handle a larger option array but keep the backward compatibility with the Twig date helper
$defaults = [
'format' => null,
'timezone' => null,
'empty_output' => ''
];
if ($formatOrOptions == null || is_string($formatOrOptions)) {
$options = array_merge($defaults, ['format'=>$formatOrOptions, 'timezone'=> $timezone]);
}
elseif (is_array($formatOrOptions)) {
if ($diff = array_diff(array_keys($formatOrOptions), array_keys($defaults))) {
throw new RuntimeException("Invalid options: [".implode(', ', $diff)."]");
}
$options = array_merge($defaults, $formatOrOptions);
}
else {
throw new RuntimeException("First filter parameter must be a string or an array");
}
// This is because by default Twig return the today date for null values
if ($date == null || $date == '' || $date == '0000-00-00'){
return $options['empty_output'];
}
return twig_date_format_filter($this->twig, $date, $options['format'], $options['timezone']);
Thanks, and sorry for the "stupid" question :)
Instead of passing the string to Twig, you can try and pass a DateTime Object. This way, the date format validation can be done in the PHP code directly. Before passing the variable to your Twig environment, you should try and build the DateTime Object like so :
$myDate = DateTime::createFromFormat('d.m.Y', $stringDate);
You should then check the contents of the date variable. If it's false, then the parsing failed. Check it this way :
// Do a strict equality check here
if ($myDate === false) {
throw new RuntimeException("Invalid date");
}
Of course, handle your exception in the way you best see fit according to your needs. This is just an example
You can then pass the $myDate variable instead of the string and integrate it in your twig template
{{ myDate|date(d.m.Y) }}