Skip to main content

Overview

The PhoneNumberToTimeZonesMapper class identifies the timezone(s) where a phone number is located. It returns an array of timezone strings in IANA timezone format (e.g., “America/New_York”, “Europe/Zurich”).
Geographic numbers typically return specific timezones, while non-geographic numbers (like toll-free) may return multiple timezones covering the entire country.

Getting an Instance

The timezone mapper uses a singleton pattern. Get an instance using the static getInstance() method:
$timezoneMapper = \libphonenumber\PhoneNumberToTimeZonesMapper::getInstance();
className
string
Optional class name for custom timezone mapping data. Only needed for advanced use cases with custom data sources.

Methods

getTimeZonesForNumber()

Returns an array of timezone strings for the given phone number. For geographical numbers, this typically returns one or a few specific timezones. For non-geographical numbers (toll-free, shared-cost, etc.), it may return all timezones in the country.
public function getTimeZonesForNumber(PhoneNumber $number): array
number
PhoneNumber
required
The phone number to get timezone information for.
return
string[]
An array of timezone strings in IANA format. Returns ["Etc/Unknown"] if:
  • The number is invalid
  • No timezone data is available
  • The number type is unknown

Geographic Number Example

Geographic (fixed-line) numbers typically return specific timezones:
use libphonenumber\PhoneNumberUtil;
use libphonenumber\PhoneNumberToTimeZonesMapper;

$phoneUtil = PhoneNumberUtil::getInstance();
$timezoneMapper = PhoneNumberToTimeZonesMapper::getInstance();

// US geographic number (Mountain View, CA)
$usNumber = $phoneUtil->parse("+1 650 253 0000", "US");

$timezones = $timezoneMapper->getTimeZonesForNumber($usNumber);
var_dump($timezones);
// Output: array(1) { [0]=> string(19) "America/Los_Angeles" }

Non-Geographic Number Example

Non-geographic numbers like toll-free can be from anywhere in the country, so they return all possible timezones:
$phoneUtil = PhoneNumberUtil::getInstance();
$timezoneMapper = PhoneNumberToTimeZonesMapper::getInstance();

// US toll-free number
$tollFreeNumber = $phoneUtil->parse("+1 800 253 0000", "US");

$timezones = $timezoneMapper->getTimeZonesForNumber($tollFreeNumber);
var_dump($timezones);
// Output: array(35) containing all US and associated territories timezones:
// [0]=> "America/Anguilla"
// [1]=> "America/Antigua"
// [2]=> "America/Barbados"
// [3]=> "America/Cayman"
// [4]=> "America/Chicago"
// [5]=> "America/Denver"
// ... (30 more timezones)

Swiss Number Example

$phoneUtil = PhoneNumberUtil::getInstance();
$timezoneMapper = PhoneNumberToTimeZonesMapper::getInstance();

// Swiss mobile number
$swissNumber = $phoneUtil->parse("798765432", "CH");

$timezones = $timezoneMapper->getTimeZonesForNumber($swissNumber);
var_dump($timezones);
// Output: array(1) { [0]=> string(13) "Europe/Zurich" }

getTimeZonesForGeographicalNumber()

Returns timezones for a geographical phone number. Assumes the number has already been validated as geographical.
public function getTimeZonesForGeographicalNumber(PhoneNumber $number): array
number
PhoneNumber
required
A valid geographical phone number.
return
string[]
An array of timezone strings, or ["Etc/Unknown"] if no mapping is found.
This method assumes the number is geographical (fixed-line or mobile). For most use cases, prefer getTimeZonesForNumber() which automatically determines the number type.

getUnknownTimeZone()

Returns the constant string used to represent unknown timezones.
public static function getUnknownTimeZone(): string
return
string
The string “Etc/Unknown”

Example

$unknownTz = \libphonenumber\PhoneNumberToTimeZonesMapper::getUnknownTimeZone();
echo $unknownTz;
// Output: "Etc/Unknown"

Complete Example

use libphonenumber\PhoneNumberUtil;
use libphonenumber\PhoneNumberToTimeZonesMapper;

$phoneUtil = PhoneNumberUtil::getInstance();
$timezoneMapper = PhoneNumberToTimeZonesMapper::getInstance();

try {
    // Geographic number - specific timezone
    $usNumber = $phoneUtil->parse("+1 650 253 0000", "US");
    $timezones = $timezoneMapper->getTimeZonesForNumber($usNumber);
    
    echo "US Geographic Number Timezones:\n";
    foreach ($timezones as $timezone) {
        echo "  - {$timezone}\n";
    }
    // Output: America/Los_Angeles
    
    // Toll-free number - multiple timezones
    $tollFree = $phoneUtil->parse("+1 800 253 0000", "US");
    $tollFreeTimezones = $timezoneMapper->getTimeZonesForNumber($tollFree);
    
    echo "\nUS Toll-Free Number Timezones: " . count($tollFreeTimezones) . " zones\n";
    // Output: 35 zones (all US and territories)
    
    // Swiss number
    $swissNumber = $phoneUtil->parse("798765432", "CH");
    $swissTimezones = $timezoneMapper->getTimeZonesForNumber($swissNumber);
    
    echo "\nSwiss Number Timezones:\n";
    foreach ($swissTimezones as $timezone) {
        echo "  - {$timezone}\n";
    }
    // Output: Europe/Zurich
    
    // Invalid number
    $invalidNumber = $phoneUtil->parse("123", "XX");
    $unknownTimezones = $timezoneMapper->getTimeZonesForNumber($invalidNumber);
    
    echo "\nInvalid Number Timezones:\n";
    var_dump($unknownTimezones);
    // Output: array(1) { [0]=> string(11) "Etc/Unknown" }
    
} catch (\libphonenumber\NumberParseException $e) {
    echo "Error: " . $e->getMessage();
}

Understanding Results

Single Timezone Result

Most geographic phone numbers return a single timezone:
// Returns: ["Europe/Zurich"]
$timezones = $timezoneMapper->getTimeZonesForNumber($swissNumber);

Multiple Timezone Results

Some scenarios return multiple timezones:
  1. Non-geographic numbers (toll-free, shared cost, etc.)
    • Can be from anywhere in the country
    • Returns all timezones for that country/region
  2. Numbers spanning multiple zones
    • Some area codes cover multiple timezones
    • Returns all applicable zones
  3. Country-level results
    • When specific geographic data isn’t available
    • Returns all timezones for the country
// US toll-free - could be answered from anywhere
$timezones = $timezoneMapper->getTimeZonesForNumber($tollFreeNumber);
echo count($timezones); // 35 timezones

Timezone Format

All timezone strings use the IANA timezone database format:
  • North America: America/New_York, America/Chicago, America/Los_Angeles
  • Europe: Europe/London, Europe/Paris, Europe/Zurich
  • Asia: Asia/Tokyo, Asia/Hong_Kong, Asia/Dubai
  • Pacific: Pacific/Auckland, Pacific/Honolulu
  • Unknown: Etc/Unknown
These timezone strings are compatible with PHP’s DateTimeZone class:
$timezones = $timezoneMapper->getTimeZonesForNumber($number);

foreach ($timezones as $tzString) {
    $timezone = new DateTimeZone($tzString);
    $datetime = new DateTime('now', $timezone);
    echo "Time in {$tzString}: " . $datetime->format('Y-m-d H:i:s T') . "\n";
}

Use Cases

Common applications:
  • Scheduling calls - Determine appropriate calling times
  • Time-based features - Show local time for phone number owners
  • Business hours - Calculate operating hours for different regions
  • Analytics - Timezone-based reporting and analysis
  • Compliance - Respect calling time restrictions by timezone

Data Availability

Timezone mapping works best for:
  • Fixed-line numbers - Usually tied to specific geographic areas
  • Mobile numbers - When registered to specific regions
  • Countries with good data coverage - Major markets have detailed mapping
Limitations:
  • Non-geographic numbers return country-level timezones (many results)
  • Some regions may have incomplete data
  • Mobile numbers may not reflect current user location
  • Returns "Etc/Unknown" when no data is available

Build docs developers (and LLMs) love