В каком формате передаются телефонные номера, с префиксом +7 или без, и сколько цифр
Что проверяют
Вопрос про договорённость о формате данных: знаете ли вы стандарт, умеете ли нормализовать ввод и где проводите границу валидации. Следом обычно спрашивают, как хранить номер в базе и что делать с номерами других стран.
Как отвечать
Сначала факты. Международный стандарт это E.164: знак +, код страны и номер, всего не больше 15 цифр, без пробелов и скобок. У России код страны 7 и национальный номер из 10 цифр, итого 11 цифр: +79111234567. Восьмёрка в начале это внутренний префикс междугородней связи, а не часть номера, поэтому 89111234567 и +79111234567 один и тот же абонент.
Каркас ответа:
- контракт API: принимать можно в разных видах, но между сервисами и в базе номер живёт в одном формате, обычно строкой E.164. Это фиксируется в схеме, например в OpenAPI или модели Pydantic;
- нормализация на входе: убрать пробелы, скобки и дефисы, заменить ведущую 8 на
+7для российских номеров, затем проверить; - валидация библиотекой:
phonenumbers(порт Google libphonenumber) разбирает номер черезphonenumbers.parse(raw, "RU"), проверяетis_valid_number()и форматирует черезformat_number(num, PhoneNumberFormat.E164). Для Pydantic есть типPhoneNumberвpydantic-extra-types, для Django пакетdjango-phonenumber-field; - хранение: строка, а не число. У числа теряется
+, а арифметика над телефоном бессмысленна; - отображение:
+7 (911) 123-45-67это формат для людей, его строят при выводе, а не хранят.
Если речь о конкретном проекте, стоит прямо спросить, какой формат ждёт внешний сервис: СМС-шлюзы и CRM нередко хотят номер без + или только 10 цифр, и тогда преобразование делают на границе интеграции.
Где спотыкаются
Пишут регулярку «11 цифр, начинается на 7 или 8» и считают номер валидным. Код 7 делят Россия и Казахстан, а правильная длина не гарантирует, что такой номер вообще существует.
Хранят номер в BIGINT или в том виде, в каком его ввёл пользователь. Потом поиск по номеру и дедупликация перестают работать.
Требуют, чтобы российский номер начинался с 9. Это верно только для мобильных, стационарные номера и 8-800 отсекаются.