dellosmusic
Version:
Dellos Music Bot - Discord Music Bot
140 lines (115 loc) • 2.84 kB
JavaScript
/**
* Exports
*/
module.exports = parseTimestring;
/**
* Default options to use when parsing a timestring
*
* @type {Object}
*/
const DEFAULT_OPTS = {
hoursPerDay: 24,
daysPerWeek: 7,
weeksPerMonth: 4,
monthsPerYear: 12,
daysPerYear: 365.25,
};
/**
* Map of accepted strings to unit
*
* @type {Object}
*/
const UNIT_MAP = {
ms: ["ms", "milli", "millisecond", "milliseconds"],
s: ["s", "sec", "secs", "second", "seconds"],
m: ["m", "min", "mins", "minute", "minutes"],
h: ["h", "hr", "hrs", "hour", "hours"],
d: ["d", "day", "days"],
w: ["w", "week", "weeks"],
mth: ["mon", "mth", "mths", "month", "months"],
y: ["y", "yr", "yrs", "year", "years"],
};
/**
* Parse a timestring
*
* @param {string} string
* @param {string} returnUnit
* @param {Object} opts
* @returns {number}
*/
function parseTimestring(string, returnUnit, opts) {
opts = Object.assign({}, DEFAULT_OPTS, opts || {});
let totalSeconds = 0;
const unitValues = getUnitValues(opts);
const groups = string
.toLowerCase()
.replace(/[^.\w+-]+/g, "")
.match(/[-+]?[0-9.]+[a-z]+/g);
if (groups === null) {
throw new Error(`The string [${string}] could not be parsed by timestring`);
}
groups.forEach((group) => {
const value = group.match(/[0-9.]+/g)[0];
const unit = group.match(/[a-z]+/g)[0];
totalSeconds += getSeconds(value, unit, unitValues);
});
if (returnUnit) {
return convert(totalSeconds, returnUnit, unitValues);
}
return totalSeconds;
}
/**
* Get unit values based on the passed options
*
* @param {Object} opts
* @returns {Object}
*/
function getUnitValues(opts) {
const unitValues = {
ms: 0.001,
s: 1,
m: 60,
h: 3600,
};
unitValues.d = opts.hoursPerDay * unitValues.h;
unitValues.w = opts.daysPerWeek * unitValues.d;
unitValues.mth = (opts.daysPerYear / opts.monthsPerYear) * unitValues.d;
unitValues.y = opts.daysPerYear * unitValues.d;
return unitValues;
}
/**
* Get the key for a unit
*
* @param {string} unit
* @returns {string}
*/
function getUnitKey(unit) {
for (const key of Object.keys(UNIT_MAP)) {
if (UNIT_MAP[key].indexOf(unit) > -1) {
return key;
}
}
throw new Error(`The unit [${unit}] is not supported by timestring`);
}
/**
* Get the number of seconds for a value, based on the unit
*
* @param {number} value
* @param {string} unit
* @param {Object} unitValues
* @returns {number}
*/
function getSeconds(value, unit, unitValues) {
return value * unitValues[getUnitKey(unit)];
}
/**
* Convert a value from its existing unit to a new unit
*
* @param {number} value
* @param {string} unit
* @param {Object} unitValues
* @returns {number}
*/
function convert(value, unit, unitValues) {
return value / unitValues[getUnitKey(unit)];
}