Created
January 29, 2023 11:43
-
-
Save akwodkiewicz/1d940b5c7dba4dbbd970cb855126ab9a to your computer and use it in GitHub Desktop.
Distance from given date in "X days/weeks/months ago" format using Intl
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
/** | |
* Tells you how long ago was `inputDate` in "x days/weeks/months ago" format using `Intl` | |
* ({@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl docs}). | |
* Automatically changes the resolution from days, to weeks, to months, to keeps things readable. | |
* Returns the exact date if the `inputDate` happened very long time ago. | |
* | |
* Dates only, time is ignored. | |
* | |
* You can use `forcedLocale` to get the string in a specific locale, otherwise a browser locale | |
* is used. | |
* | |
* @param {Date} inputDate | |
* @param {string|undefined} forcedLocale | |
*/ | |
function someTimeAgo(inputDate, forcedLocale) { | |
// numeric: "auto" uses phrases like "yesterday" instead of "1 day ago" | |
const rtf = new Intl.RelativeTimeFormat(forcedLocale, { numeric: "auto" }); | |
// this is only to return exact date as a fallback | |
const dtf = new Intl.DateTimeFormat(forcedLocale); | |
// thresholds are my own preference, you can define your own | |
const MILLISECONDS_IN_A_DAY = 1000 * 60 * 60 * 24; | |
const DAYS_THRESHOLD = 14; | |
const MILLISECONDS_IN_A_WEEK = 7 * MILLISECONDS_IN_A_DAY; | |
const WEEKS_THRESHOLD = 4; | |
const MILLISECONDS_IN_A_MONTH = 30 * MILLISECONDS_IN_A_DAY; | |
const MONTHS_THRESHOLD = 12; | |
const millisecondsAgo = new Date().getTime() - inputDate.getTime(); | |
// pseudo-pattern matching FTW | |
switch (true) { | |
case millisecondsAgo < DAYS_THRESHOLD * MILLISECONDS_IN_A_DAY: | |
return rtf.format( | |
-Math.round(millisecondsAgo / MILLISECONDS_IN_A_DAY), | |
"day" | |
); | |
case millisecondsAgo < WEEKS_THRESHOLD * MILLISECONDS_IN_A_WEEK: | |
return rtf.format( | |
-Math.round(millisecondsAgo / MILLISECONDS_IN_A_WEEK), | |
"week" | |
); | |
case millisecondsAgo < MONTHS_THRESHOLD * MILLISECONDS_IN_A_MONTH: | |
return rtf.format( | |
-Math.round(millisecondsAgo / MILLISECONDS_IN_A_MONTH), | |
"month" | |
); | |
default: | |
return dtf.format(inputDate); | |
} | |
} | |
console.log(someTimeAgo(new Date("2022-10-31"))); | |
console.log(someTimeAgo(new Date("2022-11-11"), "pl-PL")); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment