{"record":{"id":"14221dc2e3dbaa7c","repo":"symfony/finder","slug":"don-t-understand-s-as-a-date-test","errorCode":null,"errorMessage":"Don't understand \"%s\" as a date test.","messagePattern":"Don't understand \"(.+?)\" as a date test\\.","errorType":"validation","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"Comparator/DateComparator.php","lineNumber":29,"sourceCode":"\nnamespace Symfony\\Component\\Finder\\Comparator;\n\n/**\n * DateCompare compiles date comparisons.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass DateComparator extends Comparator\n{\n    /**\n     * @param string $test A comparison string\n     *\n     * @throws \\InvalidArgumentException If the test is not understood\n     */\n    public function __construct(string $test)\n    {\n        if (!preg_match('#^\\s*(==|!=|[<>]=?|after|since|before|until)?\\s*(.+?)\\s*$#i', $test, $matches)) {\n            throw new \\InvalidArgumentException(\\sprintf('Don\\'t understand \"%s\" as a date test.', $test));\n        }\n\n        try {\n            $date = new \\DateTimeImmutable($matches[2]);\n            $target = $date->format('U');\n        } catch (\\Exception) {\n            throw new \\InvalidArgumentException(\\sprintf('\"%s\" is not a valid date.', $matches[2]));\n        }\n\n        $operator = $matches[1] ?: '==';\n        if ('since' === $operator || 'after' === $operator) {\n            $operator = '>';\n        }\n\n        if ('until' === $operator || 'before' === $operator) {\n            $operator = '<';\n        }\n","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/symfony/finder/blob/4d6c057bfd67c5a93e8025c85ca9364cba7e260a/Comparator/DateComparator.php#L11-L47","documentation":"DateComparator's constructor parses the test string with a regex for an optional operator followed by a date expression; if the regex cannot extract an operator+date, it throws InvalidArgumentException saying it cannot understand the string as a date test. Note the regex is permissive, so this rarely fires for non-null strings — but null or structurally impossible input hits it.","triggerScenarios":"new DateComparator($test) where $test does not match '#^\\s*(==|!=|[<>]=?|after|since|before|until)?\\s*(.+?)\\s*$#i' — practically only null passed where a string is expected (typed as string) or empty/non-string coercion edge cases in Finder's ->date() calls.","commonSituations":"Passing null to Finder::date(), calling ->date('') via dynamic config, mistyping so the variable is null, frameworks passing user input unvalidated.","solutions":["Pass a non-empty string containing an optional operator and a parsable date, e.g. 'since yesterday' or '> 2024-01-01'","Validate the input is a non-null, non-empty string before calling DateComparator/Finder::date()","If the date itself is bad (regex matches but DateTime fails), you'll get the sibling 'is not a valid date' error — fix the date string instead"],"exampleFix":"// before\n$finder->date($userInput); // null -> \"Don't understand \\\"\\\" as a date test.\"\n// after\n$finder->date(is_string($userInput) && $userInput !== '' ? $userInput : 'since 1970-01-01');","handlingStrategy":"validation","validationCode":"if (!is_string($test) || trim($test) === '') { throw new \\InvalidArgumentException('Date test must be a non-empty string'); }","typeGuard":"function isNonEmptyString(mixed $v): bool { return is_string($v) && trim($v) !== ''; }","tryCatchPattern":"try { $finder->date($test); } catch (\\InvalidArgumentException $e) { /* handle bad date test */ }","preventionTips":["Always pass non-empty strings to Finder::date() / DateComparator","Coalesce null config values to a sane default before constructing","Validate user-supplied date expressions early at the boundary"],"tags":["dates","parsing","invalid-argument"],"backgroundTag":"invalid-argument-format","analyzedSha":"4d6c057bfd67c5a93e8025c85ca9364cba7e260a","analyzedAt":"2026-09-13T07:49:33.433Z","contentChangedAt":"2026-09-13T07:49:33.433Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}