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 --}}
-
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);
+ }
}