{"record":{"id":"0cc91fe87a76a472","repo":"briannesbitt/Carbon","slug":"absolute-timezone-offset-cannot-be-greater-than-99","errorCode":null,"errorMessage":"Absolute timezone offset cannot be greater than 99.","messagePattern":"Absolute timezone offset cannot be greater than 99\\.","errorType":"exception","errorClass":"InvalidTimeZoneException","httpStatus":null,"severity":"error","filePath":"src/Carbon/CarbonTimeZone.php","lineNumber":41,"sourceCode":"use Throwable;\n\nclass CarbonTimeZone extends DateTimeZone\n{\n    use LocalFactory;\n\n    public const MAXIMUM_TIMEZONE_OFFSET = 99;\n\n    public function __construct(string|int|float $timezone)\n    {\n        $this->initLocalFactory();\n\n        parent::__construct(static::getDateTimeZoneNameFromMixed($timezone));\n    }\n\n    protected static function parseNumericTimezone(string|int|float $timezone): string\n    {\n        if (abs((float) $timezone) > static::MAXIMUM_TIMEZONE_OFFSET) {\n            throw new InvalidTimeZoneException(\n                'Absolute timezone offset cannot be greater than '.\n                static::MAXIMUM_TIMEZONE_OFFSET.'.',\n            );\n        }\n\n        return ($timezone >= 0 ? '+' : '').ltrim((string) $timezone, '+').':00';\n    }\n\n    protected static function getDateTimeZoneNameFromMixed(string|int|float $timezone): string\n    {\n        if (\\is_string($timezone)) {\n            $timezone = preg_replace('/^\\s*([+-]\\d+)(\\d{2})\\s*$/', '$1:$2', $timezone);\n        }\n\n        if (is_numeric($timezone)) {\n            return static::parseNumericTimezone($timezone);\n        }\n","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/briannesbitt/Carbon/blob/b13f05955dcfd7da71d60af745fd148cbdb73505/src/Carbon/CarbonTimeZone.php#L23-L59","documentation":"When a numeric value is passed to CarbonTimeZone (directly or via Carbon::now($tz) etc.), it is interpreted as an HOUR offset and formatted as '+H:MM' for PHP's DateTimeZone. Because DateTimeZone rejects offsets beyond roughly +/-100 hours, Carbon caps the absolute offset at MAXIMUM_TIMEZONE_OFFSET (99) and throws InvalidTimeZoneException above that (src/Carbon/CarbonTimeZone.php:41). Real-world offsets never exceed +/-14, so values above 99 are almost always a unit mistake.","triggerScenarios":"new CarbonTimeZone(3600) (Unix seconds mistaken for hours); CarbonTimeZone::create(-100); Carbon::now(1690000000) (an epoch timestamp landing in the timezone parameter); numeric strings like '105'.","commonSituations":"Passing a UTC offset in seconds or minutes instead of hours; forwarding an epoch timestamp into a timezone argument; sign errors or duplicated minus signs ('--5'); timezone IDs (integers) confused with offsets.","solutions":["Pass the offset in hours within +/-14, or a '+05:30'-style string: CarbonTimeZone::create(-5), CarbonTimeZone::create('+05:30')","Pass a timezone name: 'UTC', 'Europe/Paris', 'America/New_York'","If the number is seconds, convert first: CarbonTimeZone::create($seconds / 3600) — or better, name the zone explicitly"],"exampleFix":"// before\n$tz = new \\Carbon\\CarbonTimeZone(3600); // seconds mistaken for hours\n\n// after\n$tz = new \\Carbon\\CarbonTimeZone(1); // +01:00\n// or explicit\n$tz = new \\Carbon\\CarbonTimeZone('+01:00');","handlingStrategy":"validation","validationCode":"if (is_numeric($tz) && \\abs((float) $tz) > \\Carbon\\CarbonTimeZone::MAXIMUM_TIMEZONE_OFFSET) {\n    throw new InvalidArgumentException(\n        'Timezone offset must be hours within ±14 (got '.$tz.') — did you pass seconds or a timestamp?'\n    );\n}\n$timezone = new \\Carbon\\CarbonTimeZone($tz);","typeGuard":"/** Narrow a timezone-ish value to a safe CarbonTimeZone input */\nfunction toTimezoneInput(mixed $tz): string|int|float\n{\n    if (is_numeric($tz) && \\abs((float) $tz) > 14) {\n        throw new InvalidArgumentException('Numeric timezone must be an hour offset within ±14');\n    }\n    return $tz;\n}","tryCatchPattern":null,"preventionTips":["Numeric timezone values are HOURS (±14 max in reality), not seconds or timestamps","Prefer named zones ('Europe/Paris') or '+05:30' strings over raw numbers","Never forward epoch timestamps into timezone parameters; check types at the boundary"],"tags":["carbon","carbon-timezone","timezone-offset","validation","unit-mistake"],"backgroundTag":"invalid-timezone-offset","analyzedSha":"b13f05955dcfd7da71d60af745fd148cbdb73505","analyzedAt":"2026-08-17T04:40:56.953Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}