{"record":{"id":"56fe317ccc24cf15","repo":"PHPOffice/PhpSpreadsheet","slug":"non-string-value-supplied-for-iso-date-conversion","errorCode":null,"errorMessage":"Non-string value supplied for Iso Date conversion","messagePattern":"Non-string value supplied for Iso Date conversion","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Shared/Date.php","lineNumber":166,"sourceCode":"        if ($timeZone instanceof DateTimeZone || $timeZone === null) {\n            return $timeZone;\n        }\n        if (in_array($timeZone, DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC))) {\n            return new DateTimeZone($timeZone);\n        }\n\n        throw new PhpSpreadsheetException('Invalid timezone');\n    }\n\n    /**\n     * @param mixed $value Converts a date/time in ISO-8601 standard format date string to an Excel\n     *                         serialized timestamp.\n     *                     See https://en.wikipedia.org/wiki/ISO_8601 for details of the ISO-8601 standard format.\n     */\n    public static function convertIsoDate(mixed $value, ?int $calendar = null): float|int\n    {\n        if (!is_string($value)) {\n            throw new Exception('Non-string value supplied for Iso Date conversion');\n        }\n\n        $date = new DateTime($value);\n        $dateErrors = DateTime::getLastErrors();\n\n        if (is_array($dateErrors) && ($dateErrors['warning_count'] > 0 || $dateErrors['error_count'] > 0)) {\n            throw new Exception(\"Invalid string $value supplied for datatype Date\");\n        }\n\n        $newValue = self::dateTimeToExcel($date, $calendar);\n\n        if (preg_match('/^\\s*\\d?\\d:\\d\\d(:\\d\\d([.]\\d+)?)?\\s*(am|pm)?\\s*$/i', $value) == 1) {\n            $newValue = fmod($newValue, 1.0);\n        }\n\n        return $newValue;\n    }\n","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Shared/Date.php#L148-L184","documentation":"Date::convertIsoDate() converts ISO-8601 date strings to Excel serials and rejects any non-string input immediately (src/PhpSpreadsheet/Shared/Date.php:166). It is called from Cell::setValueExplicit() with DataType::TYPE_ISO_DATE (src/PhpSpreadsheet/Cell/Cell.php:344) and from the Ods reader when converting date-typed cell values, so ints, floats, DateTime objects, or null bound as ISO dates all fail.","triggerScenarios":"$cell->setValueExplicit(20240101, DataType::TYPE_ISO_DATE) — numeric literal instead of 'YYYY-MM-DD'; an import mapping that assigns DateTime objects or unix timestamps with TYPE_ISO_DATE; ODS files whose date cells contain unexpected node types.","commonSituations":"Binders/ETL code that maps DB column types to TYPE_ISO_DATE but passes native values; glue code ported from libraries that accepted mixed input; test fixtures using int dates.","solutions":["Convert to an ISO string first: $cell->setValueExplicit($dt->format('Y-m-d\\TH:i:s'), DataType::TYPE_ISO_DATE)","For DateTime objects, store as a numeric Excel serial instead: setValueExplicit(Date::PHPToExcel($dt), DataType::TYPE_NUMERIC)","Guard with is_string($value) before binding as TYPE_ISO_DATE"],"exampleFix":"// before\n$cell->setValueExplicit(20240101, DataType::TYPE_ISO_DATE); // throws\n\n// after\n$cell->setValueExplicit('2024-01-01', DataType::TYPE_ISO_DATE);\n// or for DateTime objects:\n$cell->setValueExplicit(\n    \\PhpOffice\\PhpSpreadsheet\\Shared\\Date::PHPToExcel($dateTime),\n    DataType::TYPE_NUMERIC\n);","handlingStrategy":"type-guard","validationCode":"use PhpOffice\\PhpSpreadsheet\\Cell\\DataType;\n\nif (!is_string($value)) {\n    $value = match (true) {\n        $value instanceof \\DateTime => $value->format('Y-m-d\\TH:i:s'),\n        default => (string) $value,\n    };\n}\n$cell->setValueExplicit($value, DataType::TYPE_ISO_DATE);","typeGuard":"function isIsoDateString(mixed $value): bool\n{\n    return is_string($value) && preg_match('/^\\d{4}-\\d{2}-\\d{2}/', $value) === 1;\n}","tryCatchPattern":null,"preventionTips":["Only bind TYPE_ISO_DATE with strings you produced via format()","Store DateTime objects as numeric serials (Date::PHPToExcel) with TYPE_NUMERIC","Add is_string() guards in import mappers that feed TYPE_ISO_DATE"],"tags":["date","type-mismatch","value-binder","cell-api"],"backgroundTag":"type-mismatch-argument","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}