Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

shanahjr's avatar

How do I check if a string is a date string?

Please note that the date is coming from an excel file

    protected function validateDateFields(&$data, &$errors, $fieldName)
    {
        $date_format = $this->convertToPHPDateFormat($this->importMaster->getCriteria->date_format);

        if (isset($data[$fieldName])) {
            $value = $data[$fieldName];

            if (empty(trim($value))) {
                return [];
            }

            if (is_numeric($value)) {
                $timestamp = ($value - 25569) * 86400;

                try {
                    $date = Carbon::createFromTimestamp($timestamp);

                    if ($date == null || $date->format($date_format) !== Carbon::createFromTimestamp($timestamp)->format($date_format)) {
                        $errors[] = $this->getFieldName($fieldName) . ' has an Invalid value or is not in the provided format';
                        Logger::error('Date could not be changed', ["value" => $value]);
                    }

                } catch (\Throwable $th) {

                    if (function_exists($th->getMessage())) {
                        $errors[] = $this->getFieldName($fieldName) . ' ' . $th->getMessage();
                        Log::error("Date could not be changed number catch", ["value" => $value, "error" => $th.getMessage()]);
                        return;
                    } else {
                        $errors[] = $this->getFieldName($fieldName);
                        Log::error("Date could not be changed number catch", ["value" => $value]);
                        return;
                    }
                }


            } else {

                $isDateStringValid = strtotime($value);

                try {
                    // if ($isDateStringValid) {
                        $date = Carbon::createFromFormat($date_format, $value);
                        if ($date == false || $date->format($date_format) != $value) {
                            $errors[] = $this->getFieldName($fieldName) . ' has an Invalid value or is not in the provided format';
                            Log::error("Date could not be changed string", ["date" => $date, "value" => $value]);
                            return;
                        } else {
                            $data[$fieldName] = $date;
                            return;
                        }
                    // } else {
                    //     $errors[] = $this->getFieldName($fieldName) . ' has an Invalid value or is not in the provided format';
                    //     return;
                    // }
                } catch (\Throwable $e) {
                    if (function_exists($e->getMessage())) {
                        $errors[] = $this->getFieldName($fieldName) . ' has an Invalid value: ' . $e->getMessage();
                        // Log::error("Date could not be changed string catch", ["value" => $value, "error" => $e.getMessage()]);
                        return;
                    } else {
                        $errors[] = $this->getFieldName($fieldName) . ' has an Invalid value or is not in the provided format ';
                        // Log::error("Date could not be changed string catch", ["value" => $value]);
                        return;
                    }
                }


            }

        }

        return $errors;

    }

I have the above function which is meant to validate date fields.

The issue I am facing is in the else block of the is_numeric if statement.

The $value is "dfgfgdg" and the $format is "d/m/Y". For some reason the exception is not being caught within the function which results in my job crashing. The error I am getting is:

Error creating CustomerImportFromCSV instance:  {"error":"[object] (Carbon\Exceptions\InvalidFormatException(code: 0): Could not parse 'dfgdfg': Failed to parse time string (dfgdfg) at position 0 (d): The timezone could not be found in the database at /var/www/html/production/2024/07/17/ekyc/vendor/nesbot/carbon/src/Carbon/Traits/Creator.php:198)

If necessary my composer.json is below

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "require": {
        "php": "^7.3|^8.0",
        "barryvdh/laravel-dompdf": "^2.0",
        "barryvdh/laravel-snappy": "^1.0",
        "binaryk/laravel-restify": "6.12",
        "codedge/laravel-fpdf": "^1.10",
        "fruitcake/laravel-cors": "^2.0",
        "guzzlehttp/guzzle": "^7.0.1",
        "h4cc/wkhtmltoimage-amd64": "0.12.x",
        "h4cc/wkhtmltopdf-amd64": "0.12.x",
        "laravel/framework": "^8.75",
        "laravel/sanctum": "^2.11",
        "laravel/tinker": "^2.5",
        "maatwebsite/excel": "^3.1",
        "mpdf/mpdf": "^8.2",
        "pragmarx/google2fa": "^8.0",
        "predis/predis": "^2.0",
        "rap2hpoutre/laravel-log-viewer": "^2.2",
        "rappasoft/laravel-authentication-log": "*",
        "setasign/fpdi-tcpdf": "2.3",
        "simplesoftwareio/simple-qrcode": "^4.2",
        "spatie/laravel-activitylog": "^3.17",
        "spatie/pdf-to-image": "^1.2",
        "torann/geoip": "^3.0",
        "webklex/laravel-imap": "^5.2",
        "yajra/laravel-datatables-oracle": "^9.21"
    },
    "require-dev": {
        "facade/ignition": "^2.5",
        "fakerphp/faker": "^1.9.1",
        "laravel/sail": "^1.0.1",
        "mockery/mockery": "^1.4.4",
        "nunomaduro/collision": "^5.10",
        "phpunit/phpunit": "^9.5.10"
    },
    "autoload": {
        "psr-4": {
            "App\": "app/",
            "Database\Factories\": "database/factories/",
            "Database\Seeders\": "database/seeders/"
        }
    }

I have tried using the function strtotime($value) to check if the string is a valid date string but this did not work. Even though it worked when I tried it in a PHP REPL.

Trying to use the below function gives me the error that DateTime is undefined.

if (DateTime::createFromFormat($format, $value) !== false) {
  // it's a date
}

For some reason when the $isDateString if statement is uncommented, I start seeing errors about actual date strings. But when I comment it out, I only see the error about the single field that is not a date string.

What I am expecting is for the invalid format to be caught within the function and not outside of the function. All I am trying to accomplish is preventing the background job from prematurely terminating if an unexpected string is received.

0 likes
2 replies
Snapey's avatar

this is from one of my projects;

$this->excelDates is an array of columns that are expected to have dates

        try {
            foreach ($this->excelDates as $datecol) {
                $import->$datecol = ExcelDate::excelToDateTimeObject($import->$datecol)->format('Y-m-d');
            }
        } catch (\Throwable $th) {
            $message = sprintf('Error parsing Excel Date at %s:%s%s, importing for %s', $this->sheet, $datecol, $rowCount, System::find($this->flow->system_id)->name);
            Log::info($message);
            $this->errors->push($message);

            // throw new ExcelDateConversionError($message);
        }

But this is for XLS files that have a specific decimal number to represent a time.

Your code suggests the import might be a CSV file, in which case you should try parsing with Carbon.

Please or to participate in this conversation.