Signature
timezone_offset_get(DateTimeZone $object, DateTimeInterface $datetime): intPurpose
timezone_offset_get() tells you how many seconds a time zone is ahead of or behind UTC at a particular moment. It is the procedural alias of DateTimeZone::getOffset(), so both forms give the same result. Pick whichever matches your code style.
The offset depends on the moment you ask about. Many zones change offset when daylight saving time starts or ends, and the second argument supplies the instant to evaluate.
Signature
Parameters
$object: theDateTimeZonewhose offset you want. It can be a named region such asEurope/Paris, a fixed offset such as+05:45, orUTC. It is required and has no default.$datetime: anyDateTimeInterfaceobject, such asDateTimeorDateTimeImmutable. Only the instant it represents is used. The time zone attached to this object does not change the answer, because you are asking about$object. It is required and has no default.
Return value and failures
The function returns an int: the offset from UTC in seconds. Positive values are east of UTC (for example 3600 for UTC+01:00) and negative values are west (for example -18000 for UTC-05:00).
There is no false return to check. Failures surface as exceptions or errors instead. An invalid zone name makes the DateTimeZone constructor throw before you reach this function. Passing arguments of the wrong type, such as a string where a DateTimeZone is expected, throws a TypeError.
Example 1: the same zone in winter and summer
Paris is UTC+01:00 in January and UTC+02:00 in July. The same zone object returns a different offset depending on the date you pass.
date_default_timezone_set('UTC');
$tz = new DateTimeZone('Europe/Paris');
$winter = new DateTimeImmutable('2024-01-15 12:00:00', new DateTimeZone('UTC'));
$summer = new DateTimeImmutable('2024-07-15 12:00:00', new DateTimeZone('UTC'));
echo json_encode([timezone_offset_get($tz, $winter), timezone_offset_get($tz, $summer)]), "\n";[3600,7200]
Example 2: comparing several zones
One reference date can be used to compare different kinds of zones, including a fixed-offset zone. Fixed offsets and UTC return the same value for any date.
date_default_timezone_set('UTC');
$date = new DateTime('2024-03-01 00:00:00');
$zones = ['Asia/Kolkata', 'America/New_York', 'UTC', '+05:45'];
$result = [];
foreach ($zones as $name) {
$result[$name] = timezone_offset_get(new DateTimeZone($name), $date);
}
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"Asia/Kolkata":19800,"America/New_York":-18000,"UTC":0,"+05:45":20700}
Example 3: a daylight saving boundary
In 2024, New York switched to daylight saving time at 07:00:00 UTC on 10 March. One second earlier the offset is -18000. At the switch it becomes -14400. The last value shows the alias matches the method form.
date_default_timezone_set('UTC');
$tz = new DateTimeZone('America/New_York');
$utc = new DateTimeZone('UTC');
$before = new DateTimeImmutable('2024-03-10 06:59:59', $utc);
$after = new DateTimeImmutable('2024-03-10 07:00:00', $utc);
echo json_encode([
'before' => timezone_offset_get($tz, $before),
'after' => timezone_offset_get($tz, $after),
'same' => $tz->getOffset($after) === timezone_offset_get($tz, $after),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"before":-18000,"after":-14400,"same":true}
Edge cases
- Transitions: the answer is based on the exact instant. One second can separate two different offsets, as in Example 3.
- Fixed offsets: a zone created from
+05:45always reports20700, whatever date you pass. - The datetime's own zone: two objects representing the same instant but carrying different zones give identical results, because only the instant matters.
- Half-hour and 45-minute zones: offsets are not always whole hours. India is
19800and Nepal is20700, so never assume a multiple of3600. - Historic dates: region zones can have had different offsets in the past. The result follows the time zone database bundled with your PHP build.
Common mistakes
- Expecting hours. The result is in seconds. Divide by
3600if you need hours, and keep fractional hours in mind. - Forgetting the date matters. Using "now" or an arbitrary date for a region zone can yield the wrong offset for the date you really care about.
- Confusing the two arguments. The first argument is the zone you are measuring. Putting a zone on the
DateTimeand expecting it to be measured does not work. - Reversing the sign. A positive number means the zone is ahead of UTC. Some other systems use the opposite convention, so check before mixing values.
- Hard-coding a single offset per zone. Storing
-18000for New York breaks as soon as daylight saving time applies. - Looking for a failure value. Do not test for
false. Catch exceptions where you build the zone from user input.
Related functions
DateTimeZone::getOffset(): the method form of this function.timezone_open(): creates aDateTimeZoneprocedurally.timezone_name_get(): returns the zone's name.timezone_transitions_get(): lists offset changes for a zone.date_offset_get(): returns the offset of aDateTimeobject's own zone.
Recap
timezone_offset_get($zone, $datetime) returns the UTC offset in seconds of $zone at the instant given by $datetime. It is an alias of DateTimeZone::getOffset(), gives positive values east of UTC, and reflects daylight saving rules for region zones. Always pass the date you actually care about, and remember the result is in seconds.
Tested examples
date_default_timezone_set('UTC');
$tz = new DateTimeZone('Europe/Paris');
$winter = new DateTimeImmutable('2024-01-15 12:00:00', new DateTimeZone('UTC'));
$summer = new DateTimeImmutable('2024-07-15 12:00:00', new DateTimeZone('UTC'));
echo json_encode([timezone_offset_get($tz, $winter), timezone_offset_get($tz, $summer)]), "\n";[3600,7200]
date_default_timezone_set('UTC');
$date = new DateTime('2024-03-01 00:00:00');
$zones = ['Asia/Kolkata', 'America/New_York', 'UTC', '+05:45'];
$result = [];
foreach ($zones as $name) {
$result[$name] = timezone_offset_get(new DateTimeZone($name), $date);
}
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"Asia/Kolkata":19800,"America/New_York":-18000,"UTC":0,"+05:45":20700}
date_default_timezone_set('UTC');
$tz = new DateTimeZone('America/New_York');
$utc = new DateTimeZone('UTC');
$before = new DateTimeImmutable('2024-03-10 06:59:59', $utc);
$after = new DateTimeImmutable('2024-03-10 07:00:00', $utc);
echo json_encode([
'before' => timezone_offset_get($tz, $before),
'after' => timezone_offset_get($tz, $after),
'same' => $tz->getOffset($after) === timezone_offset_get($tz, $after),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";{"before":-18000,"after":-14400,"same":true}