Если кто-то из пользователей MacOS вынужден следить за временем в разных часовых поясах (ну или наслаждается этим процессом глобализации), он, возможно, захочет использовать для этих целей Dashboard и стандартный виджет World Clock.
Однако, к сожалению, этот виджет не позволяет отображать время для всех нужных городов, к примеру, в нем от рождения нет Минска! Краем уха я слышал, что виджеты для дашборда наврайчены на javascript/css/html. Итак, пришло время посмотреть, так ли это, и исправить недоразумение с недостатком городов. Я не задавался целью изучать API виджетов, это скорее туториал для людей, не совсем близких к программированию.
Приступим
Итак, первой задачей было отыскать местоположение виджетов в системе. Нашлись они быстро в директории /Library/Widgets/. Я новенький в макоси, идея с директориями, как пакетами, мне показалась интересной.
Находим:
Открываем:
Собственно, дальше нас встречает привычная многим структура статического сайта. Наш клиент находится в файле WorldClock.js. Если ваш редактор позволяет повышать привилегии пользователя для записи в системные директории после редактирования, читать дальше вам не нужно. Если же вы не знаете как это сделать, я советую перед редактированием скопировать файл WorldClock.js куда-нибудь в другое место, например, на рабочий стол, редактировать его там и потом перенести назад в директорию /Library/Widgets/World Clock/. На всякий случай сделайте резервную копию исходного файла где-нибудь в другом месте.
Открываем файл, видим примерно следующие строчки:
Нас интересует две вещи:
Регион, например Европа или Азия, и город, которого нам так не хватает.
Выглядит это следующим образом:
var Europe = [
{city:'Amsterdam', offset:120, timezone:'Europe/Amsterdam', id:"2759794"},
// …
// много городов
]
Итак, разбираемся, что тут написано.
- Регион: Европа;
- Город: Амстердам;
- Offset (смещение): Это UTC offset для вашего часового пояса. Если у вас есть перевод на летнее время и обратно, это смещение нужно указывать для обычного или «зимнего», как его еще называют, времени. Указывать нужно в минутах. Для смещения +03:00 это будет 180, для -01:30 это будет -90;
- Timezone: тут используется какой-то странный для меня формат, я честно говоря не понял, зачем отдельно нужно указывать этот пункт вообще;
- Id: непонятные пока чиселки.
Давате разберемся, для чего нам нужна Timezone и Id. Судя по беглому просмотру кода, по таймзоне мы тащим данные о времени (зимнее / летнее), а по id сохраняем информацию о настройках виджета. Я бы убрал к чертовой матери всю эту информацию о таймзоне и UTC смещении. Вообще весь код производит удручающее впечатления студенческой работы. Ознакомится с его содержанием можно по адресу:
gist.github.com/1284923
Разбираемся с таймзоной: я тупо вбил туда данные по образцу из файла: «Континент/Город». Если кто-то подскажет, что за формат, я с радостью дополню статью. Айди в коде назван еще и GeoId, давайте посмотрим… Так и есть:
Найти геоайди вашего города можно на сайте geonames.org, хотя, в текущей реализации виджета, можно с чистой совестью туда вбить первый попавшейся набор цифр, не совпадающий с остальными городами.
В общем, строчка для Минска будет выглядеть так (плохо знакомым с javascript людям посоветую не забыть запятую в конце строки):
{city:'Minsk',offset:180,timezone:'Europe/Minsk',id:"625144"},
Сохраняем файл, создаем новый виджет… вуаля, Минск с нами!
Конечно же, лучшим решением было бы сделать возможность добавлять любые города по вкусу, однако это совсем другие трудозатраты, согласитесь. Спасибо за внимание, надеюсь, это кому-то облегчит жизнь.
P. S. Если вы хотите локализованого имени города, вам необходимо отредактировать файл localizedStrings.js, который расположен в директории с виджетом и в поддиректории с именем вашей локали. К примеру для русской локали это будет /Library/Widgets/World\ Clock/ru.lproj/localizedStrings.js.
В файл необходимо добавить строку вида:
localizedCityNames['Minsk'] = 'Мiнск';
Если для вас это слишком сложно, просто напишите имя города на удобном вам языке в строчке из файла WorldClock.js:
{city:'Мiнск',offset:180,timezone:'Europe/Minsk',id:"625144"},