Created
February 6, 2018 15:23
-
-
Save imranismail/0a30d0bdadb688d75ef46e6196ac3b61 to your computer and use it in GitHub Desktop.
formatDistance for luxon extracted from date-fns
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In case anyone else stumbles upon this, luxon now has https://moment.github.io/luxon/api-docs/index.html#datetimetorelative