π File detail
utils/formatBriefTimestamp.ts
π― Use case
This file lives under βutils/β, which covers cross-cutting helpers (shell, tempfiles, settings, messages, process input, β¦). On the API surface it exposes formatBriefTimestamp β mainly functions, hooks, or classes. What the file header says: Format an ISO timestamp for the brief/chat message label line. Display scales with age (like a messaging app): - same day: "1:30 PM" or "13:30" (locale-dependent) - within 6 days: "Sunday, 4:15 PM" (locale-dependent) - older: "Sunday, Feb 20, 4:30 PM" (locale-dependent) Respects.
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
Format an ISO timestamp for the brief/chat message label line. Display scales with age (like a messaging app): - same day: "1:30 PM" or "13:30" (locale-dependent) - within 6 days: "Sunday, 4:15 PM" (locale-dependent) - older: "Sunday, Feb 20, 4:30 PM" (locale-dependent) Respects POSIX locale env vars (LC_ALL > LC_TIME > LANG) for time format (12h/24h), weekday names, month names, and overall structure. Bun/V8's `toLocaleString(undefined)` ignores these on macOS, so we convert them to BCP 47 tags ourselves. `now` is injectable for tests.
π€ Exports (heuristic)
formatBriefTimestamp
π₯οΈ Source preview
/**
* Format an ISO timestamp for the brief/chat message label line.
*
* Display scales with age (like a messaging app):
* - same day: "1:30 PM" or "13:30" (locale-dependent)
* - within 6 days: "Sunday, 4:15 PM" (locale-dependent)
* - older: "Sunday, Feb 20, 4:30 PM" (locale-dependent)
*
* Respects POSIX locale env vars (LC_ALL > LC_TIME > LANG) for time format
* (12h/24h), weekday names, month names, and overall structure.
* Bun/V8's `toLocaleString(undefined)` ignores these on macOS, so we
* convert them to BCP 47 tags ourselves.
*
* `now` is injectable for tests.
*/
export function formatBriefTimestamp(
isoString: string,
now: Date = new Date(),
): string {
const d = new Date(isoString)
if (Number.isNaN(d.getTime())) {
return ''
}
const locale = getLocale()
const dayDiff = startOfDay(now) - startOfDay(d)
const daysAgo = Math.round(dayDiff / 86_400_000)
if (daysAgo === 0) {
return d.toLocaleTimeString(locale, {
hour: 'numeric',
minute: '2-digit',
})
}
if (daysAgo > 0 && daysAgo < 7) {
return d.toLocaleString(locale, {
weekday: 'long',
hour: 'numeric',
minute: '2-digit',
})
}
return d.toLocaleString(locale, {
weekday: 'long',
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: '2-digit',
})
}
/**
* Derive a BCP 47 locale tag from POSIX env vars.
* LC_ALL > LC_TIME > LANG, falls back to undefined (system default).
* Converts POSIX format (en_GB.UTF-8) to BCP 47 (en-GB).
*/
function getLocale(): string | undefined {
const raw =
process.env.LC_ALL || process.env.LC_TIME || process.env.LANG || ''
if (!raw || raw === 'C' || raw === 'POSIX') {
return undefined
}
// Strip codeset (.UTF-8) and modifier (@euro), replace _ with -
const base = raw.split('.')[0]!.split('@')[0]!
if (!base) {
return undefined
}
const tag = base.replaceAll('_', '-')
// Validate by trying to construct an Intl locale β invalid tags throw
try {
new Intl.DateTimeFormat(tag)
return tag
} catch {
return undefined
}
}
function startOfDay(d: Date): number {
return new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime()
}