Статьи

Создание вашего стартапа: автоматическое определение часового пояса

Конечный продукт
Что вы будете создавать

Это руководство является частью серии « Создай свой стартап с помощью PHP» на Envato Tuts +. В этой серии я проведу вас через запуск стартапа от концепции до реальности, используя мое приложение Meeting Planner в качестве примера из реальной жизни. На каждом этапе я буду публиковать код Планировщика собраний в качестве примеров с открытым исходным кодом, из которых вы можете извлечь уроки. Я также буду решать вопросы, связанные с бизнесом по мере их возникновения.

Для альфа-версии Meeting Planner я предоставил людям возможность изменить свой часовой пояс в пользовательских настройках. Однако, для любого человека за пределами западной части Соединенных Штатов, они, возможно, задавались вопросом, почему их календарные назначения были в неподходящее время. Вы должны знать, чтобы искать страницу настроек.

По мере приближения к бета-версии я осознал, что нужно исправить это как можно скорее. Поэтому я начал размышлять о том, как лучше решить эту проблему.

В сегодняшнем выпуске я расскажу вам о моем подходе к автоматическому обнаружению часовых поясов и о том, как я интегрировал его в пользовательский интерфейс.

Если вы еще этого не сделали, попробуйте прямо сейчас Планировщик собраний, запланировав свою первую встречу . Если вы находитесь за пределами тихоокеанского стандартного часового пояса, вы, вероятно, увидите подсказки для обновления часового пояса, которые описаны ниже. Пожалуйста, оставьте свой отзыв об опыте в комментариях ниже.

Я участвую в комментариях, но вы также можете связаться со мной @reifman в Twitter. Я всегда открыт для новых идей и тематических предложений для будущих уроков.

Напоминаем, что весь код для Meeting Planner написан на Yii2 Framework для PHP. Если вы хотите узнать больше о Yii2, ознакомьтесь с моей параллельной серией Программирование с Yii2 . Чем больше я строю Планировщика встреч, тем больше меня впечатляет Yii2 и их команда добровольцев.

Текущая страница настроек позволяет пользователям выбирать часовой пояс. Я собрал скриншот, показывающий часть выбранных часовых поясов, которые появляются при нажатии на выпадающий список; много:

Построение запуска при обнаружении часовых поясов

Казалось, это работает хорошо, но пользователи не обязательно будут искать его. На самом деле, они не смогут узнать, находятся ли они в одном часовом поясе с нашим сервером.

Во-первых, я посмотрел на некоторые из селекторов карты часовых поясов, чтобы увидеть, будут ли они иметь простой ответ. Я нашел два человека с практически одинаковым именем: Выбор часового пояса :

Построение стартапа для определения часового пояса - Timepicker с графической картой

и quicksketch / timezonepicker: средство выбора часового пояса на основе jQuery и ImageMap . Хотя я по достоинству оценил графические селекторы, они плохо работали для мобильных устройств и не обеспечивали обнаружение.

Я нашел расширение Yii2 под названием « Детектор часовых поясов», но не было ясно, как он определяет часовой пояс и насколько надежным он будет.

В конечном итоге я выбрал простое решение JavaScript, называемое jsTimezoneDetect ; Вы можете увидеть демонстрационную страницу ниже:

Создание вашего часового пояса при запуске - демонстрационная страница jsTimezoneDetect

Он основан на настройке часового пояса вашей платформы или устройства, а не работает с IP-адресами геолокации, которые могут вводить в заблуждение корпоративные сети, интернет-провайдеры и VPN. Это было быстро и способствовало его точности.

Моя цель состояла в том, чтобы определить часовой пояс пользователя и позволить ему обновлять свои настройки быстро и без отвлекающих факторов. Первое, что меня беспокоило, когда пользователь устанавливал часовой пояс, было, когда они добавляли время встречи к новой встрече.

Например, когда они нажимают значок « плюс» рядом с « Когда» для встреч:

Построение вашего запуска часового пояса обнаружения - время встречи в PST

Например, если я живу в Торонто, Канада, в восточном часовом поясе и посещаю Планировщик собраний, его настройкой по умолчанию является PST, что на три часа позади. Таким образом, мое время встречи выше 7:30 вечера не будет правильным.

Теперь, если jsTimezoneDetect определит, что вы находитесь в другом часовом поясе (например, Торонто), чем ваш текущий пользовательский параметр (например, Лос-Анджелес), он спросит вас, хотите ли вы изменить его:

Построение вашего запуска часового пояса обнаружения - всплывающее окно, чтобы изменить свой часовой пояс

На приведенном выше снимке экрана я использовал настройки даты и времени MacOS (вверху справа), чтобы изменить часовой пояс по сравнению с текущим параметром Планировщика собраний и позволить мне проверить его изменение.

После обновления часового пояса более ранний выбор времени будет отображаться во времени Восточного побережья:

Построение стартапа Обнаружение часового пояса - время встречи в восточном побережье

Но в следующий раз, когда вы добавите время встречи, оно будет в вашем правильном часовом поясе.

Я не хотел, чтобы пользователи переходили на страницу настроек, чтобы внести изменения, и теряли свое место при планировании встречи. Поэтому, хотя это заняло дополнительное время, я написал на этой странице несколько файлов AJAX, которые обновили для них часовой пояс, чтобы они могли продолжить планирование.

Ниже вы можете видеть, что после того, как вы щелкнете по новому часовому поясу, статус предупреждает вас о том, что он был обновлен, и вы можете продолжать добавлять время встречи, не теряя своего места:

Построение вашего запуска обнаружения часового пояса - ваш часовой пояс был успешно обновлен оповещения

Чтобы построить это, я начал работать над интерфейсом / views / meeting-time / _form.php выше. Сначала я добавил JavaScript для определения часового пояса и управления оповещениями:

1
2
3
4
<?php ActiveForm::end();
  $this->registerJsFile(MiscHelpers::buildUrl().’/js/jstz.min.js’,[‘depends’ => [\yii\web\JqueryAsset::className()]]);
  $this->registerJsFile(MiscHelpers::buildUrl().’/js/meeting_time.js’,[‘depends’ => [\yii\web\JqueryAsset::className()]]);
  ?>

Я также создал некоторые скрытые переменные формы для поддержки скрипта:

1
2
3
4
<?php $form = ActiveForm::begin();?>
   <?= BaseHtml::activeHiddenInput($model, ‘url_prefix’,[‘value’=>\common\components\MiscHelpers::getUrlPrefix(),’id’=>’url_prefix’]);
   <?= BaseHtml::activeHiddenInput($model, ‘tz_dynamic’,[‘id’=>’tz_dynamic’]);
   <?= BaseHtml::activeHiddenInput($model, ‘tz_current’,[‘id’=>’tz_current’]);

url_prefix помогает управлять адресацией JavaScript между средами разработки и производства. tz_current загружается из MeetingTimeController.php. Это текущий часовой пояс пользователя в Планировщике собраний. tz_dynamic   будет заполнен нашим сценарием обнаружения.

Я также создал два поля предупреждений в верхней части формы, которые по умолчанию будут скрыты, используя определения CSS их идентификаторов:

01
02
03
04
05
06
07
08
09
10
11
12
<div class=»tz_success» id=»tz_success»>
<div id=»w4-tz-success» class=»alert-success alert fade in»>
<button type=»button» class=»close» data-dismiss=»alert» aria-hidden=»true»>×</button>
<?= Yii::t(‘frontend’,’Your timezone has been updated successfully.’) ?>
</div>
</div>
<div class=»tz_warning» id=»tz_alert»>
<div id=»w4-tz-info» class=»alert-info alert fade in»>
<button type=»button» class=»close» data-dismiss=»alert» aria-hidden=»true»>×</button>
<?= Yii::t(‘frontend’,’Would you like us to change your timezone setting to <span id=»tz_new»>
</div>
</div>

tz_alert появляется, если обнаруженный часовой пояс отличается от ваших текущих настроек. tz_success появляется, если вы меняете часовой пояс.

Обратите внимание также на пустой тег span:

...change your timezone setting to <span id="tz_new"></span>?') ?>

Скрипт разместит там AJAX-ссылку для tz_detect , которую вы увидите в нашем скрипте.

Вот выдержка из frontend / web / js / meeting_time.js:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$(document).ready(function(){
    // detect user timezone
    var tz = jstz.determine();
    var timezone = tz.name();
    $(‘#tz_dynamic’).val(timezone);
    // compare to current setting
    if (timezone != $(‘#tz_current’).val()) {
      // set the text span alert
      $(‘#tz_new’).html(‘<a onclick=»setTimezone(\»+timezone+’\’)» href=»javascript:void(0);»>’+timezone+'</a>’);
      $(‘#tz_alert’).show();
    }
  });
 
function setTimezone(timezone) {
  $.ajax({
     url: $(‘#url_prefix’).val()+’/user-setting/timezone’,
     data: {‘timezone’: timezone},
     success: function(data) {
       $(‘#tz_alert’).hide();
       $(‘#tz_success’).show();
       return true;
     }
  });
}

В приведенной выше функции $(document).ready() она вызывает jsTimezoneDetect() и проверяет, jsTimezoneDetect() ли текущий часовой пояс пользователя. Если это так, он заменяет пустой тег span ссылкой JavaScript на setTimezone() и отображает окно предупреждения.

Функция setTimezone делает AJAX-вызов к UserSettingController.php:

1
2
3
4
5
6
7
public function actionTimezone($timezone) {
     // set current logged in user timezone than return
     Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
     $user_id = Yii::$app->user->getId();
     UserSetting::setUserTimezone($user_id,$timezone);
     return true;
   }

Он легко обновляет настройки часового пояса, не требуя посещения страницы настроек.

Затем JavaScript закрывает предупреждение и показывает окно успеха.

JavaScript и AJAX всегда занимают у меня больше времени, чем PHP, но UX действительно хорошо работает с этой функцией.

Я обнаружил, что jsTimezoneDetect является быстрым и абсолютно точным во всех моих тестах.

Я решил применить это дружественное обнаружение к странице настроек, чтобы пользователю не нужно было щелкать раскрывающийся список и пролистывать десятки и десятки часовых поясов.

Построение запуска при обнаружении часового пояса - обновите настройки с помощью всплывающего окна определения часового пояса

Если они щелкают по обнаруженной ссылке часового пояса, появляется успешно сохраненное предупреждение, и для них делается настройка в раскрывающемся списке Местный часовой пояс . Там на самом деле нет необходимости отправлять форму.

Построение вашего запуска часового пояса обнаружения - ваш часовой пояс был успешно сохранен оповещение

Чтобы реализовать это, я создал почти идентичный файл JavaScript для frontend / web / js / user_setting.js:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$(document).ready(function(){
    // detect user timezone
    var tz = jstz.determine();
    var timezone = tz.name();
    $(‘#tz_dynamic’).val(timezone);
    // compare to current setting
    if (timezone != $(‘#tz_combo’).val()) {
      // set the text span alert
      $(‘#tz_new’).html(‘<a onclick=»setTimezone(\»+timezone+’\’)» href=»javascript:void(0);»>’+timezone+'</a>’);
      $(‘#tz_alert’).show();
    }
  });
 
function setTimezone(timezone) {
  $.ajax({
     url: $(‘#url_prefix’).val()+’/user-setting/timezone’,
     data: {‘timezone’: timezone},
     success: function(data) {
       $(‘#tz_alert’).hide();
       $(‘#tz_success’).show();
       $(‘#tz_combo’).val(timezone);
       return true;
     }
  });
}

После завершения он обновляет раскрывающееся значение #tz_combo для пользователя с новым часовым поясом.

Все это прекрасно работает для новых пользователей, планирующих свою первую встречу. Но как насчет получателей приглашения на собрание? Люди, встречающиеся лично, в основном будут находиться в одном часовом поясе, но для виртуальных собраний, таких как конференц-связь, могут потребоваться другие часовые пояса.

Если вы прочитали эпизод « Экспорт файлов iCal в календари» , вы, возможно, помните, что мы включили настройку часового пояса в наш экспорт файла ics:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
DTSTART:20160506T013000Z
DTEND:20160506T023000Z
DTSTAMP:20160506T013000Z
ORGANIZER;CN=admin:mailto:[email protected]
URL;VALUE=URI:http://localhost:8888/mp/index.php/meeting/command?id=45&amp;cmd=10&amp;actor_id=1&amp;k=ESxJU_2ZRhZIgzHFyJAIiC39RhZuLiM_&amp;obj_id=0
ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=robsmith;X-NUM-GUESTS=0:mailto:[email protected]
ATTENDEE;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=admin;X-NUM-GUESTS=0:mailto:[email protected]
CREATED:
DESCRIPTION:It was fun running into you — let’s definitely grab that beer!
LAST-MODIFIED:20160506T013000Z
LOCATION:Patxi’s Pizza Ballard 5323 Ballard Ave NW Seattle WA 98107
SUMMARY:Meetup for Pizza and Long Delayed Conversation
SEQUENCE:0
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

Это гарантирует, что получатель будет видеть тот же часовой пояс, что и органайзер, когда они импортируют файл .ics в свой календарь.

Все наши времена собраний хранятся в базе данных как общие временные метки Unix в часовом поясе GMT, и наш дисплей настраивается в зависимости от местного часового пояса каждого пользователя.

Однако мне все равно нужно будет добавить обнаружение JavaScript на страницы планирования собраний и страницы подтверждения для получателей, чтобы им было предложено настроить часовой пояс для просмотра правильного времени собрания.

В настоящее время я работаю над кодом в бета-версии Meeting Planner. Я работаю над множеством функций, связанных с отправкой запросов на изменение или прямым изменением собраний после их подтверждения. Это требует много концептуальных размышлений о том, как упростить планирование для людей. Я напишу больше об этом в ближайшее время.

Как всегда, пожалуйста, следите за обновлениями этого и последующих учебников из серии « Построение стартапа с помощью PHP» . Вы уже запланировали встречу через Meeting Planner? Нет? Чего же ты ждешь? Сделай это сейчас! И как всегда, дайте мне знать, что вы думаете ниже или в комментариях. Я признателен за это. Вы также можете обратиться ко мне @reifman . Я всегда открыт для новых идей и тематических предложений для будущих уроков.

Я также планирую написать учебное пособие по краудфандингу, поэтому просим вас посетить нашу страницу Планировщика собраний WeFunder .