Files
AstralRinth/src/utils/ago.ts

44 lines
1.5 KiB
TypeScript

/**
* Human readable elapsed or remaining time (example: 3 minutes)
* modified from https://stackoverflow.com/a/67338038/938822
*/
const rft = new Intl.RelativeTimeFormat(
typeof navigator !== 'undefined' ? [...navigator?.languages] : ['en'],
{ numeric: 'auto' }
)
export function ago(
/** A Date object, timestamp or string parsable with Date.parse() */
date: string | number | Date,
/** A Date object, timestamp or string parsable with Date.parse() */
nowDate: string | number | Date = Date.now()
): string {
const SECOND = 1000
const MINUTE = 60 * SECOND
const HOUR = 60 * MINUTE
const DAY = 24 * HOUR
const WEEK = 7 * DAY
const MONTH = 30 * DAY
const YEAR = 365 * DAY
const intervals = [
{ ge: YEAR, divisor: YEAR, unit: 'year' },
{ ge: MONTH, divisor: MONTH, unit: 'month' },
{ ge: WEEK, divisor: WEEK, unit: 'week' },
{ ge: DAY, divisor: DAY, unit: 'day' },
{ ge: HOUR, divisor: HOUR, unit: 'hour' },
{ ge: MINUTE, divisor: MINUTE, unit: 'minute' },
{ ge: 0, divisor: SECOND, unit: 'seconds' },
]
const now = typeof nowDate === 'object' ? nowDate.getTime() : new Date(nowDate).getTime()
const diff = now - (typeof date === 'object' ? date : new Date(date)).getTime()
const diffAbs = Math.abs(diff)
for (const interval of intervals) {
if (diffAbs >= interval.ge) {
const x = Math.round(Math.abs(diff) / interval.divisor)
const isFuture = diff < 0
return rft.format(isFuture ? x : -x, interval.unit as Intl.RelativeTimeFormatUnit)
}
}
}