Skip to content

Instantly share code, notes, and snippets.

@francescozanoni
Last active May 16, 2018 09:44
Show Gist options
  • Save francescozanoni/105e18972deeba516d9d72188ac3a5b7 to your computer and use it in GitHub Desktop.
Save francescozanoni/105e18972deeba516d9d72188ac3a5b7 to your computer and use it in GitHub Desktop.
[PHP] Get the offset list of a timezone, optionally defining the year

Function code:

/**
 * Get all the time offsets of a timezone.
 *
 * @param string $timezoneIdentifier
 * @param bool $withDayLightSavingTime
 * @return array
 */
function getTimeZoneOffsets(string $timezoneIdentifier, bool $withDayLightSavingTime = true) : array
{

    if (in_array($timezoneIdentifier, \DateTimeZone::listIdentifiers()) === false) {
        throw new \InvalidArgumentException('Invalid time zone identifier');
    }

    // Time offsets are retrieved by merging the set
    // of all offsets of months of the current year.
    $dates = function () {
        $year = date('Y');
        for ($i = 1; $i <= 12; $i++) {
            yield $year . '-' . str_pad((string)$i, 2, '0', STR_PAD_LEFT) . '-01 00:00:00';
        }
    };

    $timezoneObject = new \DateTimeZone($timezoneIdentifier);

    $offsets = [];

    foreach ($dates() as $date) {
        $dateTime = new \DateTime($date, $timezoneObject);

        // Day light saving time offsets are optionally ignored.
        if ($withDayLightSavingTime === false &&
            $dateTime->format('I') == 1
        ) {
            continue;
        }

        $offsetInSeconds = $timezoneObject->getOffset($dateTime);

        $sign = ($offsetInSeconds < 0 ? '-' : '+');
        // https://stackoverflow.com/questions/3172332/convert-seconds-to-hourminutesecond
        $hours = floor(abs($offsetInSeconds / 3600));
        $minutes = floor(abs(($offsetInSeconds / 60) % 60));
        $offsets[] = $sign . sprintf('%02d:%02d', $hours, $minutes);
    }

    $offsets = array_values(array_unique($offsets));

    return $offsets;

}

Usage example:

print_r(getTimeZoneOffsets('Europe/Rome'));

// Output:
// Array
// (
//     [0] => +01:00
//     [1] => +02:00
// )

print_r(getTimeZoneOffsets('Europe/Rome', false));

// Output:
// Array
// (
//     [0] => +01:00
// )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment