Skip to content

Instantly share code, notes, and snippets.

@imranismail
Created February 6, 2018 15:23
Show Gist options
  • Save imranismail/0a30d0bdadb688d75ef46e6196ac3b61 to your computer and use it in GitHub Desktop.
Save imranismail/0a30d0bdadb688d75ef46e6196ac3b61 to your computer and use it in GitHub Desktop.
formatDistance for luxon extracted from date-fns
const FORMAT_DISTANCE_LOCALE = {
lessThanXSeconds: {
one: "'less than a second'",
other: "'less than 's' seconds'"
},
xSeconds: {
one: "s' second'",
other: "s' seconds'"
},
halfAMinute: 'half a minute',
lessThanXMinutes: {
one: "'less than a minute'",
other: "'less than 'm' minutes'"
},
xMinutes: {
one: "m' minute'",
other: "m' minutes'"
},
aboutXHours: {
one: "'about 'h' hour'",
other: "'about 'h' hours'"
},
xHours: {
one: "h' hour'",
other: "h' hours'"
},
xDays: {
one: "d' day'",
other: '{{count}} days'
},
aboutXMonths: {
one: "'about 'M' month'",
other: "'about 'M' months'"
},
xMonths: {
one: "M' month'",
other: "M' months'"
},
aboutXYears: {
one: "'about 'y' year'",
other: 'about {{count}} years'
},
xYears: {
one: "y' year'",
other: "y' years'"
},
overXYears: {
one: "'over 'y' year'",
other: "'over 'y' years'"
},
almostXYears: {
one: "'almost 'y' year'",
other: "'almost 'y' years'"
}
}
const format = (token, duration, options) => {
options = options || {}
let result
if (typeof formatDistanceLocale[token] === 'string') {
result = formatDistanceLocale[token]
} else if (count === 1) {
result = duration.toFormat(formatDistanceLocale[token].one)
} else {
result = duration.toFormat(formatDistanceLocale[token].other)
}
if (options.addSuffix) {
if (options.comparison > 0) {
return `in ${result}`
} else {
return `${result} ago`
}
}
return result
}
export default formatDistance = (duration, options = { includeSeconds: false, addSuffix: false }) => {
const seconds = Math.abs(duration.as('seconds'));
const minutes = Math.abs(duration.as('minutes'));
const days = Math.abs(duration.as('days'));
const months = Math.abs(duration.as('months'));
const years = Math.abs(duration.as('years'));
const localizeOptions = {...options, comparison: duration.as('milliseconds') > 0 ? 1 : 0};
// 0 up to 2 mins
if (minutes < 2) {
if (options.includeSeconds) {
if (seconds < 5) {
return format('lessThanXSeconds', Duration.fromObject({seconds: 5}), localizeOptions)
} else if (seconds < 10) {
return format('lessThanXSeconds', Duration.fromObject({seconds: 10}), localizeOptions)
} else if (seconds < 20) {
return format('lessThanXSeconds', Duration.fromObject({seconds: 20}), localizeOptions)
} else if (seconds < 40) {
return format('halfAMinute', null, localizeOptions)
} else if (seconds < 60) {
return format('lessThanXMinutes', Duration.fromObject({minutes: 1}), localizeOptions)
} else {
return format('xMinutes', Duration.fromObject({minutes: 1}), localizeOptions)
}
} else {
if (minutes === 0) {
return format('lessThanXMinutes', Duration.fromObject({minutes: 1}), localizeOptions)
} else {
return format('xMinutes', Duration.fromObject({minutes}), localizeOptions)
}
}
// 2 mins up to 0.75 hrs
} else if (minutes < 45) {
return format('xMinutes', Duration.fromObject({minutes}), localizeOptions)
// 0.75 hrs up to 1.5 hrs
} else if (minutes < 90) {
return format('aboutXHours', Duration.fromObject({hours: 1}), localizeOptions)
// 1.5 hrs up to 24 hrs
} else if (hours < 24) {
return format('aboutXHours', Duration.fromObject({hours}), localizeOptions)
// 1 day up to 1.75 days
} else if (days < 1.75) {
return format('xDays', Duration.fromObject({days: 1}), localizeOptions)
// 1.75 days up to 30 days
} else if (months < 1) {
return format('xDays', Duration.fromObject({days}), localizeOptions)
// 1 month up to 2 months
} else if (months < 2) {
return format('aboutXMonths', Duration.fromObject({months}), localizeOptions)
}
// 2 months up to 12 months
if (months < 12) {
return format('xMonths', Duration.fromObject({months}), localizeOptions)
// 1 year up to max Date
} else {
const monthsSinceStartOfYear = months % 12
// N years up to 1 years 3 months
if (monthsSinceStartOfYear < 3) {
return format('aboutXYears', Duration.fromObject({years}), localizeOptions)
// N years 3 months up to N years 9 months
} else if (monthsSinceStartOfYear < 9) {
return format('overXYears', Duration.fromObject({years}), localizeOptions)
// N years 9 months up to N year 12 months
} else {
return format('almostXYears', Duration.fromObject({years: years + 1}), localizeOptions)
}
}
}
@supermario
Copy link

supermario commented Oct 19, 2023

In case anyone else stumbles upon this, luxon now has https://moment.github.io/luxon/api-docs/index.html#datetimetorelative

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment