Dates7 min readExamples run on PHP 8.5.10

date_timezone_get()

Learn how date_timezone_get() returns the DateTimeZone attached to a date object, with PHP 8.4 signature, examples, edge cases and mistakes.

Signature

date_timezone_get(DateTimeInterface $object): DateTimeZone|false
Available since PHP 5.2.07.48.08.18.28.38.48.5All versions →

Purpose

date_timezone_get() is the procedural form of DateTime::getTimezone(). The manual lists it as an alias of that method. You give it a date object and it returns a DateTimeZone object describing the timezone stored in that date. Use it when you need to ask a date "which zone are you in?", for example to build a second date in the same zone, to display the zone name, or to compare zones.

The zone it reports belongs to the date object. It has nothing to do with the script's default timezone unless the date was created with that default.

Signature

The object-oriented equivalent is $object->getTimezone().

Parameters and defaults

  • $object: a DateTime, a DateTimeImmutable, or any other DateTimeInterface implementation. Procedural code usually gets one from date_create() or date_create_immutable(). There is no default; the argument is required.

Return value and failure cases

The declared return type is DateTimeZone|false. With a normally constructed date object you receive a DateTimeZone instance. Call getName() on it to read the zone as text.

Passing something that is not a DateTimeInterface, such as a string like '2024-03-15', throws a TypeError. Convert the string first with date_create(). Because date_create() itself returns false for an unparseable string, check that result before handing it on.

Example 1: reading a named zone

A date created with an explicit identifier reports that identifier.

Example
<?php
$date = date_create('2024-03-15 12:00:00', timezone_open('Europe/Paris'));
$tz = date_timezone_get($date);
echo $tz->getName(), "\n";
Output
Europe/Paris

Example 2: offset-style zones

A zone is not always a region name. When the input string carries a numeric offset, the date's zone is that offset, and getName() reports it in that form.

Example
<?php
$date = date_create('2024-03-15 12:00:00+05:30');
$tz = date_timezone_get($date);
echo $tz->getName(), "\n";
Output
+05:30

Example 3: reusing a zone for another date

The returned zone can be passed to a new date. Because the zone is a region identifier, daylight saving rules apply to the new date as well. July and December in New York have different offsets.

Example
<?php
date_default_timezone_set('UTC');
$start = date_create_immutable('2024-07-01 09:00:00', new DateTimeZone('America/New_York'));
$tz = date_timezone_get($start);
$other = new DateTimeImmutable('2024-12-01 09:00:00', $tz);
echo json_encode([
    'zone' => $tz->getName(),
    'july' => $start->format('c'),
    'december' => $other->format('c'),
], JSON_UNESCAPED_SLASHES), "\n";
Output
{"zone":"America/New_York","july":"2024-07-01T09:00:00-04:00","december":"2024-12-01T09:00:00-05:00"}

Edge cases

  • Three kinds of zone. A DateTimeZone may be a region identifier (Europe/Paris), a fixed offset (+05:30), or an abbreviation (such as EST). getName() returns whichever form the date holds, so do not assume it is always a region name.
  • The zone is not an offset. A region zone has no single offset. The offset depends on the moment, so ask for it with timezone_offset_get() and a date, or format the date with P.
  • Default timezone. If you create a date without a zone argument and without an offset in the string, it uses the current default timezone. Set the default explicitly in code that must be reproducible.
  • Changes are reflected. After date_timezone_set() on a DateTime, the next date_timezone_get() returns the new zone. A DateTimeImmutable never changes; the with-style methods return a new object, so read the zone from that new object.
  • Immutable and mutable objects both work. The parameter type is DateTimeInterface, so either class is accepted.

Common mistakes

  1. Echoing the result directly. DateTimeZone is an object with no string conversion, so echo date_timezone_get($d); raises an error. Call getName() first.
  2. Passing a string. The function needs a date object, not a date string. Build the object with date_create() and check for false.
  3. Expecting the default timezone. The function reports the zone of the given object, which may differ from date_default_timezone_get().
  4. Treating the name as an offset. Parsing Europe/Paris for hours is wrong. Use offset functions or format('P').
  5. Ignoring the shared type. The result can be a region, an offset or an abbreviation. Code that only handles region names will surprise you with input such as +05:30.
  • date_timezone_set() changes the zone of a mutable date.
  • timezone_name_get() is the procedural counterpart of DateTimeZone::getName().
  • timezone_offset_get() returns the offset in seconds for a zone at a given date.
  • date_default_timezone_get() returns the script-wide default zone.
  • date_create(), date_create_immutable() and timezone_open() build the objects used above.
  • DateTime::getTimezone() is the method this function aliases.

Recap

date_timezone_get() takes a DateTimeInterface object and returns its DateTimeZone. Call getName() to read it as text, remember that the zone may be a region, an offset or an abbreviation, and pass the result to new dates when you want them to share rules. Always supply a real date object, since strings cause a TypeError.

Tested examples

Reading a named zone
<?php
$date = date_create('2024-03-15 12:00:00', timezone_open('Europe/Paris'));
$tz = date_timezone_get($date);
echo $tz->getName(), "\n";
Output
Europe/Paris
Offset-style zones
<?php
$date = date_create('2024-03-15 12:00:00+05:30');
$tz = date_timezone_get($date);
echo $tz->getName(), "\n";
Output
+05:30
Reusing a zone for another date
<?php
date_default_timezone_set('UTC');
$start = date_create_immutable('2024-07-01 09:00:00', new DateTimeZone('America/New_York'));
$tz = date_timezone_get($start);
$other = new DateTimeImmutable('2024-12-01 09:00:00', $tz);
echo json_encode([
    'zone' => $tz->getName(),
    'july' => $start->format('c'),
    'december' => $other->format('c'),
], JSON_UNESCAPED_SLASHES), "\n";
Output
{"zone":"America/New_York","july":"2024-07-01T09:00:00-04:00","december":"2024-12-01T09:00:00-05:00"}