Портрет 4X_Pro
Был в Сети 27 авг. 2025 г., 05:32
Мультиблог
4X_Pro
Кратко о себе: Web-разработчик. Пишу на PHP, Python, JavaScript. Знаю Ruby и Go, со студенческих времён более-менее помню C и asm. Специализируюсь на ускорении загрузки сайтов и разработке ботов для Telegram. Linuxоид (использую Debian+LXDE). Сторонник IndieWeb, slow lifer.

Социальные сети


Новости сайта в Telegram

t.me/4x_pro

Компьютерное

Часовой пояс в ботах для Telegram

4X_Pro

Часто при разработке ботов для Telegram требуется учитывать информацию о часовом поясе пользователя. К сожалению, получить её через Bot API невозможно, поэтому предусматривать в боте команду, с помощью которой пользователь сможет указать, какой часовой пояс он использует. И тут возникает вопрос, как лучше это сделать, чтобы пользователю было удобно. Если бот ориентирован только на российских пользователей, вопрос решается просто: выводим список всех часовых поясов России, пользователь выбирает нужный, и бот сохраняет выбор в базу данных.
Но как быть, если пользователи могут быть из других стран? Выводить огромный список из более чем сотни часовых поясов — крайне неудобно. Требовать от пользователя вручную написать название его часового пояса в формате Europe/Moscow или хотя бы MSK — тоже не самое лучшее решение. Можно предложить указать смещение в формате ±ЧЧ:ММ, но тогда нельзя будет учесть переход на летнее время.

В поисках более удобного решения я наткнулся на модули tzwhere и geopy. Первый позволяет определить часовой пояс для того или иного местоположения, заданного с помощью координат. Второй — получить эти самые координаты по названию города, причём позволяет это делать через Google Maps API, API Яндекс.Карт и ещё почти десяток сервисов. Я решил использовать Nominatim (это сервис Open Street Maps), так как он не требует получения tokenа, в отличие от Яндекс и Google, и при этом понимает названия городов и на английском языке, и на русском.
В итоге код определения часового пояса выглядит примерно так:
import geopy from tzwhere import tzwhere import datetime import pytz def get_timezone(bot,chat_id,city): geo = geopy.geocoders.Nominatim(user_agent="SuperMon_Bot") location = geo.geocode(city) # преобразуе if location is None: bot.send_message(chat_id,"Не удалось найти такой город. Попробуйте написать его название латиницей или указать более крупный город поблизости.") else: tzw = tzwhere.tzwhere() timezone_str = tzw.tzNameAt(location.latitude,location.longitude) # получаем название часового пояса tz = pytz.timezone(timezone_str) tz_info = datetime.datetime.now(tz=tz).strftime("%z") # получаем смещение часового пояса tz_info = tz_info[0:3]+":"+tz_info[3:] # приводим к формату ±ЧЧ:ММ bot.send_message(chat_id,"Часовой пояс установлен в %s (%s от GMT)." % (timezone_str,tz_info)) # здесь должно быть сохранение выбранной строки в БД return timezone_str
Приведение даты к нужному часовому поясу перед выводом пользователю делается либо с помощью метода tz.localize(dt) (для так называемых naive date, то есть не содержащих информацию о часовом поясе), либо с помощью метода dt.astimezone(tz), где dt — объект класса datetime, а tz — timezone.

Красивая транслитерация для URL с помощью AWS Lambda

4X_Pro

Занимаясь SEO, столкнулся с тем, что во многих CMS URLы для страниц генерируются так: название прогоняется через транслитератор, потом небуквенные символы заменяются на _, и на этом все. С учетом того, что при наполнении сайта данные часто вставляются через буфер обмена с лишними пробелами, получаем ужасные адреса вида http://example.com/-ochen-horoshiy--tovar_-_kupite-оbyazatelno_. Глядя на это, я решил, что нужно создать транслитератор, который будет делать красивые URL. Такой транслитератор должен уметь следующее:

  • делать регистр букв всегда нижним
  • удалять все посторонние символы, кроме букв, цифр, тире и прочерков, а пробелы заменять на «-» (в соответствии с рекомендациями Google);
  • обрезать пробелы по краям, а также несколько пробелов, идущих подряд;
  • уметь обрезать URL по первой запятой (это полезно для многих магазинов, где после запятой часто идут второстепенные параметры товара, которые не требуется выносить в URL);
  • уметь обрезать URL по границе слова так, чтобы не превышать указанную длину.

Встроить такое в какую-либо конкретную CMS несложно. Но хотелось сделать какое-то более универсальное решение — API, к которой можно было бы обращаться из любой CMS. И вот недавно я узнал о бессерверных вычислениях и платформе Lambda для Amazon Web Services. Я счел, что она для таких задач подходит идеально и решил попробовать её в деле.
"Подробнее о том, как создавался такой транслитератор и пример интеграции"

Время выполнения кода в PHP и Python

4X_Pro

Иногда при написании скриптов требуется узнать, сколько времени скрипт выполняется. Для этого есть несколько способов. Во-первых, можно воспользоваться стандартной для Unix-систем утилитой time:
time script.sh time python script.py time php script.php
Она выдаст что-то вроде
real 0m0.012s user 0m0.004s sys 0m0.000s
Здесь нас интересует первое значение: real. Оно показывает, сколько реального времени заняло выполнение скрипта. User и sys показывают потраченное процессорное время в режиме пользователя и режиме ядра, которое, даже суммарно, может быть меньше реального из-за простоя и ожидания.
Но утилита time замеряет полное время выполнения, с учетом затрат на запуск интерпретатора, загрузку скрипта и т.п., что не всегда желательно.
Поэтому иногда бывает целесообразнее использовать средства самого языка программирования. В PHP для этого используется функция microtime:
$start_time = microtime(true); // true — получать данные в // какой-то код $time = microtime(true)-$start_time; // в переменой $time будет время в секундах, // которое потрачено на выполнение кода
В Python все аналогично, только необходимо подключить модуль time:
import time start_time = time.time() # какой-то код time = time.time()-start_time  // время выполнения также будет в секундах
В JavaScript это выглядит чуть иначе — необходимо использовать объекты Date:
let start_time = new Date; # какой-то код time = (new Date -start_time)/1000  // разность между двумя объектами Date измеряется в милисекундах, // поэтому делим ее на тысячу


Задать вопрос

Здесь можно задать мне вопрос или спросить совета по любой теме, затронутой в блогах или на форуме. После того, как я отвечу, вопрос и ответ появятся в соответствующем разделе. Но не забываем, что я — сторонник slow life, поэтому каких-либо сроков ответов не обещаю. Самые интересные вопросы станут основой для новых тем на форуме или записей в блоге.
Сразу предупреждаю: глупости, провокации, троллинг и тому подобное летит прямо в /dev/null.