Signature
timezone_open(string $timezone): DateTimeZone|falsePurpose
timezone_open() is the procedural form of new DateTimeZone(...). The manual describes it as an alias of DateTimeZone::__construct(). You give it a timezone description and get back a DateTimeZone object. That object can be passed to DateTime, DateTimeImmutable, date_timezone_set(), timezone_offset_get() and related functions.
Use it when you write in a procedural style, or when you want a plain function call that gives you false for a bad value instead of an exception to catch.
Signature
Parameters and defaults
| Parameter | Type | Default | Meaning |
|---|---|---|---|
$timezone |
string |
none (required) | A timezone identifier such as Europe/Paris or UTC, a UTC offset such as +05:30, or a timezone abbreviation such as EST. |
There are no optional parameters. The function does not read or change the default timezone set by date_default_timezone_set(); it only builds an object for the value you pass.
Return value and failure cases
On success you get a DateTimeZone object. If the string is not a recognized timezone, the procedural function returns false and raises a warning. Empty strings and made-up names such as Mars/Base are failures. Always compare the result with false before you use it as an object.
The object-oriented constructor behaves differently. new DateTimeZone('Mars/Base') throws an exception rather than returning false.
Example 1: create a zone and convert a time
The fixed UTC input makes the result deterministic. The zone is created once, then used for the conversion and for an offset lookup.
$utc = new DateTimeImmutable('2024-01-15 12:00:00', timezone_open('UTC'));
$tokyo = timezone_open('Asia/Tokyo');
$local = $utc->setTimezone($tokyo);
echo json_encode([
'zone' => timezone_name_get($tokyo),
'local' => $local->format('Y-m-d H:i:s P'),
'offset' => timezone_offset_get($tokyo, $utc),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"zone":"Asia/Tokyo","local":"2024-01-15 21:00:00 +09:00","offset":32400}The offset is returned in seconds east of UTC, so Tokyo is 32400, which is nine hours.
Example 2: named zones versus fixed offsets
A region identifier carries daylight saving rules, so its offset depends on the date. A fixed offset string always has the same offset.
$london = timezone_open('Europe/London');
$winter = new DateTimeImmutable('2024-01-15 12:00:00', timezone_open('UTC'));
$summer = new DateTimeImmutable('2024-07-15 12:00:00', timezone_open('UTC'));
$fixed = timezone_open('+05:30');
echo json_encode([
'londonWinter' => timezone_offset_get($london, $winter),
'londonSummer' => timezone_offset_get($london, $summer),
'fixedName' => timezone_name_get($fixed),
'fixedOffset' => timezone_offset_get($fixed, $summer),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"londonWinter":0,"londonSummer":3600,"fixedName":"+05:30","fixedOffset":19800}London is at offset 0 in January and 3600 in July. The +05:30 zone stays at 19800 in both seasons.
Example 3: validate user-supplied names
When a timezone name comes from a form or a stored setting, wrap the call in a small helper that turns failure into null. The @ operator silences the warning here because the helper reports failure through its return value. Use it narrowly, only around the call you are handling.
function zoneOrNull(string $name): ?DateTimeZone
{
$zone = @timezone_open($name);
return $zone === false ? null : $zone;
}
$names = ['Europe/London', 'Mars/Base'];
$result = [];
foreach ($names as $name) {
$result[$name] = zoneOrNull($name) !== null;
}
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"Europe/London":true,"Mars/Base":false}Edge cases
- A timezone object is not a moment in time. It describes rules, so you need a date to learn the actual offset.
- Offsets such as
+05:30are accepted, but they have no daylight saving rules. A real region identifier is usually better for scheduling future events. - Abbreviations such as
ESTare accepted as timezone values, but they are less precise than region identifiers because one abbreviation can be used in several places. - Passing
UTCis the clearest way to request Coordinated Universal Time. - Creating a zone object does not change
date()or the default timezone for the script.
Common mistakes
- Not checking for
false. Passing the result straight into code that expectsDateTimeZonefails with a type error. - Inventing identifiers. Use names such as
America/New_York, not city nicknames or country names. - Expecting a fixed offset from a region. Region zones change offsets across the year.
- Hiding all warnings globally. Validate input and handle
falseexplicitly rather than suppressing errors across a whole script. - Confusing it with
date_default_timezone_set(). That function changes the default for later date calls.timezone_open()only returns an object.
Related functions
timezone_name_get()reads the name of a zone object.timezone_offset_get()returns the offset for a specific date.date_timezone_set()changes the zone of an existing date object.date_default_timezone_set()sets the script default.DateTimeZone::listIdentifiers()lists valid region identifiers.
Recap
timezone_open(string $timezone) builds a DateTimeZone from an identifier, offset or abbreviation and returns false with a warning when the value is not valid. It is an alias of DateTimeZone::__construct(), so the two accept the same input, but the function form reports failure through its return value. Check the return value, prefer region identifiers for real-world schedules, and ask for offsets using a concrete date.
Tested examples
$utc = new DateTimeImmutable('2024-01-15 12:00:00', timezone_open('UTC'));
$tokyo = timezone_open('Asia/Tokyo');
$local = $utc->setTimezone($tokyo);
echo json_encode([
'zone' => timezone_name_get($tokyo),
'local' => $local->format('Y-m-d H:i:s P'),
'offset' => timezone_offset_get($tokyo, $utc),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"zone":"Asia/Tokyo","local":"2024-01-15 21:00:00 +09:00","offset":32400}
$london = timezone_open('Europe/London');
$winter = new DateTimeImmutable('2024-01-15 12:00:00', timezone_open('UTC'));
$summer = new DateTimeImmutable('2024-07-15 12:00:00', timezone_open('UTC'));
$fixed = timezone_open('+05:30');
echo json_encode([
'londonWinter' => timezone_offset_get($london, $winter),
'londonSummer' => timezone_offset_get($london, $summer),
'fixedName' => timezone_name_get($fixed),
'fixedOffset' => timezone_offset_get($fixed, $summer),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"londonWinter":0,"londonSummer":3600,"fixedName":"+05:30","fixedOffset":19800}
function zoneOrNull(string $name): ?DateTimeZone
{
$zone = @timezone_open($name);
return $zone === false ? null : $zone;
}
$names = ['Europe/London', 'Mars/Base'];
$result = [];
foreach ($names as $name) {
$result[$name] = zoneOrNull($name) !== null;
}
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"Europe/London":true,"Mars/Base":false}