/** Takes a relative date and an optional date parameter, and returns a human-readable string representing the difference between the two dates. @function @param {number|Date} relativeDate - The relative date (can be a number representing an UTC timestamp, or a Date object). @param {Date} [date=new Date()] - An optional date parameter to compare the relative date to. Defaults to the current date and time. @returns {string} A human-readable string representing the difference between the two dates (e.g., "in 3 months", "5 hours ago", etc.). Returns "-" if the input date is invalid or not yet loaded. @example const timestamp = Date.now() / 1000 + 60 * 60 * 24 * 3; // UTC timestamp 3 days from now console.log(getRelativeTime(timestamp)); // Output: "in 3 days" */ export const getRelativeTime = (relativeDate, date = new Date()) => { // if relativeDate is a number, we assume it is an UTC timestamp if (typeof relativeDate === 'number') { // count charachters to check if in seconds or milliseconds if (relativeDate.toString().length < 13) { relativeDate = relativeDate * 1000; } // convert to date object relativeDate = new Date(relativeDate); } if (!(relativeDate instanceof Date)) { // invalid date, probably still loading return '-'; } let units = { year : 24 * 60 * 60 * 1000 * 365, month : 24 * 60 * 60 * 1000 * 365/12, day : 24 * 60 * 60 * 1000, hour : 60 * 60 * 1000, minute: 60 * 1000, second: 1000 } let rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' }) let elapsed = relativeDate - date // "Math.abs" accounts for both "past" & "future" scenarios for (let u in units) { if (Math.abs(elapsed) > units[u] || u === 'second') { return rtf.format(Math.round(elapsed/units[u]), u) } } }