Склонение слов 'год', 'года', 'лет' с помощью JavaScript
Основные подходы к склонению слова "год"
Как реализовать правильное написание "год", "года", "лет" в зависимости от числа наиболее простым и эффективным способом?
Самым распространённым решением является функция, которая вычисляет остаток от деления числа на 10 и на 100. Она учитывает числа от 11 до 19, для которых всегда используется слово "лет", и корректно определяет форму для остальных.
function getYearWord(n) {
const remainder10 = n % 10;
const remainder100 = n % 100;
if (remainder100 >= 11 && remainder100 <= 19) return 'лет';
if (remainder10 === 1) return 'год';
if (remainder10 >= 2 && remainder10 <= 4) return 'года';
return 'лет';
}Js date (дата в javascript)
Примеры работы:
getYearWord(1) // 'год' getYearWord(2) // 'года' getYearWord(5) // 'лет' getYearWord(11) // 'лет' getYearWord(21) // 'год' getYearWord(22) // 'года' getYearWord(100) // 'лет'
Js время (работа с временем в javascript)
Этот подход не требует дополнительных библиотек, работает быстро и легко адаптируется под другие слова.
Как склонять слово "год" с помощью массива и вычисления индекса?
Вместо цепочки условных операторов можно использовать массив с тремя формами и вычислять индекс по тому же правилу:
const yearForms = ['год', 'года', 'лет'];
function getYearWordArr(n) {
const remainder100 = n % 100;
const remainder10 = n % 10;
if (remainder100 >= 11 && remainder100 <= 19) return yearForms[2];
if (remainder10 === 1) return yearForms[0];
if (remainder10 >= 2 && remainder10 <= 4) return yearForms[1];
return yearForms[2];
}
Js год года лет (склонение дат (год/года/лет) в javascript)
Такой вариант удобен, когда нужно менять список слов или добавлять новые языки.
Как использовать объект с правилами для склонения?
Можно описать варианты в объекте и выбирать нужный по ключу:
const yearRules = {
'год': [1],
'года': [2, 3, 4],
'лет': [0, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19]
};
function getYearWordObj(n) {
const remainder10 = n % 10;
const remainder100 = n % 100;
if (remainder100 >= 11 && remainder100 <= 19) return 'лет';
if (remainder10 === 1) return 'год';
if (remainder10 >= 2 && remainder10 <= 4) return 'года';
return 'лет';
}
Данный метод нагляден, но избыточен для простой задачи. Его стоит применять, если требуется много различных склонений в одном месте.
Как применить Intl.PluralRules для автоматического определения формы?
Современный браузерный API Intl.PluralRules позволяет получить категорию числа (one, few, many, other) для заданной локали. Для русского языка:
const pluralRules = new Intl.PluralRules('ru');
const yearFormsIntl = {
one: 'год',
few: 'года',
many: 'лет',
other: 'лет'
};
function getYearWordIntl(n) {
const category = pluralRules.select(n);
return yearFormsIntl[category];
}
Это решение автоматически обрабатывает числа 11-19 (категория many) и корректно работает для всех целых чисел. Недостаток - требуется поддержка Intl, которая есть во всех современных браузерах.
Типичные ошибки и их решение
- Игнорирование чисел 11-19. Если в функции проверяется только остаток от деления на 10, то для чисел 11, 12 и т.д. функция вернёт неверную форму. Решение - всегда проверять остаток от 100 перед остатком от 10.
- Путаница с типами данных. Если число передано как строка, оператор % может дать неожиданный результат. Лучше явно преобразовывать в Number: Number(n).
- Локализация. При использовании Intl.PluralRules нужно указывать правильную локаль. Для русского языка - 'ru'. Если указать 'en', формы будут отличаться.
- Отрицательные числа. Стандартная формула работает и для отрицательных чисел, но если требуется склонять только для неотрицательных, стоит добавить проверку n < 0 и вернуть 'лет' или выбросить ошибку.
Расширенные примеры использования склонения дат
Ниже приведены более сложные сценарии, которые могут потребоваться в реальных проектах.
1. Функция для склонения не только года, но и других единиц времени
Универсальная функция, принимающая массив форм для разных числовых категорий:
function pluralize(n, forms) {
const remainder100 = n % 100;
const remainder10 = n % 10;
if (remainder100 >= 11 && remainder100 <= 19) return forms[2];
if (remainder10 === 1) return forms[0];
if (remainder10 >= 2 && remainder10 <= 4) return forms[1];
return forms[2];
}
// Примеры использования
const yearForms = ['год', 'года', 'лет'];
const monthForms = ['месяц', 'месяца', 'месяцев'];
const dayForms = ['день', 'дня', 'дней'];
console.log(`5 ${pluralize(5, yearForms)}`); // 5 лет
console.log(`1 ${pluralize(1, monthForms)}`); // 1 месяц
console.log(`21 ${pluralize(21, dayForms)}`); // 21 день
5 лет 1 месяц 21 день
2. Обработка чисел с плавающей точкой и отрицательных значений
Иногда требуется склонять нецелые числа, например, 2.5 года. Для дробных чисел используется форма множественного числа (кроме 1.0). Правило: если целая часть равна 1 и дробная часть отсутствует - 'год', иначе - 'года' для 2-4 и 'лет' для остальных. Упрощённый вариант:
function getYearWordFloat(n) {
const intPart = Math.floor(Math.abs(n));
const remainder100 = intPart % 100;
const remainder10 = intPart % 10;
if (remainder100 >= 11 && remainder100 <= 19) return 'лет';
if (remainder10 === 1) return 'год';
if (remainder10 >= 2 && remainder10 <= 4) return 'года';
return 'лет';
}
console.log(`2.5 ${getYearWordFloat(2.5)}`); // 2.5 года
console.log(`1.0 ${getYearWordFloat(1.0)}`); // 1.0 год
console.log(`-3 ${getYearWordFloat(-3)}`); // -3 года
2.5 года 1.0 год -3 года
3. Форматирование строки "N год(а)/лет назад"
Функция, которая возвращает готовую фразу с правильным склонением:
function yearsAgo(n) {
const word = getYearWord(n);
return `${n} ${word} назад`;
}
console.log(yearsAgo(1)); // 1 год назад
console.log(yearsAgo(3)); // 3 года назад
console.log(yearsAgo(10)); // 10 лет назад
1 год назад 3 года назад 10 лет назад
4. Использование с объектом Date для вычисления возраста
Пример вычисления количества полных лет между двумя датами и склонения:
function ageString(birthDate, currentDate = new Date()) {
const ageYears = currentDate.getFullYear() - birthDate.getFullYear();
const monthDiff = currentDate.getMonth() - birthDate.getMonth();
if (monthDiff < 0 || (monthDiff === 0 && currentDate.getDate() < birthDate.getDate())) {
ageYears--;
}
return `${ageYears} ${getYearWord(ageYears)}`;
}
const birth = new Date(1990, 5, 15);
console.log(ageString(birth)); // например: 34 года (зависит от текущей даты)
34 года
5. Автоматическое склонение для больших чисел (тысячи, миллионы)
При работе с большими числами слово "год" склоняется по тем же правилам. Пример для чисел до 10⁹:
function formatYears(n) {
const suffixes = ['', 'тысяча', 'миллион', 'миллиард'];
const word = getYearWord(n % 1000);
return `${n} ${word}`;
}
console.log(formatYears(1001)); // 1001 год
console.log(formatYears(2000)); // 2000 лет
1001 год 2000 лет