Marble UI
← Components

Relative Time

Preview: Feed

"3 minutes ago" that stays current (refresh interval adapts to the distance). Full timestamp in title and dateTime.

Import

import { RelativeTime, ZoneClock } from '@marbleui/ui'

Props

<RelativeTime>

PropTypeDefaultDescription
date *requiredDate—
classNamestring—
styleRelativeTimeFormatStyle'long'

<ZoneClock>

Live clock for a time zone: label, then the time and the zone's UTC offset ("Amsterdam 14:02 GMT+1"), both in the React Aria locale.

PropTypeDefaultDescription
label *requiredstring—
timeZone *requiredstring—

Usage notes

RelativeTime shows a Date relative to now, such as “3 minutes ago”, “yesterday” or “in 2 hours”, and keeps it current. ZoneClock from the same module is a labelled live clock for an IANA time zone.

<RelativeTime date={new Date(issue.updatedAt)} className="text-fg-muted" />
<RelativeTime date={deployedAt} style="short" />
<ZoneClock label="Amsterdam" timeZone="Europe/Amsterdam" />
  • It renders a <time> with an ISO dateTime and the full timestamp in title. The title appears only on hover, so show the exact time elsewhere when it matters.
  • style is long (default), short or narrow; the locale comes from LocaleProvider. formatRelative(date, locale) returns the same text for strings such as an aria-label.
  • It re-renders every second, 30 seconds or 5 minutes, depending on the date’s current age, slowing down as the date gets older. The text depends on the clock at render time, so in server-rendered pages wrap it in ClientOnly to avoid a hydration mismatch.
  • ZoneClock shows the time and UTC offset (“14:02 GMT+1”), both in the React Aria locale, and refreshes every 15 seconds.
Example source · show
import { useState } from 'react'
import { RelativeTime, ZoneClock } from './relative-time'

function Feed() {
  const [base] = useState(() => Date.now())
  const items = [['Ada opened ACME-142', 8e3], ['Deploy finished', 4.2e5], ['Charles commented', 3.8e6], ['Invoice paid', 8.64e7 * 1.2], ['Workspace created', 8.64e7 * 40]] as const
  return <ul className="w-80 divide-y divide-border rounded-xl border border-border bg-surface">{items.map(([t, ago]) => <li key={t} className="flex justify-between px-4 py-2.5 text-sm"><span className="text-fg">{t}</span><RelativeTime date={new Date(base - ago)} className="text-fg-muted" /></li>)}</ul>
}
export const styles = {
  Feed,
  'Short style': () => <p className="text-sm text-fg-muted">Updated <RelativeTime date={new Date(Date.now() - 3.6e6 * 5)} style="short" /></p>,
  'World clocks': () => <div className="flex w-72 flex-col gap-2 rounded-xl border border-border bg-surface p-4">{[['San Francisco', 'America/Los_Angeles'], ['New York', 'America/New_York'], ['Amsterdam', 'Europe/Amsterdam'], ['Singapore', 'Asia/Singapore']].map(([l, z]) => <ZoneClock key={z} label={l!} timeZone={z!} />)}</div>,
}

Source: packages/ui/src/relative-time/relative-time.tsx

Catalog

Category
date-time
Priority
Extra
Primitive
custom
React Aria
useDateFormatter