Как отображать относительное время в краткой или полной форме

Используйте опцию style, чтобы управлять тем, как относительное время отображается: сокращённо, полностью или в виде компактных символов

Введение

Когда вы показываете относительное время, например «2 часа назад» или «через 3 месяца», формат занимает разное количество места. Метка времени, показывающая возраст контента, может выглядеть как «2 часа назад», «2 ч назад» или «2ч назад» — в зависимости от того, сколько у вас места и насколько важна читаемость. Каждый формат балансирует между удобочитаемостью и экономией горизонтального пространства.

В разных ситуациях нужны разные форматы. В ленте соцсетей для отметок времени лучше использовать понятный текст вроде «2 часа назад». На мобильной панели с несколькими индикаторами активности удобнее компактный вариант — «2ч назад». В визуализации данных, где на экране много событий, используют максимально сжатую форму, чтобы уместить всю информацию.

В JavaScript Intl.RelativeTimeFormat есть опция style, которая позволяет выбрать нужный формат. Можно выбрать длинный вариант с полностью написанными словами, короткий — со стандартными сокращениями, или узкий — с самой компактной записью. Эта опция даёт вам полный контроль над тем, как пользователи увидят относительное время.

Что регулирует опция style

Опция style в Intl.RelativeTimeFormat принимает три значения: "long", "short" и "narrow". Каждое значение определяет степень подробности отображения относительного времени.

Значение long полностью пишет слова, например: «2 часа назад». Значение short использует стандартные сокращения, например: «2 ч назад». Значение narrow даёт самый компактный вариант, например: «2ч назад», часто без пробелов и с минимальным количеством символов.

const longFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "long"
});

console.log(longFormatter.format(-2, "hour"));
// Output: "2 hours ago"

const shortFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "short"
});

console.log(shortFormatter.format(-2, "hour"));
// Output: "2 hr. ago"

const narrowFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "narrow"
});

console.log(narrowFormatter.format(-2, "hour"));
// Output: "2h ago"

Опция style по умолчанию устанавливается в "long", если вы её не укажете. Это значит, что для форматирования относительного времени используются полные слова, если вы явно не выберете другой стиль отображения.

Форматирование относительного времени в длинном стиле

Длинный стиль полностью прописывает слова. Такой формат обеспечивает максимальную ясность, но занимает больше горизонтального пространства.

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "long"
});

console.log(formatter.format(-2, "hour"));
// Output: "2 hours ago"

console.log(formatter.format(3, "day"));
// Output: "in 3 days"

Форматтер автоматически различает единственное и множественное число. Для одного часа используется форма "час", для нескольких — "часов". Вам не нужно определять форму вручную.

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "long"
});

console.log(formatter.format(-1, "hour"));
// Output: "1 hour ago"

console.log(formatter.format(-2, "hour"));
// Output: "2 hours ago"

console.log(formatter.format(1, "day"));
// Output: "in 1 day"

console.log(formatter.format(5, "day"));
// Output: "in 5 days"

Каждая единица времени полностью прописывается вне зависимости от выбранной единицы.

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "long"
});

console.log(formatter.format(-30, "second"));
// Output: "30 seconds ago"

console.log(formatter.format(-5, "minute"));
// Output: "5 minutes ago"

console.log(formatter.format(-3, "month"));
// Output: "3 months ago"

console.log(formatter.format(2, "year"));
// Output: "in 2 years"

Длинный стиль делает относительное время сразу понятным, не заставляя пользователей разгадывать сокращения. Тем, кто не знаком с сокращениями времени, проще воспринимать полностью написанные слова.

Форматирование относительного времени в коротком стиле

Короткий стиль использует стандартные сокращения, которые большинству знакомы. Такой формат сочетает читаемость и экономию места.

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "short"
});

console.log(formatter.format(-2, "hour"));
// Output: "2 hr. ago"

console.log(formatter.format(3, "day"));
// Output: "in 3 days"

Форматтер использует общеизвестные сокращения. Часы — "ч", минуты — "мин", секунды — "сек". Эти сокращения сохраняют читаемость и уменьшают количество символов.

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "short"
});

console.log(formatter.format(-30, "second"));
// Output: "30 sec. ago"

console.log(formatter.format(-5, "minute"));
// Output: "5 min. ago"

console.log(formatter.format(-3, "month"));
// Output: "3 mo. ago"

console.log(formatter.format(2, "year"));
// Output: "in 2 yr."

Каждая единица времени использует своё стандартное сокращение. Секунды — "сек", минуты — "мин", месяцы — "мес", годы — "г". Эти сокращения хорошо узнаваемы и подходят для большинства случаев.

Вы можете форматировать как прошедшее, так и будущее время в коротком стиле.

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "short"
});

console.log(formatter.format(-7, "day"));
// Output: "7 days ago"

console.log(formatter.format(2, "week"));
// Output: "in 2 wk."

console.log(formatter.format(-1, "quarter"));
// Output: "1 qtr. ago"

Форматтер одинаково обрабатывает оба направления. Для прошедшего времени используется "назад", для будущего — "через". Сокращения остаются теми же независимо от направления.

Форматирование относительного времени в узком стиле

Узкий стиль обеспечивает максимально компактное отображение. В этом формате убираются пробелы и используются минимальные символы, чтобы сэкономить каждый знак.

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "narrow"
});

console.log(formatter.format(-2, "hour"));
// Output: "2h ago"

console.log(formatter.format(3, "day"));
// Output: "in 3 days"

Форматтер использует однобуквенные сокращения и минимальные пробелы для большинства единиц. Часы становятся «ч», минуты — «м», секунды — «с». Такой вывод компактнее, чем в коротком или длинном стиле.

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "narrow"
});

console.log(formatter.format(-30, "second"));
// Output: "30s ago"

console.log(formatter.format(-5, "minute"));
// Output: "5m ago"

console.log(formatter.format(-3, "month"));
// Output: "3mo ago"

console.log(formatter.format(2, "year"));
// Output: "in 2y"

Узкий стиль зависит от языка и единицы измерения. Для некоторых единиц результат становится заметно короче, а для других почти не отличается от короткого стиля. В английском «days» пишется полностью, а часы, минуты и секунды сокращаются до одной буквы.

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "narrow"
});

console.log(formatter.format(-7, "day"));
// Output: "7 days ago"

console.log(formatter.format(2, "week"));
// Output: "in 2w"

console.log(formatter.format(-1, "quarter"));
// Output: "1q ago"

Узкий стиль лучше всего подходит, когда пространство очень ограничено, а пользователи знакомы с контекстом измерения времени. Такой сжатый формат предполагает, что пользователи смогут понять единицы без явных разделителей или пояснений.

Сравнение длинного, короткого и узкого стилей

Различия между тремя стилями становятся очевидны, если отформатировать одни и те же относительные значения времени с каждым вариантом.

const longFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "long"
});

const shortFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "short"
});

const narrowFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "narrow"
});

const value = -2;
const unit = "hour";

console.log("Long:   " + longFormatter.format(value, unit));
console.log("Short:  " + shortFormatter.format(value, unit));
console.log("Narrow: " + narrowFormatter.format(value, unit));

// Output:
// Long:   2 hours ago
// Short:  2 hr. ago
// Narrow: 2h ago

Длинный стиль использует полные слова и явные пробелы. Короткий — стандартные сокращения с точками. Узкий — однобуквенные обозначения с минимальными пробелами. Эта последовательность показывает компромисс между наглядностью и экономией места.

Можно сравнить разные значения относительного времени, чтобы увидеть, как каждый стиль справляется с разными промежутками.

const times = [
  { value: -30, unit: "second" },
  { value: -5, unit: "minute" },
  { value: -2, unit: "hour" },
  { value: 3, unit: "day" },
  { value: 2, unit: "week" },
  { value: -3, unit: "month" }
];

times.forEach(time => {
  const long = new Intl.RelativeTimeFormat("en-US", {
    style: "long"
  }).format(time.value, time.unit);

  const short = new Intl.RelativeTimeFormat("en-US", {
    style: "short"
  }).format(time.value, time.unit);

  const narrow = new Intl.RelativeTimeFormat("en-US", {
    style: "narrow"
  }).format(time.value, time.unit);

  console.log(`${time.value} ${time.unit}:`);
  console.log(`  Long:   ${long}`);
  console.log(`  Short:  ${short}`);
  console.log(`  Narrow: ${narrow}`);
  console.log("");
});

// Output:
// -30 second:
//   Long:   30 seconds ago
//   Short:  30 sec. ago
//   Narrow: 30s ago
//
// -5 minute:
//   Long:   5 minutes ago
//   Short:  5 min. ago
//   Narrow: 5m ago
//
// -2 hour:
//   Long:   2 hours ago
//   Short:  2 hr. ago
//   Narrow: 2h ago
//
// 3 day:
//   Long:   in 3 days
//   Short:  in 3 days
//   Narrow: in 3 days
//
// 2 week:
//   Long:   in 2 weeks
//   Short:  in 2 wk.
//   Narrow: in 2w
//
// -3 month:
//   Long:   3 months ago
//   Short:  3 mo. ago
//   Narrow: 3mo ago

Разница в количестве символов становится заметной при большом количестве временных меток. В ленте или списке с множеством относительных дат узкий стиль экономит значительное пространство по сравнению с длинным.

Как стили относительного времени различаются в разных языках

Все три варианта стиля адаптируются под выбранную локаль. Разные языки используют свои сокращения, слова и правила расстановки пробелов.

const locales = ["en-US", "de-DE", "fr-FR", "ja-JP"];

const value = -2;
const unit = "hour";

locales.forEach(locale => {
  const longFormatter = new Intl.RelativeTimeFormat(locale, {
    style: "long"
  });

  const shortFormatter = new Intl.RelativeTimeFormat(locale, {
    style: "short"
  });

  console.log(locale + ":");
  console.log("  Long:  " + longFormatter.format(value, unit));
  console.log("  Short: " + shortFormatter.format(value, unit));
});

// Output:
// en-US:
//   Long:  2 hours ago
//   Short: 2 hr. ago
// de-DE:
//   Long:  vor 2 Stunden
//   Short: vor 2 Std.
// fr-FR:
//   Long:  il y a 2 heures
//   Short: il y a 2 h
// ja-JP:
//   Long:  2 時間前
//   Short: 2 時間前

Длинный стиль сильно отличается в разных языках, потому что у каждого языка свои слова для единиц времени и свой порядок слов. Например, в немецком перед количеством времени ставится «vor», во французском — «il y a», а в японском показатель времени ставится после числа. Форматтер автоматически учитывает порядок слов.

Краткий стиль тоже подстраивается под локальные правила. В немецком для часов пишут «Std.», во французском — «h», а в японском используется тот же формат, что и для длинного стиля. Такие сокращения отражают, как в разных странах принято записывать время в сокращённой форме.

Форматтер автоматически учитывает грамматические особенности. Для каждого языка получается естественный и привычный результат.

const locales = ["en-US", "es-ES", "pt-BR"];

const value = -3;
const unit = "month";

locales.forEach(locale => {
  const narrowFormatter = new Intl.RelativeTimeFormat(locale, {
    style: "narrow"
  });

  console.log(locale + ": " + narrowFormatter.format(value, unit));
});

// Output:
// en-US: 3mo ago
// es-ES: hace 3 m
// pt-BR: há 3 meses

Узкий стиль тоже отличается в разных языках. В английском для месяцев пишут «mo», в испанском — «m», а в португальском полностью пишут «meses». Эти различия отражают особенности компактной записи времени в разных странах.

Когда использовать длинный стиль

Длинный стиль лучше всего подходит, когда важнее понятность и доступность, чем экономия места. Такой вариант делает относительное время сразу понятным, не требуя дополнительных разъяснений.

Интерфейсы, ориентированные на доступность, выигрывают от длинного стиля, потому что экранные дикторы лучше произносят полностью написанные слова. Например, «2 часа назад» звучит естественнее, чем «2 ч назад», которое может быть прочитано некорректно или потребовать специальных правил произношения.

Образовательные материалы выигрывают от длинного стиля, потому что не все ученики знакомы с сокращениями времени. В учебных материалах лучше писать единицы времени полностью, чтобы избежать путаницы.

В лентах активности и таймлайнах длинный стиль помогает сохранить понятный, разговорный тон. Сообщение в соцсетях с текстом «3 часа назад» воспринимается естественнее, чем «3ч назад» в тексте.

В официальных отчетах и документации используется полный стиль написания для поддержания единых стандартов оформления. В бизнес-отчетах, журналах аудита и официальных документах обычно время указывается полностью, а не сокращённо.

Международным пользователям проще воспринимать полный стиль, особенно если они только изучают язык. Полные названия единиц, такие как «часы» и «дни», понятнее для тех, кто не является носителем языка, чем сокращения.

function formatActivityTimestamp(date, locale) {
  const formatter = new Intl.RelativeTimeFormat(locale, {
    style: "long",
    numeric: "auto"
  });

  const now = new Date();
  const diffInMs = date - now;
  const diffInHours = Math.round(diffInMs / (1000 * 60 * 60));

  return formatter.format(diffInHours, "hour");
}

const threeHoursAgo = new Date(Date.now() - 3 * 60 * 60 * 1000);

console.log("Activity: " + formatActivityTimestamp(threeHoursAgo, "en-US"));
// Output: "Activity: 3 hours ago"

Полный стиль ставит на первое место понятность, а не краткость. Используйте его, когда пользователям важно безошибочно и без дополнительных усилий понять, сколько времени прошло.

Когда использовать краткий стиль

Краткий стиль лучше всего подходит для ситуаций, где важна экономия места, а сокращения хорошо известны. Такой формат сочетает ясность и эффективность.

Мобильные интерфейсы выигрывают от краткого стиля, потому что ширина экрана ограничена. На карточках дашборда с несколькими временными метками нужны компактные обозначения, чтобы вся информация помещалась на экране. Например, «2 ч назад» вместо «2 часа назад» экономит символы для каждой метки, что важно при большом количестве данных.

В разделах с комментариями используют краткий стиль, чтобы показывать время публикации без перегрузки интерфейса. Например, «5 мин назад» рядом с комментарием выглядит компактнее, чем «5 минут назад», но при этом остаётся понятным.

В таблицах данных с временными метками в столбцах важна одинаковая ширина. Краткие сокращения, такие как «ч», «мин» и «сек», позволяют держать столбцы узкими. Длинные варианты, такие как «часы», «минуты» и «секунды», делают столбцы шире без необходимости.

В панели уведомлений используют краткий стиль, потому что пользователи уже знакомы с сокращениями времени. Например, уведомление «1 ч назад» сочетает понятность и экономию места на экране.

В почтовых клиентах краткий стиль помогает показывать, сколько времени прошло с момента получения письма. Например, «2 дн назад» в списке писем выглядит понятнее, чем «2д назад», но занимает меньше места, чем полностью написанное «2 дня назад».

function formatCommentTimestamp(date, locale) {
  const formatter = new Intl.RelativeTimeFormat(locale, {
    style: "short",
    numeric: "auto"
  });

  const now = new Date();
  const diffInMs = date - now;
  const diffInMinutes = Math.round(diffInMs / (1000 * 60));

  return formatter.format(diffInMinutes, "minute");
}

const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000);

console.log(formatCommentTimestamp(fiveMinutesAgo, "en-US"));
// Output: "5 min. ago"

Краткий стиль — это баланс между понятностью и эффективностью. Большинство пользователей без проблем распознают стандартные сокращения.

Когда использовать узкий стиль

Узкий стиль лучше всего подходит для ситуаций с очень ограниченным пространством, где важен каждый символ, а пользователи хорошо знакомы с обозначениями времени.

Компактные виджеты, показывающие одну метрику, могут использовать узкий стиль, если размер отображения минимален. Например, таймер с надписью «5м назад» маленьким шрифтом выглядит лучше, чем «5 минут назад».

Визуализации данных с плотной информацией выигрывают от узкого стиля. Подписи к графикам, аннотации и временные метки требуют минимального текста, чтобы не закрывать важную визуальную информацию. Использование «2ч назад» вместо «2 ч. назад» экономит место и остаётся понятным для тех, кто знаком с контекстом.

Виджеты на главном экране мобильных устройств с ограниченным пространством используют узкий стиль для максимальной плотности информации. Например, виджет активности, показывающий несколько последних событий в маленькой плитке, выигрывает от компактного формата времени.

Интерфейсы смарт-часов используют узкий стиль, потому что экран очень маленький. Отображение «1ч назад» на маленьком круглом экране выглядит лучше, чем длинные форматы.

Списки с множеством элементов и временными метками могут использовать узкий стиль, чтобы каждая строка оставалась компактной. Музыкальные приложения с историей прослушиваний, видеоприложения с историей просмотров или фитнес-приложения с историей тренировок выигрывают от минимального формата времени.

function formatCompactTimestamp(date, locale) {
  const formatter = new Intl.RelativeTimeFormat(locale, {
    style: "narrow",
    numeric: "auto"
  });

  const now = new Date();
  const diffInMs = date - now;
  const diffInHours = Math.round(diffInMs / (1000 * 60 * 60));

  return formatter.format(diffInHours, "hour");
}

const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000);

console.log(formatCompactTimestamp(twoHoursAgo, "en-US"));
// Output: "2h ago"

Узкий стиль предполагает, что пользователи знакомы с обозначениями времени и могут понять единицы без пояснений. Такой вариант жертвует понятностью ради максимальной экономии места.

Совмещайте стиль с числовым вариантом

Опция style работает вместе с опцией numeric. Опция numeric определяет, будет ли использоваться естественный язык, например «вчера», или числовой формат, например «1 день назад». Опция style управляет краткостью числового формата, когда он используется.

const autoLong = new Intl.RelativeTimeFormat("en-US", {
  numeric: "auto",
  style: "long"
});

console.log(autoLong.format(-1, "day"));
// Output: "yesterday"

console.log(autoLong.format(-2, "day"));
// Output: "2 days ago"

const autoShort = new Intl.RelativeTimeFormat("en-US", {
  numeric: "auto",
  style: "short"
});

console.log(autoShort.format(-1, "day"));
// Output: "yesterday"

console.log(autoShort.format(-2, "day"));
// Output: "2 days ago"

Когда numeric — это "auto", а форматтер использует естественный язык, например «вчера», опция style не влияет на результат, потому что нет числового вывода, который можно стилизовать. Форматтер выдаёт одинаковый результат независимо от стиля.

Когда форматтер выдаёт числовой результат, опция style управляет степенью подробности.

const alwaysLong = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "long"
});

console.log(alwaysLong.format(-1, "day"));
// Output: "1 day ago"

const alwaysShort = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "short"
});

console.log(alwaysShort.format(-1, "day"));
// Output: "1 day ago"

const alwaysNarrow = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "narrow"
});

console.log(alwaysNarrow.format(-1, "day"));
// Output: "1 day ago"

Для дней все три стиля дают похожий результат на английском. Различия между стилями становятся заметнее для других единиц времени.

const alwaysLong = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "long"
});

const alwaysShort = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "short"
});

const alwaysNarrow = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "narrow"
});

console.log("Long:   " + alwaysLong.format(-2, "hour"));
console.log("Short:  " + alwaysShort.format(-2, "hour"));
console.log("Narrow: " + alwaysNarrow.format(-2, "hour"));

// Output:
// Long:   2 hours ago
// Short:  2 hr. ago
// Narrow: 2h ago

Эта комбинация даёт полный контроль как над тем, будет ли использоваться естественный язык, так и над тем, как отображается числовой результат.

Что важно запомнить

Опция style определяет, как будут отображаться относительные значения времени при форматировании с помощью Intl.RelativeTimeFormat. Установите её в "long" для полного написания, например «2 часа назад», в "short" для стандартных сокращений, например «2 ч назад», или в "narrow" для компактных форм, например «2ч назад». По умолчанию используется "long", если не указано иное.

Используйте длинный стиль, когда важны ясность и доступность, или если пользователи могут не знать сокращения времени. Короткий стиль подходит для обычных приложений, где важна экономия места и пользователи понимают стандартные сокращения. Узкий стиль используйте только в очень ограниченных по пространству случаях, когда пользователи хорошо знакомы с обозначениями времени.

Форматтер автоматически учитывает особенности локали, включая разные слова, сокращения, порядок слов и правила пробелов. Комбинируйте style с опцией numeric, чтобы управлять и появлением естественного языка, и отображением числового результата.