Files
speckle-server/packages/frontend-2/utils/dateFormatter.ts
T
2024-09-13 13:45:44 +01:00

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)
}
}