diff --git a/CHANGELOG b/CHANGELOG index e92d60278..58f049df9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ UNRELEASED CHANGES: * Fix accounts with an empty reminder time * Fix account id get for acceptPolicy * Use our own docker image (central perk) to run tests +* Render timezone listbox dynamically RELEASED VERSIONS: diff --git a/app/Helpers/TimezoneHelper.php b/app/Helpers/TimezoneHelper.php new file mode 100644 index 000000000..1cde8d0cb --- /dev/null +++ b/app/Helpers/TimezoneHelper.php @@ -0,0 +1,122 @@ + $tz, + 'timezone' => $timezone, + 'name' => $name, + ]); + } + + $collect = collect($list) + ->groupBy('id') + ->sortKeys(); + + $result = []; + foreach ($collect as $item) { + $values = array_values(array_sort($item, function ($value) { + return $value['name']; + })); + foreach ($values as $val) { + array_push($result, $val); + } + } + + return $result; + } + + /** + * Format a timezone to be displayed (english only). + * + * @param string $timezone + * @return array int value of the offset, string formatted timezone + */ + private static function formatTimezone($timezone) : array + { + $dtimezone = new DateTimeZone($timezone); + $time = now($timezone); + + $offset = $time->format('P'); + + $loc = $dtimezone->getLocation(); + + if ($timezone == 'UTC') { + $formatted = '(UTC) Universal Time Coordinated'; + } else { + $name = $time->tzName; + $i = strpos($name, '/'); + if ($i > 0) { + $name = substr($name, $i + 1); + } + $name = str_replace(['St_', '/', '_'], ['St. ', ', ', ' '], $name); + + if (empty($loc['comments'])) { + $formatted = '(UTC '.$offset.') '.$name; + } else { + $formatted = '(UTC '.$offset.') '.$loc['comments'].' ('.$name.')'; + } + } + + $tz = str_replace(':', '', $offset); + $tz = intval($tz); + + return [$tz, $formatted]; + } + + /** + * Equivalent timezone to convert deprecated timezone. + * + * @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones + */ + protected static $equivalentTimezone = [ + 'Australia/Canberra' => 'Australia/Sydney', + 'Asia/Calcutta' => 'Asia/Kolkata', + 'Asia/Chongqing' => 'Asia/Shanghai', + 'Asia/Katmandu' => 'Asia/Kathmandu', + 'Asia/Rangoon' => 'Asia/Yangon', + 'Asia/Ulan_Bator' => 'Asia/Ulaanbaatar', + 'Canada/Atlantic' => 'America/Halifax', + 'Canada/Newfoundland' => 'America/St_Johns', + 'Canada/Saskatchewan' => 'America/Regina', + 'Etc/Greenwich' => 'UTC', // This is not an equivalent, but it the same zone + 'Pacific/Samoa' => 'Pacific/Pago_Pago', + 'US/Alaska' => 'America/Anchorage', + 'US/Arizona' => 'America/Phoenix', + 'US/Central' => 'America/Chicago', + 'US/East-Indiana' => 'America/Indiana/Indianapolis', + 'US/Eastern' => 'America/New_York', + 'US/Mountain' => 'America/Denver', + ]; + + /** + * Adjust a timezone with equivalent name (remove deprecated). + * + * @param string $timezone + * @return string + */ + public static function adjustEquivalentTimezone($timezone) : string + { + if (array_key_exists($timezone, self::$equivalentTimezone)) { + return self::$equivalentTimezone[$timezone]; + } + + return $timezone; + } +} diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 34ef5bdc2..4a991cfab 100644 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -9,6 +9,7 @@ use App\Models\Contact\Tag; use Illuminate\Http\Request; use App\Helpers\LocaleHelper; use App\Jobs\SendNewUserAlert; +use App\Helpers\TimezoneHelper; use App\Jobs\ExportAccountAsSQL; use App\Jobs\AddContactFromVCard; use App\Jobs\SendInvitationEmail; @@ -81,7 +82,9 @@ class SettingsController extends Controller return view('settings.index') ->withNamesOrder($namesOrder) ->withLocales(LocaleHelper::getLocaleList()) - ->withHours(DateHelper::getListOfHours()); + ->withHours(DateHelper::getListOfHours()) + ->withSelectedTimezone(TimezoneHelper::adjustEquivalentTimezone(DateHelper::getTimezone())) + ->withTimezones(TimezoneHelper::getListOfTimezones()); } /** diff --git a/resources/views/settings/index.blade.php b/resources/views/settings/index.blade.php index ab612f7be..9db6a71ef 100644 --- a/resources/views/settings/index.blade.php +++ b/resources/views/settings/index.blade.php @@ -92,152 +92,10 @@ {{-- Timezone --}}
- + @foreach ($timezones as $timezone) + + @endforeach
diff --git a/tests/Helper/DateHelperTest.php b/tests/Helper/DateHelperTest.php index 94c137f0b..b9f0c93b9 100644 --- a/tests/Helper/DateHelperTest.php +++ b/tests/Helper/DateHelperTest.php @@ -5,6 +5,7 @@ namespace Tests\Helper; use Carbon\Carbon; use Tests\FeatureTestCase; use App\Helpers\DateHelper; +use App\Helpers\TimezoneHelper; class DateHelperTest extends FeatureTestCase { @@ -433,4 +434,168 @@ class DateHelperTest extends FeatureTestCase $this->assertInstanceOf(Carbon::class, DateHelper::getDateMinusGivenNumberOfDays($date, 7)); } + + public function test_old_timezones_exists() + { + // These are all currently used timezone in monica + $oldTimezones = [ + 'US/Eastern', + 'US/Central', + 'America/Los_Angeles', + 'Pacific/Midway', + 'Pacific/Samoa', + 'Pacific/Honolulu', + 'US/Alaska', + 'America/Tijuana', + 'US/Arizona', + 'America/Chihuahua', + 'America/Chihuahua', + 'America/Mazatlan', + 'US/Mountain', + 'America/Managua', + 'US/Central', + 'America/Mexico_City', + 'America/Mexico_City', + 'America/Monterrey', + 'Canada/Saskatchewan', + 'America/Bogota', + 'US/Eastern', + 'US/East-Indiana', + 'America/Lima', + 'America/Bogota', + 'Canada/Atlantic', + 'America/Caracas', + 'America/La_Paz', + 'America/Santiago', + 'Canada/Newfoundland', + 'America/Sao_Paulo', + 'America/Argentina/Buenos_Aires', + 'America/Godthab', + 'America/Noronha', + 'Atlantic/Azores', + 'Atlantic/Cape_Verde', + 'Africa/Casablanca', + 'Europe/London', + 'Etc/Greenwich', + 'Europe/Lisbon', + 'Europe/London', + 'Africa/Monrovia', + 'UTC', + 'Europe/Amsterdam', + 'Europe/Belgrade', + 'Europe/Berlin', + 'Europe/Bratislava', + 'Europe/Brussels', + 'Europe/Budapest', + 'Europe/Copenhagen', + 'Europe/Ljubljana', + 'Europe/Madrid', + 'Europe/Paris', + 'Europe/Prague', + 'Europe/Rome', + 'Europe/Sarajevo', + 'Europe/Skopje', + 'Europe/Stockholm', + 'Europe/Vienna', + 'Europe/Warsaw', + 'Africa/Lagos', + 'Europe/Zagreb', + 'Europe/Zurich', + 'Europe/Athens', + 'Europe/Bucharest', + 'Africa/Cairo', + 'Africa/Harare', + 'Europe/Helsinki', + 'Europe/Istanbul', + 'Asia/Jerusalem', + 'Europe/Helsinki', + 'Africa/Johannesburg', + 'Europe/Riga', + 'Europe/Sofia', + 'Europe/Tallinn', + 'Europe/Vilnius', + 'Asia/Baghdad', + 'Asia/Kuwait', + 'Europe/Minsk', + 'Africa/Nairobi', + 'Asia/Riyadh', + 'Europe/Volgograd', + 'Asia/Tehran', + 'Asia/Muscat', + 'Asia/Baku', + 'Europe/Moscow', + 'Asia/Muscat', + 'Europe/Moscow', + 'Asia/Tbilisi', + 'Asia/Yerevan', + 'Asia/Kabul', + 'Asia/Karachi', + 'Asia/Karachi', + 'Asia/Tashkent', + 'Asia/Calcutta', + 'Asia/Kolkata', + 'Asia/Calcutta', + 'Asia/Calcutta', + 'Asia/Calcutta', + 'Asia/Katmandu', + 'Asia/Almaty', + 'Asia/Dhaka', + 'Asia/Dhaka', + 'Asia/Yekaterinburg', + 'Asia/Rangoon', + 'Asia/Bangkok', + 'Asia/Bangkok', + 'Asia/Jakarta', + 'Asia/Novosibirsk', + 'Asia/Hong_Kong', + 'Asia/Chongqing', + 'Asia/Hong_Kong', + 'Asia/Krasnoyarsk', + 'Asia/Kuala_Lumpur', + 'Australia/Perth', + 'Asia/Singapore', + 'Asia/Taipei', + 'Asia/Ulan_Bator', + 'Asia/Urumqi', + 'Asia/Irkutsk', + 'Asia/Tokyo', + 'Asia/Tokyo', + 'Asia/Seoul', + 'Asia/Tokyo', + 'Australia/Adelaide', + 'Australia/Darwin', + 'Australia/Brisbane', + 'Australia/Canberra', + 'Pacific/Guam', + 'Australia/Hobart', + 'Australia/Melbourne', + 'Pacific/Port_Moresby', + 'Australia/Sydney', + 'Asia/Yakutsk', + 'Asia/Vladivostok', + 'Pacific/Auckland', + 'Pacific/Fiji', + 'Pacific/Kwajalein', + 'Asia/Kamchatka', + 'Asia/Magadan', + 'Pacific/Fiji', + 'Asia/Magadan', + 'Asia/Magadan', + 'Pacific/Auckland', + 'Pacific/Tongatapu', + ]; + + $list = TimezoneHelper::getListOfTimezones(); + $list = collect($list); + + $missed = ''; + foreach ($oldTimezones as $timezone) { + $timezone = TimezoneHelper::adjustEquivalentTimezone($timezone); + if ($list->firstWhere('timezone', $timezone) == null) { + $missed .= ', '.$timezone; + } + } + + $this->assertTrue(empty($missed), 'Missed timezones : '.$missed); + } }