Vize

use-relative-time-format

Pick the largest unit that expresses a millisecond difference as a non-zero rounded amount: seconds below a minute, minutes below an hour, hours below a day, days below a week, weeks below a month, months below a year, and years otherwise (Gregorian average month/year lengths).

Package @vizejs/composable/use-relative-time-format
Own the source vize lib pull composable:use-relative-time-format
Runtime exports selectRelativeTimeUnit, useRelativeTimeFormat
Gzip budget 3072 B

Minimal setup

Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).

vp install @vizejs/composable

Import the entry directly. Call lifecycle-bound utilities inside <script setup> so cleanup follows the component scope; consult the runtime contract for this entry's SSR and hydration behavior.

import { selectRelativeTimeUnit, useRelativeTimeFormat } from "@vizejs/composable/use-relative-time-format";

Try it

Say when a meetup happens

Describe a date relative to today in the reader's language, using words such as tomorrow instead of in 1 day.

Open the interactive example

What to observe: The meetup is in 3 days. Change the days to 1, 0 and -1 for tomorrow, today and yesterday. Choose German (Germany) for in 3 Tagen or Japanese (Japan) for 3 日後.

numeric: "auto" lets the formatter use words for nearby values. The value and unit can be refs; pass locale explicitly when rendering on the server. selectRelativeTimeUnit() picks a unit from a millisecond difference.

Compare the initial and interacted states
Say when a meetup happens: initial state
Initial state
Say when a meetup happens: state after the verified interactions
After the verified interactions

Copy the example

Save this complete SFC in your Vue project. Its public imports and source are the same ones executed in the preview.

<script setup lang="ts">
import { computed, ref } from "vue";
import { useRelativeTimeFormat } from "@vizejs/composable/use-relative-time-format";

const locale = ref("en-US");
const days = ref(3);
const options = computed(() => ({ locale: locale.value, numeric: "auto" as const }));
const { formatted } = useRelativeTimeFormat(days, "day", options);
</script>

<template>
  <div class="composable-example">
    <p>Say when an event happens in words the reader would use.</p>
    <label>
      Reader locale
      <select v-model="locale">
        <option value="en-US">English (United States)</option>
        <option value="de-DE">German (Germany)</option>
        <option value="ja-JP">Japanese (Japan)</option>
      </select>
    </label>
    <label>
      Days from today
      <input v-model.number="days" type="number" min="-30" max="30" step="1" />
    </label>
    <output aria-live="polite">The meetup is {{ formatted }}.</output>
  </div>
</template>

Runtime contract

Utility Category Stability SSR Hydration Cleanup Targets Host globals Uses
selectRelativeTimeUnit i18n experimental safe not-applicable none web, server, worker, native, desktop, terminal — —
useRelativeTimeFormat i18n experimental deterministic-fallback caller-managed none web, server, worker, native, desktop, terminal Date, Intl, window selectRelativeTimeUnit, useLocale

API

selectRelativeTimeUnit

Pick the largest unit that expresses a millisecond difference as a non-zero rounded amount: seconds below a minute, minutes below an hour, hours below a day, days below a week, weeks below a month, months below a year, and years otherwise (Gregorian average month/year lengths).

function selectRelativeTimeUnit(diffMs: number): RelativeTimeValue

useRelativeTimeFormat

Format relative times ("in 3 days", "yesterday") with Intl.RelativeTimeFormat. A pure formatting wrapper: it owns no clock or timer, so it never re-renders on its own and stays deterministic during server rendering (pair it with a clock composable for live "time ago" labels). The formatter follows the reactive options and is cached per locale and option set through useLocale; invalid options surface as the platform's RangeError.

function useRelativeTimeFormat( value: MaybeRefOrGetter<number | null | undefined>, unit: MaybeRefOrGetter<Intl.RelativeTimeFormatUnit>, options: MaybeRefOrGetter<UseRelativeTimeFormatOptions> = {}, ): RelativeTimeFormatControls
const { formatted } = useRelativeTimeFormat(-1, "day", { locale: "en", numeric: "auto" });
formatted.value; // "yesterday"

Types

RelativeTimeValue

A signed amount in one relative-time unit.

Member Type Description
value number Signed, rounded amount; negative values are in the past.
unit RelativeTimeUnitSelection Unit the amount is expressed in.

UseRelativeTimeFormatOptions

Options for useRelativeTimeFormat.

Member Type Description
locale? string | Intl.Locale Locale used for formatting. Pass it explicitly for hydration-stable server rendering.

RelativeTimeFromOptions

Options for RelativeTimeFormatControls.formatFrom.

Member Type Description
now? number Reference time in Unix milliseconds. Pass it explicitly to keep server and client output identical.

RelativeTimeFormatControls

Reactive relative-time formatting returned by useRelativeTimeFormat.

Member Type Description
locale ComputedRef<string> Canonical locale in use.
formatter ComputedRef<Intl.RelativeTimeFormat> Cached formatter for the current locale and options.
formatted ComputedRef<string> Formatted value in unit, or "" while either is missing.
format (value: number, unit: Intl.RelativeTimeFormatUnit) => string Format an amount in a unit.
formatToParts ( value: number, unit: Intl.RelativeTimeFormatUnit, ) => Intl.RelativeTimeFormatPart[] Format an amount in a unit into parts.
formatDiff (diffMs: number) => string Format a signed millisecond difference using the best-fitting unit (see selectRelativeTimeUnit).
formatFrom (date: Date | number, options?: RelativeTimeFromOptions) => string Format a date relative to a reference time using the best-fitting unit.