How to display relative time in short or long form

Use the style option to control whether relative times appear as abbreviations, full words, or compact symbols

Introduction

When you display relative times like "2 hours ago" or "in 3 months", the format takes up different amounts of space. A timestamp showing content age can appear as "2 hours ago", "2 hr. ago", or "2h ago" depending on how much space you have and how clear you need to be. Each format trades readability against horizontal space.

Different contexts require different formatting choices. A social media feed showing post timestamps benefits from clear text like "2 hours ago". A mobile dashboard displaying multiple activity indicators needs compact text like "2h ago". A data visualization showing timeline events uses the most condensed form possible to fit information on screen.

JavaScript's Intl.RelativeTimeFormat provides the style option to control this choice. You can select between long display with spelled-out words, short display with standard abbreviations, or narrow display with the most compact representation possible. This option gives you precise control over how relative times appear to users.

What the style option controls

The style option in Intl.RelativeTimeFormat accepts three values: "long", "short", and "narrow". Each value produces a different level of verbosity for the relative time output.

The long value spells out complete words like "2 hours ago". The short value uses standard abbreviations like "2 hr. ago". The narrow value produces the most compact representation like "2h ago", often removing spaces and using minimal symbols.

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"

The style option defaults to "long" if you omit it. This means relative time formatting uses complete words unless you explicitly request a different display style.

Format relative time with long style

Long style spells out complete words. This format provides maximum clarity at the cost of additional horizontal space.

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"

The formatter automatically handles singular and plural forms. One hour uses the singular "hour" while multiple hours use the plural "hours". You do not need to manually determine which form to use.

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"

Each time unit gets spelled out completely regardless of which unit you use.

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"

Long style makes relative times immediately clear without requiring users to interpret abbreviations. Users unfamiliar with time abbreviations find spelled-out words more accessible.

Format relative time with short style

Short style uses standard abbreviations that most people recognize. This format balances readability with space efficiency.

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"

The formatter uses commonly recognized abbreviations. Hours become "hr.", minutes become "min.", and seconds become "sec.". These abbreviations maintain readability while reducing character count.

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."

Each time unit uses its standard abbreviation. Seconds use "sec.", minutes use "min.", months use "mo.", and years use "yr.". These abbreviations are widely recognized and work well in most contexts.

You can format both past and future times with short style.

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"

The formatter handles both directions consistently. Past times use "ago" while future times use "in". The abbreviations remain the same regardless of direction.

Format relative time with narrow style

Narrow style produces the most compact representation possible. This format removes spaces and uses minimal symbols to save every character.

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"

The formatter uses single-letter abbreviations and minimal spacing for most units. Hours become "h", minutes become "m", and seconds become "s". The output is more compact than short or long style.

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"

Narrow style varies by locale and unit. Some units produce significantly shorter output while others remain similar to short style. English keeps "days" spelled out but abbreviates hours, minutes, and seconds to single letters.

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"

Narrow style works best when space is extremely limited and users are familiar with the time measurement context. The condensed format assumes users can interpret the units without explicit separation or explanation.

Compare long, short, and narrow styles

The differences between the three style options become clear when you format the same relative times with each option.

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

Long style uses complete words and explicit spacing. Short style uses standard abbreviations with periods. Narrow style uses single letters with minimal spacing. This progression shows the tradeoff between clarity and space efficiency.

You can compare different relative time values to see how each style handles various time spans.

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

The character count difference becomes significant across multiple timestamps. In a feed or list showing many relative times, narrow style saves substantial horizontal space compared to long style.

How relative time styles vary across languages

All three style options adapt to the locale you specify. Different languages use different abbreviations, words, and spacing conventions.

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 時間前

Long style varies significantly across locales because each language has its own words for time units and different word order. German uses "vor" before the time amount, French uses "il y a" before the amount, and Japanese places the time indicator after the number. The formatter handles word order automatically.

Short style also adapts to locale conventions. German uses "Std." for hours, French uses "h", and Japanese uses the same format as long style. These locale-specific abbreviations reflect how each culture writes relative times in abbreviated form.

The formatter handles grammatical variations automatically. Each locale produces natural-looking output for its language.

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

Narrow style shows variation across locales. English uses "mo" for months, Spanish uses "m", and Portuguese spells out "meses". These differences reflect locale-specific conventions for compact time notation.

When to use long style

Long style works best when clarity and accessibility matter more than space efficiency. This choice makes relative times immediately understandable without requiring interpretation.

Accessibility-focused interfaces benefit from long style because screen readers pronounce spelled-out words more naturally. A screen reader announcing "2 hours ago" sounds more natural than "2 hr. ago", which might be read awkwardly or require special pronunciation rules.

Educational content benefits from long style because learners may not be familiar with time abbreviations. Teaching materials explaining timestamps should spell out units to avoid confusion.

Activity feeds and timelines use long style to maintain a clear, conversational tone. A social media post showing "3 hours ago" reads more naturally than "3h ago" in flowing text.

Formal reports and documentation use long style to maintain consistent writing standards. Business reports, audit logs, and official documents typically spell out relative times rather than abbreviating them.

International audiences benefit from long style when users may be learning the language. Spelled-out unit names like "hours" and "days" are easier to understand than abbreviations for non-native speakers.

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"

Long style prioritizes understanding over brevity. Use it whenever users need to grasp the relative time without any ambiguity or interpretation effort.

When to use short style

Short style works best in contexts where space matters but abbreviations are widely understood. This format balances clarity with efficiency.

Mobile interfaces benefit from short style because screen width is limited. Dashboard cards showing multiple timestamps need compact relative times to fit information on screen. Using "2 hr. ago" instead of "2 hours ago" saves characters per timestamp, adding up across multiple values.

Comment sections use short style to show when comments were posted without cluttering the interface. Displaying "5 min. ago" next to a comment is more compact than "5 minutes ago" while remaining clear.

Data tables displaying timestamps in columns need consistent width. Short abbreviations like "hr.", "min.", and "sec." keep column widths manageable. Long units like "hours", "minutes", and "seconds" widen columns unnecessarily.

Notification panels use short style because users checking notifications are familiar with time abbreviations. A notification showing "1 hr. ago" balances clarity with efficient use of display space.

Email clients use short style to show message age. Displaying "2 days ago" in a message list is clearer than "2d ago" but more compact than "2 days ago" spelled out completely.

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"

Short style strikes a balance between clarity and efficiency. Most users recognize standard abbreviations without confusion.

When to use narrow style

Narrow style works best in extremely space-constrained contexts where every character matters and users are highly familiar with time notation.

Compact widgets showing single metrics can use narrow style when the display size is minimal. A timer widget showing "5m ago" in small text fits better than "5 minutes ago".

Data visualizations with dense information benefit from narrow style. Chart labels, graph annotations, and timeline markers need minimal text to avoid obscuring underlying visual content. Using "2h ago" instead of "2 hr. ago" saves characters while remaining readable to users who understand the context.

Mobile home screen widgets with limited space use narrow style to maximize information density. An activity tracking widget showing multiple recent events in a small tile benefits from compact relative time notation.

Smartwatch interfaces use narrow style because screen space is extremely limited. Displaying "1h ago" on a small circular screen works better than longer formats.

List views showing many items with timestamps can use narrow style to keep each row compact. A music app showing recently played tracks, a video app showing watch history, or a fitness app showing workout history all benefit from minimal timestamp formatting.

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"

Narrow style assumes users are familiar with time notation and can interpret units without assistance. This option trades clarity for maximum space efficiency.

Combine style with numeric option

The style option works with the numeric option. The numeric option controls whether you get natural language like "yesterday" or numeric output like "1 day ago". The style option controls the verbosity of the numeric output when it appears.

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"

When numeric is "auto" and the formatter uses natural language like "yesterday", the style option has no effect because there is no numeric output to style. The formatter produces the same output regardless of style.

When the formatter produces numeric output, the style option controls the verbosity.

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"

For days, all three styles produce similar output in English. The style differences appear more clearly with other time units.

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

This combination gives you full control over both whether natural language appears and how numeric output displays.

What to remember

The style option controls how relative times appear when formatting with Intl.RelativeTimeFormat. Set it to "long" for spelled-out words like "2 hours ago", "short" for standard abbreviations like "2 hr. ago", or "narrow" for compact forms like "2h ago". The option defaults to "long" if omitted.

Use long style when clarity and accessibility matter more than space, or when users may be unfamiliar with time abbreviations. Use short style for general-purpose applications where space matters and users understand standard abbreviations. Use narrow style only in extremely space-constrained contexts where users are highly familiar with time notation.

The formatter handles locale-specific variations automatically, including different words, abbreviations, word order, and spacing conventions. Combine style with the numeric option to control both whether natural language appears and how numeric output displays.