fromNow()
Returns a human-readable relative-time string such as "3 hours ago" or "in 2 days", built on the native Intl.RelativeTimeFormat — no manual thresholds, fully localized.
Signature
function fromNow(
temporalObj: RelativeTemporalType,
reference?: Temporal.Instant,
locale?: string
): string
type RelativeTemporalType =
| Temporal.PlainDate
| Temporal.PlainDateTime
| Temporal.ZonedDateTime
| Temporal.Instant
Temporal.PlainTimeis not supported — without a date there is no way to tell whether a time is past or future.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
temporalObj | RelativeTemporalType | required | The target time to describe. |
reference | Temporal.Instant | Temporal.Now.* | The "now" to measure against. Pass an explicit value for deterministic output. |
locale | string | runtime default | BCP 47 tag controlling the language of the result. |
When reference is omitted, moment-less reads the current time internally, which makes output non-deterministic — always pass an explicit reference in tests.
Unit selection
The output unit is chosen from the absolute difference, then rendered with Intl.RelativeTimeFormat's numeric: 'auto' mode (which produces words like "yesterday" and "last week" where a locale defines them):
| Difference | Unit | Example output |
|---|---|---|
| < 60 seconds | seconds | "30 seconds ago", "now" |
| < 60 minutes | minutes | "3 minutes ago", "1 minute ago" |
| < 24 hours | hours | "3 hours ago", "1 hour ago" |
| < 7 days | days | "2 days ago", "yesterday", "tomorrow" |
| < 30 days | weeks | "3 weeks ago", "last week", "next week" |
| < 365 days | months | "3 months ago", "last month" |
| ≥ 365 days | years | "2 years ago", "last year" |
Months and years use approximate boundaries (30 and 365 days). Values are rounded, so an exact ±1 boundary renders via the auto words ("yesterday", "last week", …).
PlainDate is compared by calendar day. A
PlainDatehas no clock, so moment-less measures the whole-day difference against the reference date instead of folding it through a UTC-midnight instant. That keepsfromNow(today)reliably"today"andfromNow(tomorrow)reliably"tomorrow", independent of the time of day or time zone.
Examples
Past — by unit
import { fromNow } from 'moment-less'
const now = Temporal.Instant.from('2026-04-09T14:00:00Z')
fromNow(now.subtract({ seconds: 30 }), now) // → "30 seconds ago"
fromNow(now.subtract({ minutes: 1 }), now) // → "1 minute ago"
fromNow(now.subtract({ hours: 3 }), now) // → "3 hours ago"
fromNow(now.subtract({ hours: 24 }), now) // → "yesterday"
fromNow(now.subtract({ hours: 24 * 7 }), now) // → "last week"
fromNow(now.subtract({ hours: 24 * 30 }), now) // → "last month"
fromNow(now.subtract({ hours: 24 * 365 }), now) // → "last year"Future
import { fromNow } from 'moment-less'
const now = Temporal.Instant.from('2026-04-09T14:00:00Z')
fromNow(now.add({ minutes: 5 }), now) // → "in 5 minutes"
fromNow(now.add({ hours: 2 }), now) // → "in 2 hours"
fromNow(now.add({ hours: 24 }), now) // → "tomorrow"
fromNow(now.add({ hours: 24 * 7 }), now) // → "next week"PlainDate (calendar-day diffing)
import { fromNow } from 'moment-less'
const ref = Temporal.Instant.from('2026-04-09T12:00:00Z') // → UTC date 2026-04-09
fromNow(Temporal.PlainDate.from('2026-04-09'), ref) // → "today"
fromNow(Temporal.PlainDate.from('2026-04-10'), ref) // → "tomorrow"
fromNow(Temporal.PlainDate.from('2026-04-08'), ref) // → "yesterday"
fromNow(Temporal.PlainDate.from('2026-04-02'), ref) // → "last week"
fromNow(Temporal.PlainDate.from('2025-04-09'), ref) // → "last year"Deterministic reference (for tests)
import { fromNow } from 'moment-less'
const posted = Temporal.Instant.from('2026-04-09T08:00:00Z')
const viewed = Temporal.Instant.from('2026-04-09T12:30:00Z')
fromNow(posted, viewed) // → "4 hours ago" (stable regardless of when the test runs)Locale examples
Localization is zero-cost — Intl.RelativeTimeFormat ships with the platform, so there are no locale bundles to import.
import { fromNow } from 'moment-less'
const now = Temporal.Instant.from('2026-04-09T14:00:00Z')
const past = now.subtract({ hours: 3 })
fromNow(past, now) // → "3 hours ago"
fromNow(past, now, 'fr') // → "il y a 3 heures"
fromNow(past, now, 'es') // → "hace 3 horas"
fromNow(past, now, 'de') // → "vor 3 Stunden"
fromNow(past, now, 'ja') // → "3 時間前"
fromNow(past, now, 'ar') // → "قبل 3 ساعات"Supported Temporal types
| Type | Supported | Notes |
|---|---|---|
Temporal.PlainDate | ✅ | Compared by calendar day (no time-of-day). |
Temporal.PlainDateTime | ✅ | Treated as UTC wall-clock against the reference instant. |
Temporal.ZonedDateTime | ✅ | Converted to its absolute instant. |
Temporal.Instant | ✅ | Compared directly. |
Temporal.PlainTime | ❌ | Throws — no date context. |