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


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