Skip to content

Commit

Permalink
CakeTime::listTimezones(): Add option to Display timezone abbreviations
Browse files Browse the repository at this point in the history
Useful for countries that do not have many of its cities, even major ones,
listed. For eg: Indonesia, only have 4 cities listed.

For backward compatibility, abbreviations will not be shown.

Note: You might need to update timezonedb for PHP 5.3

Closes #7271
  • Loading branch information
rchavik committed Aug 21, 2015
1 parent 6fae3f6 commit e6acaca
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 4 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -37,6 +37,7 @@ before_script:
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'CREATE SCHEMA test3;' -U postgres -d cakephp_test; fi"
- chmod -R 777 ./app/tmp
- sudo apt-get install lighttpd
- if [[ ${TRAVIS_PHP_VERSION:0:3} == "5.3" ]] ; then pecl install timezonedb ; fi
- sh -c "if [ '$PHPCS' = '1' ]; then composer global require 'cakephp/cakephp-codesniffer:1.*'; fi"
- sh -c "if [ '$PHPCS' = '1' ]; then ~/.composer/vendor/bin/phpcs --config-set installed_paths ~/.composer/vendor/cakephp/cakephp-codesniffer; fi"
- echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
Expand Down
13 changes: 13 additions & 0 deletions lib/Cake/Test/Case/Utility/CakeTimeTest.php
Expand Up @@ -1166,6 +1166,19 @@ public function testListTimezones() {
$this->assertTrue(isset($return['Asia']['Asia/Bangkok']));
$this->assertFalse(isset($return['Pacific']));

$return = CakeTime::listTimezones(null, null, array('abbr' => true));
$this->assertTrue(isset($return['Asia']['Asia/Jakarta']));
$this->assertEquals('Jakarta - WIB', $return['Asia']['Asia/Jakarta']);
$this->assertEquals('Amsterdam - CEST', $return['Europe']['Europe/Amsterdam']);

$return = CakeTime::listTimezones(null, null, array(
'abbr' => true,
'before' => ' (',
'after' => ')',
));
$this->assertEquals('Jayapura (WIT)', $return['Asia']['Asia/Jayapura']);
$this->assertEquals('Amsterdam (CEST)', $return['Europe']['Europe/Amsterdam']);

$return = CakeTime::listTimezones('#^(America|Pacific)/#', null, false);
$this->assertTrue(isset($return['America/Argentina/Buenos_Aires']));
$this->assertTrue(isset($return['Pacific/Tahiti']));
Expand Down
36 changes: 32 additions & 4 deletions lib/Cake/Utility/CakeTime.php
Expand Up @@ -1075,12 +1075,29 @@ public static function i18nFormat($date, $format = null, $default = false, $time
* Or one of DateTimeZone class constants (PHP 5.3 and above)
* @param string $country A two-letter ISO 3166-1 compatible country code.
* This option is only used when $filter is set to DateTimeZone::PER_COUNTRY (available only in PHP 5.3 and above)
* @param bool $group If true (default value) groups the identifiers list by primary region
* @param bool|array $options If true (default value) groups the identifiers list by primary region.
* Otherwise, an array containing `group`, `abbr`, `before`, and `after` keys.
* Setting `group` and `abbr` to true will group results and append timezone
* abbreviation in the display value. Set `before` and `after` to customize
* the abbreviation wrapper.
* @return array List of timezone identifiers
* @since 2.2
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::listTimezones
*/
public static function listTimezones($filter = null, $country = null, $group = true) {
public static function listTimezones($filter = null, $country = null, $options = array()) {
if (is_bool($options)) {
$options = array(
'group' => $options,
);
}
$options = array_merge(array(
'group' => true,
'abbr' => false,
'before' => ' - ',
'after' => null,
), $options);
$group = $options['group'];

$regex = null;
if (is_string($filter)) {
$regex = $filter;
Expand Down Expand Up @@ -1108,12 +1125,23 @@ public static function listTimezones($filter = null, $country = null, $group = t

if ($group) {
$return = array();
$now = time();
$before = $options['before'];
$after = $options['after'];
foreach ($identifiers as $key => $tz) {
$abbr = null;
if ($options['abbr']) {
$dateTimeZone = new DateTimeZone($tz);
$trans = $dateTimeZone->getTransitions($now, $now);
$abbr = isset($trans[0]['abbr']) ?
$before . $trans[0]['abbr'] . $after :
null;
}
$item = explode('/', $tz, 2);
if (isset($item[1])) {
$return[$item[0]][$tz] = $item[1];
$return[$item[0]][$tz] = $item[1] . $abbr;
} else {
$return[$item[0]] = array($tz => $item[0]);
$return[$item[0]] = array($tz => $item[0] . $abbr);
}
}
return $return;
Expand Down

0 comments on commit e6acaca

Please sign in to comment.