Склонение слов 'год', 'года', 'лет' с помощью JavaScript

Раздел: Основы 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 лет

Склонение дат (год/года/лет) в JavaScript - comments

En
Js год года лет (javascript)