Skip to content

Commit ce37c78

Browse files
committed
[Intl] Provide translated timezone names
1 parent 64515b8 commit ce37c78

File tree

184 files changed

+37422
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

184 files changed

+37422
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Intl\Data\Generator;
13+
14+
use Symfony\Component\Intl\Data\Bundle\Reader\BundleReaderInterface;
15+
use Symfony\Component\Intl\Data\Util\ArrayAccessibleResourceBundle;
16+
use Symfony\Component\Intl\Data\Bundle\Compiler\GenrbCompiler;
17+
use Symfony\Component\Intl\Data\Util\LocaleScanner;
18+
19+
/**
20+
* The rule for compiling the currency bundle.
21+
*
22+
* @internal
23+
*/
24+
class TimezoneDataGenerator extends AbstractDataGenerator
25+
{
26+
/**
27+
* Collects all available timezones.
28+
*
29+
* @var string[]
30+
*/
31+
private $timezones = array();
32+
33+
/**
34+
* {@inheritdoc}
35+
*/
36+
protected function scanLocales(LocaleScanner $scanner, $sourceDir)
37+
{
38+
return $scanner->scanLocales($sourceDir.'/zone');
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
protected function compileTemporaryBundles(GenrbCompiler $compiler, $sourceDir, $tempDir)
45+
{
46+
$compiler->compile($sourceDir.'/zone', $tempDir);
47+
}
48+
49+
/**
50+
* {@inheritdoc}
51+
*/
52+
protected function preGenerate()
53+
{
54+
$this->timezones = array();
55+
}
56+
57+
/**
58+
* {@inheritdoc}
59+
*/
60+
protected function generateDataForLocale(BundleReaderInterface $reader, $tempDir, $displayLocale)
61+
{
62+
$localeBundle = $reader->read($tempDir, $displayLocale);
63+
64+
if (isset($localeBundle['zoneStrings']) && null !== $localeBundle['zoneStrings']) {
65+
$data = array(
66+
'Version' => $localeBundle['Version'],
67+
'Names' => $this->generateTimezoneNames($localeBundle),
68+
);
69+
70+
$this->timezones = array_merge($this->timezones, array_keys($data['Names']));
71+
72+
return $data;
73+
}
74+
75+
return;
76+
}
77+
78+
/**
79+
* {@inheritdoc}
80+
*/
81+
protected function generateDataForRoot(BundleReaderInterface $reader, $tempDir)
82+
{
83+
$rootBundle = $reader->read($tempDir, 'root');
84+
85+
return array(
86+
'Version' => $rootBundle['Version'],
87+
'Names' => $this->generateTimezoneNames($rootBundle),
88+
);
89+
}
90+
91+
/**
92+
* {@inheritdoc}
93+
*/
94+
protected function generateDataForMeta(BundleReaderInterface $reader, $tempDir)
95+
{
96+
$rootBundle = $reader->read($tempDir, 'root');
97+
98+
$this->timezones = array_unique($this->timezones);
99+
100+
sort($this->timezones);
101+
102+
$data = array(
103+
'Version' => $rootBundle['Version'],
104+
'Timezones' => $this->timezones,
105+
);
106+
107+
return $data;
108+
}
109+
110+
/**
111+
* @param ArrayAccessibleResourceBundle $rootBundle
112+
*
113+
* @return array
114+
*/
115+
private function generateTimezoneNames(ArrayAccessibleResourceBundle $rootBundle)
116+
{
117+
$timezoneNames = array();
118+
foreach ($rootBundle['zoneStrings'] as $key => $zone) {
119+
if (strpos($key, ':') !== false && substr($key, 5) != 'meta:') {
120+
$identifier = str_replace(':', '/', $key);
121+
122+
$zone = iterator_to_array($zone);
123+
124+
if (isset($zone['ec'])) {
125+
$timezoneNames[$identifier] = $zone['ec'];
126+
}
127+
}
128+
}
129+
130+
return $timezoneNames;
131+
}
132+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Intl\Data\Provider;
13+
14+
use Symfony\Component\Intl\Exception\MissingResourceException;
15+
use Symfony\Component\Intl\Locale;
16+
use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface;
17+
18+
/**
19+
* Data provider for timezone-related data.
20+
*
21+
* @internal
22+
*/
23+
class TimezoneDataProvider
24+
{
25+
/**
26+
* @var string
27+
*/
28+
private $path;
29+
30+
/**
31+
* @var BundleEntryReaderInterface
32+
*/
33+
private $reader;
34+
35+
/**
36+
* Creates a data provider that reads timezone-related data from a
37+
* resource bundle.
38+
*
39+
* @param string $path The path to the resource bundle.
40+
* @param BundleEntryReaderInterface $reader The reader for reading the resource bundle.
41+
*/
42+
public function __construct($path, BundleEntryReaderInterface $reader)
43+
{
44+
$this->path = $path;
45+
$this->reader = $reader;
46+
}
47+
48+
public function getTimezones()
49+
{
50+
return $this->reader->readEntry($this->path, 'meta', array('Timezones'));
51+
}
52+
53+
public function getName($timezone, $displayLocale = null)
54+
{
55+
if (null === $displayLocale) {
56+
$displayLocale = Locale::getDefault();
57+
}
58+
59+
try {
60+
return $this->reader->readEntry($this->path, $displayLocale, array('Names', $timezone));
61+
} catch (MissingResourceException $e) {
62+
return $this->getFallbackName($timezone);
63+
}
64+
}
65+
66+
public function getNames($displayLocale = null)
67+
{
68+
if (null === $displayLocale) {
69+
$displayLocale = Locale::getDefault();
70+
}
71+
72+
$names = $this->reader->readEntry($this->path, $displayLocale, array('Names'));
73+
74+
if ($names instanceof \Traversable) {
75+
$names = iterator_to_array($names);
76+
}
77+
78+
foreach ($this->getTimezones() as $timezone) {
79+
if (!isset($names[$timezone])) {
80+
$names[$timezone] = $this->getFallbackName($timezone);
81+
}
82+
}
83+
84+
// Sorting by value cannot be done during bundle generation, because
85+
// binary bundles are always sorted by keys
86+
$collator = new \Collator($displayLocale);
87+
$collator->asort($names);
88+
89+
return $names;
90+
}
91+
92+
/**
93+
* Converts a timezone identifier to an English string.
94+
*
95+
* @param string $timezone
96+
*
97+
* @return string
98+
*/
99+
protected function getFallbackName($timezone)
100+
{
101+
if (!in_array($timezone, $this->getTimezones())) {
102+
throw new MissingResourceException('Unknown timezone: '.$timezone);
103+
}
104+
105+
$parts = explode('/', $timezone);
106+
if (count($parts) == 1) {
107+
$name = $parts[0];
108+
} elseif (count($parts) == 2) {
109+
$name = $parts[1];
110+
} else {
111+
$name = $parts[2].', '.$parts[1];
112+
}
113+
return $name;
114+
}
115+
}

src/Symfony/Component/Intl/Intl.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ final class Intl
6363
*/
6464
const REGION_DIR = 'regions';
6565

66+
/**
67+
* The directory name of the timezone data.
68+
*/
69+
const TIMEZONE_DIR = 'timezones';
70+
6671
/**
6772
* @var ResourceBundle\CurrencyBundleInterface
6873
*/
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Intl\ResourceBundle;
13+
14+
use Symfony\Component\Intl\Data\Provider\TimezoneDataProvider;
15+
use Symfony\Component\Intl\Exception\MissingResourceException;
16+
17+
/**
18+
* Default implementation of {@link TimezoneBundleInterface}.
19+
*
20+
* @internal
21+
*/
22+
class TimezoneBundle extends TimezoneDataProvider implements TimezoneBundleInterface
23+
{
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
public function getTimezones()
28+
{
29+
try {
30+
return parent::getTimezones();
31+
} catch (MissingResourceException $e) {
32+
return array();
33+
}
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
public function getTimezoneName($timezone, $displayLocale = null)
40+
{
41+
try {
42+
return $this->getName($timezone, $displayLocale);
43+
} catch (MissingResourceException $e) {
44+
return;
45+
}
46+
}
47+
48+
/**
49+
* {@inheritdoc}
50+
*/
51+
public function getTimezoneNames($displayLocale = null)
52+
{
53+
try {
54+
return $this->getNames($displayLocale);
55+
} catch (MissingResourceException $e) {
56+
return array();
57+
}
58+
}
59+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Intl\ResourceBundle;
13+
14+
/**
15+
* Gives access to locale-related ICU data.
16+
*/
17+
interface TimezoneBundleInterface extends ResourceBundleInterface
18+
{
19+
/**
20+
* Returns the location name (usually a city) for a timezone.
21+
*
22+
* @param string $locale The locale to return the name of (e.g. "de_AT").
23+
* @param string $displayLocale Optional. The locale to return the name in.
24+
* Defaults to {@link \Locale::getDefault()}.
25+
*
26+
* @return string|null The location name for the timezone or NULL if not found.
27+
*/
28+
public function getTimezoneName($timezone, $displayLocale = null);
29+
30+
/**
31+
* Returns the location names (usually cities) for all known timezones.
32+
*
33+
* @param string $displayLocale Optional. The locale to return the names in.
34+
* Defaults to {@link \Locale::getDefault()}.
35+
*
36+
* @return string[] A list of locale names indexed by locale codes.
37+
*/
38+
public function getTimezoneNames($displayLocale = null);
39+
}

src/Symfony/Component/Intl/Resources/bin/update-data.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Intl\Data\Generator\LocaleDataGenerator;
1818
use Symfony\Component\Intl\Data\Generator\RegionDataGenerator;
1919
use Symfony\Component\Intl\Data\Generator\ScriptDataGenerator;
20+
use Symfony\Component\Intl\Data\Generator\TimezoneDataGenerator;
2021
use Symfony\Component\Intl\Data\Provider\LanguageDataProvider;
2122
use Symfony\Component\Intl\Data\Provider\RegionDataProvider;
2223
use Symfony\Component\Intl\Data\Provider\ScriptDataProvider;
@@ -257,6 +258,14 @@
257258

258259
$generator->generateData($config);
259260

261+
echo "Generating timezone data...\n";
262+
263+
$reader = new BundleEntryReader(new JsonBundleReader());
264+
265+
$generator = new TimezoneDataGenerator($compiler, Intl::TIMEZONE_DIR);
266+
267+
$generator->generateData($config);
268+
260269
//echo "Compiling...\n";
261270
//
262271
//$compiler->compile($txtDir.'/'.Intl::LOCALE_DIR, $resDir.'/'.Intl::LOCALE_DIR);

0 commit comments

Comments
 (0)