Last active
October 21, 2020 08:29
-
-
Save martin-sweeny/ecdaba464b8a3e50793af1aa2aae2701 to your computer and use it in GitHub Desktop.
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
/** | |
* @typedef {TimeUnitTuple[]} TimeUnitTable A table of time units (seconds, minutes, for example), with their corresponding multipliers compared to the last value. The order is important, as each tuple contains a `multiplier`, which is how many times the last value would fit into this one (i.e. there are 60 minutes in an hour, so hour would be [60, 'hours']) | |
* @typedef {[multiplier: number, label: string]} TimeUnitTuple Intended to be used in an array of the same type, where the `multiplier` represents how many times this unit fits into the last, and `label` is the name of that unit (for example, days) | |
*/ | |
/** | |
* Returns the absolute difference between two date objects | |
* @curried | |
* @param {(number | Date)} date1 | |
* @returns {(date2?: number | Date) => number} The difference in milliseconds | |
* @example | |
* // returns 1008823000 | |
* getTimeDifference | |
* (new Date("October 12 2020 16:00:00")) | |
* (new Date("October 24 2020 08:13:43")); | |
* @example <caption>The function can take 1 date to get the difference between then and now</caption> | |
* // (Assuming that the current date is October 24 2020 08:13:43) | |
* // returns 1008823000 | |
* getTimeDifference(new Date("October 12 2020 16:00:00"))(); | |
*/ | |
const getTimeDifference = (date1) => (date2 = new Date().getTime()) => | |
Math.abs(date2 - date1); | |
/** | |
* Translates an amount of milliseconds into a human readable form | |
* @param {number} ms | |
* @returns {string} A human readable string, including (if necessary) days, hours, minutes, and seconds | |
* @example | |
* // returns '11 days 16 hours 13 minutes 43 seconds' | |
* const diff = toHumanReadable(1008823000); | |
*/ | |
const toHumanReadable = (ms) => { | |
/** | |
* @type TimeUnitTable | |
*/ | |
const unitMap = [ | |
[1000, "seconds"], | |
[60, "minutes"], | |
[60, "hours"], | |
[24, "days"], | |
]; | |
/** | |
* Loops through unitMap, multiplying the numbers to get the total amount of milliseconds to divide by | |
* @param {number} index The index to start at | |
*/ | |
const getDivisor = (index) => | |
unitMap.slice(index).reduce((prev, [curr]) => prev * curr, 1); | |
/** | |
* Loops through unitMap, using the tuples to divide the remaining ms and labeling the step with the appropriate unit | |
* @param {number} ms | |
* @returns {[string, number]} The text and remaining milliseconds | |
*/ | |
const getTimeRemaining = (ms) => | |
unitMap.reverse().reduce( | |
([text, time], [, unitText], i) => { | |
const divisor = getDivisor(i); | |
const dividend = time / divisor; | |
const remainder = time % divisor; | |
return dividend > 1 | |
? [`${text} ${Math.floor(dividend)} ${unitText}`, remainder] | |
: [text, time]; | |
}, | |
["", ms] | |
); | |
// Let's return only the text | |
return getTimeRemaining(ms)[0]; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment