From 49abc59d925f6c67e3dea247b850d7b114f3af5c Mon Sep 17 00:00:00 2001 From: Juan Lago Date: Mon, 8 Apr 2024 11:56:41 +0200 Subject: [PATCH 1/2] Added timezones. --- src/Data/Countries/CountryCodes.php | 74 +++++++++++++++++++++++++++++ tests/test/CountriesTest.php | 35 +++++++++++++- 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/src/Data/Countries/CountryCodes.php b/src/Data/Countries/CountryCodes.php index d7ef4d4..9795012 100644 --- a/src/Data/Countries/CountryCodes.php +++ b/src/Data/Countries/CountryCodes.php @@ -2,6 +2,7 @@ namespace Juanparati\ISOCodes\Data\Countries; +use Illuminate\Support\Arr; use Juanparati\ISOCodes\Data\ISODataBase; /** @@ -3243,4 +3244,77 @@ class CountryCodes extends ISODataBase 'eu_member' => false, ], ]; + + + /** + * Contains the capital timezones (or compatible) for countries that has more than 1 timezone. + * In case of autonomous regions it contains the most compatible timezone. + * + * @var array|string[] + */ + protected array $mainTimezones = [ + 'AR' => 'America/Argentina/Buenos_Aires', + 'AU' => 'Australia/Sydney', + 'BV' => 'Africa/Johannesburg', + 'CA' => 'America/Toronto', + 'CD' => 'Africa/Kinshasa', + 'CL' => 'America/Santiago', + 'CN' => 'Asia/Shanghai', + 'EC' => 'America/Guayaquil', + 'ES' => 'Europe/Madrid', + 'FM' => 'Pacific/Chuuk', + 'GL' => 'America/Godthab', + 'HM' => 'Australia/Perth', + 'ID' => 'Asia/Jakarta', + 'KI' => 'Pacific/Tarawa', + 'KZ' => 'Asia/Almaty', + 'MH' => 'Pacific/Majuro', + 'MN' => 'Asia/Ulaanbaatar', + 'MX' => 'America/Mexico_City', + 'MY' => 'Asia/Kuala_Lumpur', + 'NZ' => 'Pacific/Auckland', + 'PF' => 'Pacific/Tahiti', + 'PG' => 'Pacific/Port_Moresby', + 'PS' => 'Asia/Gaza', + 'PT' => 'Europe/Lisbon', + 'RU' => 'Europe/Moscow', + 'TF' => 'Indian/Kerguelen', + 'UA' => 'Europe/Kiev', + 'UM' => 'Pacific/Midway', + 'US' => 'America/New_York', + 'UZ' => 'Asia/Samarkand', + ]; + + + /** + * Retrieve all the elements from the database. + * + * @return array + */ + public function all(): array + { + // Populate timezones. + // PHP already has the different timezones, so it's not required to create a complete list of timezones. + return Arr::map( + $this->db, + function (array $data, string $alpha2) { + $zones = \DateTimeZone::listIdentifiers(\DateTimeZone::PER_COUNTRY, $alpha2); + + if ($this->mainTimezones[$alpha2] ?? null) { + + if (count($zones)) { + $zones = array_filter($zones, fn($zone) => $zone !== $this->mainTimezones[$alpha2]); + array_unshift($zones, $this->mainTimezones[$alpha2]); + } else { + $zones = [$this->mainTimezones[$alpha2]]; + } + } + + $data['timezones'] = $zones; + + return $data; + } + ); + + } } diff --git a/tests/test/CountriesTest.php b/tests/test/CountriesTest.php index 7b35a08..eea6c27 100644 --- a/tests/test/CountriesTest.php +++ b/tests/test/CountriesTest.php @@ -3,9 +3,9 @@ namespace Juanparati\ISOCodes\Tests\test; use Illuminate\Support\Collection; +use Juanparati\ISOCodes\Data\Countries\CountryCodes; use Juanparati\ISOCodes\Enums\NodeResolution; use Juanparati\ISOCodes\ISOCodes; -use Juanparati\ISOCodes\Models\CountryModel; use Juanparati\ISOCodes\Models\ModelRecord; use PHPUnit\Framework\TestCase; @@ -18,6 +18,11 @@ class CountriesTest extends TestCase 'alpha3' => 'ESP', 'numeric' => '724', 'tld' => '.es', + 'timezones' => [ + 'Europe/Madrid', + 'Africa/Ceuta', + 'Atlantic/Canary' + ] ]; protected array $testNodeCode = [ @@ -78,6 +83,7 @@ public function testAllCountries() { $this->assertArrayHasKey('currencies', $country); $this->assertArrayHasKey('continents', $country); $this->assertArrayHasKey('name', $country); + $this->assertArrayHasKey('timezones', $country); } } @@ -202,11 +208,36 @@ public function testCurrencyAsNumber() { } + /** + * Test continent search. + * + * @return void + */ public function testContinentSearch() { $this->assertCount(2, (new ISOCodes())->countries()->whereContinent(['AS', 'EU'], true)); } + /** + * Test that main timezones are correct. + * + * @return void + */ + public function testMainTimezone() { + $iso = new ISOCodes(); + $countryCodes = new CountryCodes(); + + $reflectedClass = new \ReflectionClass($countryCodes); + $reflection = $reflectedClass->getProperty('mainTimezones'); + $mainTimezones = $reflection->getValue($countryCodes); + + foreach ($mainTimezones as $alpha2 => $timezone) { + $timezones = $iso->countries()->findByAlpha2($alpha2)->timezones; + $this->assertEquals($timezone, $timezones[0]); + } + } + + /** * Assert expected country. * @@ -218,4 +249,4 @@ protected function assertCountry(array $expected, \ArrayAccess|ModelRecord $coun $this->assertEquals($country[$key], $value); } -} \ No newline at end of file +} From d43e8b57f6d6b10beddede6824f6a3a39042633a Mon Sep 17 00:00:00 2001 From: Juan Lago Date: Mon, 8 Apr 2024 12:46:39 +0200 Subject: [PATCH 2/2] Added timezones. --- README.md | 58 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 36b2b95..1078910 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ This library provides the following ISOs and codes: - [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) (Currency codes) - [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (Language codes) - [International dialing codes](https://en.wikipedia.org/wiki/List_of_country_calling_codes) +- [Olson Timezones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) - [Unicode flags](https://en.wikipedia.org/wiki/Regional_indicator_symbol) - [European Union Members](https://european-union.europa.eu/principles-countries-history/country-profiles_en) @@ -64,24 +65,32 @@ It returns something like this: [ ... "AL"=> [ - "alpha2" => "AL", - "alpha3" => "ALB", - "numeric" => "008", - "tld" => ".al", + "alpha2" => "ES", + "alpha3" => "ESP", + "numeric" => "724", + "tld" => ".es", "currencies" => [ - 'ALL' + "EUR", ], - "languages" => [ - "SQ", + "languages" => [ + "ES", + "CA", + "GL", + "EU", ], "continents" => [ - "EU", + "EU", ], - "name" => "Albania", - "capital" => "Tirana", - "flag" => "🇦🇱", - "phone_code" => "355", - "eu_member" => false + "capital" => "Madrid", + "flag" => "🇪🇸", + "phone_code" => "34", + "eu_member" => true, + "name" => "Spain", + "timezones" => [ + "Europe/Madrid", + "Africa/Ceuta", + "Atlantic/Canary", + ] ] ... ]; @@ -218,6 +227,9 @@ It returns something like: "languages" => [ …1], "continents" => [ …1], "name" => "Andorra", + "timezones" => [ + "Europe/Andorra" + ] ], ... ], @@ -342,7 +354,12 @@ returns the following: "capital" => "Lisboa", "flag" => "🇵🇹", "phone_code" => "351", - "eu_member" => true + "eu_member" => true, + "timezones" => [ + "Europe/Lisbon", + "Atlantic/Azores", + "Atlantic/Madeira", + ], ] instead of: @@ -365,7 +382,12 @@ instead of: "capital" => "Lisboa", "flag" => "🇵🇹", "phone_code" => "351", - "eu_member" => true + "eu_member" => true, + "timezones" => [ + "Europe/Lisbon", + "Atlantic/Azores", + "Atlantic/Madeira", + ], ] The node resolutions works with the others models like "currencies", "languages", etc. @@ -396,6 +418,12 @@ $iso = new ISOCodes(new ISOCodes(defaultResolutions: [ ]); ``` +## Main language and timezone + +- The more spoken language is displayed first in the list. +- The country capital timezone is displayed first in the list. + + ## Custom dataset and locales It's possible to register custom datasets and locales during the ISOCodes instantiation.