78 lines
2.6 KiB
TypeScript
78 lines
2.6 KiB
TypeScript
import type { ConfigType } from 'dayjs'
|
|
import dayjs from 'dayjs'
|
|
|
|
/**
|
|
* Converts a given date input into a relative time string
|
|
* @example
|
|
* customRelativeTime('2023-07-16') - returns "Jul 16" or "Jul 16, 2023" if the year is different from the current year
|
|
* customRelativeTime(new Date()) - returns "just now"
|
|
*/
|
|
const customRelativeTime = (date: ConfigType, capitalize?: boolean): string => {
|
|
const pastDate = dayjs(date)
|
|
const now = dayjs()
|
|
const diffInMinutes = now.diff(date, 'minute')
|
|
const diffInHours = now.diff(date, 'hour')
|
|
const diffInDays = now.diff(date, 'day')
|
|
|
|
if (diffInDays > 14) {
|
|
return pastDate.year() === now.year()
|
|
? pastDate.format('MMM D')
|
|
: pastDate.format('MMM D, YYYY')
|
|
} else if (diffInDays >= 1) {
|
|
return diffInDays === 1 ? '1 day ago' : `${diffInDays} days ago`
|
|
} else if (diffInHours <= 23 && diffInHours >= 1) {
|
|
return diffInHours === 1 ? '1 hour ago' : `${diffInHours} hours ago`
|
|
} else if (diffInMinutes <= 59 && diffInMinutes >= 1) {
|
|
return diffInMinutes === 1 ? '1 minute ago' : `${diffInMinutes} minutes ago`
|
|
}
|
|
|
|
return capitalize ? 'Just now' : 'just now'
|
|
}
|
|
|
|
/**
|
|
* Determines if the given date input is using timeframe formatting
|
|
* @example
|
|
* isTimeframe('2023-07-16') - returns false
|
|
* isTimeframe(new Date()) - returns true or false depending on the current time
|
|
*/
|
|
const isTimeframe = (date: ConfigType) => {
|
|
const unit = customRelativeTime(date)
|
|
return (
|
|
unit.includes('second') ||
|
|
unit.includes('minute') ||
|
|
unit.includes('hour') ||
|
|
unit.includes('day') ||
|
|
unit.includes('just now')
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Formats a given date input into a full date string with our default format
|
|
* @example
|
|
* formattedFullDate('2023-12-01') - returns "Dec 12, 2023"
|
|
*/
|
|
export const formattedFullDate = (date: ConfigType): string =>
|
|
dayjs(date).format('MMM D, YYYY, H:mm')
|
|
|
|
/**
|
|
* Formats a given date input into a relative time string with optional prefix
|
|
* @example
|
|
* Assuming today is January 1st 2024
|
|
* formattedRelativeDate('2023-12-01') - returns "Dec 12, 2023"
|
|
* formattedRelativeDate('2023-12-01', { prefix: true }) - returns "on Dec 12, 2023"
|
|
* formattedRelativeDate('2023-12-31') - returns "1 day ago"
|
|
* formattedRelativeDate('2023-12-31', { prefix: true }) - returns "1 day ago"
|
|
*/
|
|
export const formattedRelativeDate = (
|
|
date: ConfigType,
|
|
options?: Partial<{ prefix: boolean; capitalize: boolean }>
|
|
): string => {
|
|
if (options?.prefix) {
|
|
return isTimeframe(date)
|
|
? customRelativeTime(date, options?.capitalize)
|
|
: `on ${customRelativeTime(date)}`
|
|
} else {
|
|
return customRelativeTime(date, options?.capitalize)
|
|
}
|
|
}
|