{"record":{"id":"4ffa11c64bb19a06","repo":"PHPOffice/PhpSpreadsheet","slug":"invalid-timezone-timezonename","errorCode":null,"errorMessage":"Invalid timezone {$timezoneName}","messagePattern":"Invalid timezone (.+?)","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Shared/TimeZone.php","lineNumber":69,"sourceCode":"    {\n        return self::$timezone;\n    }\n\n    /**\n     *    Return the Timezone offset used for date/time conversions to/from UST\n     * This requires both the timezone and the calculated date/time to allow for local DST.\n     *\n     * @param ?string $timezoneName The timezone for finding the adjustment to UST\n     * @param float|int $timestamp PHP date/time value\n     *\n     * @return int Number of seconds for timezone adjustment\n     */\n    public static function getTimeZoneAdjustment(?string $timezoneName, $timestamp): int\n    {\n        $timezoneName = $timezoneName ?? self::$timezone;\n        $dtobj = Date::dateTimeFromTimestamp(\"$timestamp\");\n        if (!self::validateTimeZone($timezoneName)) {\n            throw new PhpSpreadsheetException(\"Invalid timezone $timezoneName\");\n        }\n        $dtobj->setTimeZone(new DateTimeZone($timezoneName));\n\n        return $dtobj->getOffset();\n    }\n}\n","sourceCodeStart":51,"sourceCodeEnd":76,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Shared/TimeZone.php#L51-L76","documentation":"Thrown by TimeZone::getTimeZoneAdjustment() when the timezone name supplied (or the globally configured one via TimeZone::setTimeZone()) fails validateTimeZone(). The method then builds a DateTimeZone, which requires a valid IANA zone identifier (e.g. 'Europe/Paris', 'UTC'); abbreviations like 'CST' or made-up strings are rejected.","triggerScenarios":"Calling TimeZone::getTimeZoneAdjustment($tzName, $timestamp) directly, or after TimeZone::setTimeZone($bad) — note setTimeZone() itself only returns false on a bad name, so a silent failure there resurfaces as this exception at adjustment time. Typical bad inputs: 'CST', 'GMT+2', 'Eastern', trailing whitespace, or null falling back to a default that was never configured.","commonSituations":"Feeding user-profile timezone strings or $_POST/DB values straight into the API; config files with 'timezone: EST' instead of IANA names; setTimeZone() return value ignored so the bad value persists until a date conversion runs.","solutions":["Use full IANA identifiers everywhere ('America/New_York', 'Europe/Berlin', 'UTC') and normalize input before use.","Check the setter's return: if (!TimeZone::setTimeZone($tz)) { /* reject */ } — never ignore it, since the failure converts into this later exception.","Validate user-supplied names against DateTimeZone::listIdentifiers() (or TimeZone::validateTimeZone()) at the input boundary and keep a safe default.","Catch PhpSpreadsheetException around date-heavy export code and map it to a configuration error message naming the bad timezone."],"exampleFix":"// before\n\\PhpOffice\\PhpSpreadsheet\\Shared\\TimeZone::setTimeZone('CST'); // returns false, ignored\n$adjust = \\PhpOffice\\PhpSpreadsheet\\Shared\\TimeZone::getTimeZoneAdjustment(null, $ts);\n// Invalid timezone CST\n\n// after\n$tz = in_array($userTz, DateTimeZone::listIdentifiers(), true) ? $userTz : 'UTC';\nif (!\\PhpOffice\\PhpSpreadsheet\\Shared\\TimeZone::setTimeZone($tz)) {\n    throw new RuntimeException(\"Unusable timezone: $tz\");\n}","handlingStrategy":"validation","validationCode":"$valid = in_array($tzName, DateTimeZone::listIdentifiers(), true)\n    || $tzName === 'UTC';\nif (!$valid) { $tzName = 'UTC'; /* or reject */ }\n$adjust = \\PhpOffice\\PhpSpreadsheet\\Shared\\TimeZone::getTimeZoneAdjustment($tzName, $ts);","typeGuard":"function validTimeZoneOrNull(?string $tz): ?string\n{\n    return ($tz !== null && (TimeZone::validateTimeZone($tz) || in_array($tz, DateTimeZone::listIdentifiers(), true)))\n        ? $tz : null; // null → caller uses safe default\n}","tryCatchPattern":"try { $adjust = TimeZone::getTimeZoneAdjustment($tzName, $ts); }\ncatch (\\PhpOffice\\PhpSpreadsheet\\Exception $e) {\n    if (str_contains($e->getMessage(), 'Invalid timezone')) {\n        $adjust = TimeZone::getTimeZoneAdjustment('UTC', $ts); // safe fallback\n    } else { throw $e; }\n}","preventionTips":["Store and accept only IANA identifiers ('Europe/Berlin'), never abbreviations like 'CST' or offsets like 'GMT+2'.","Never ignore the boolean return of TimeZone::setTimeZone() — a silent false becomes this exception later.","Validate timezone strings at the input boundary (user profiles, config) with DateTimeZone::listIdentifiers()."],"tags":["timezone","configuration","date-time","phpspreadsheet"],"backgroundTag":"invalid-timezone","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}