var _ = require('lodash') /** * Exports */ module.exports = parseTimestring /** * Default options to use when parsing a timestring * * @type {Object} */ var defaultOpts = { hoursPerDay: 24, daysPerWeek: 7, weeksPerMonth: 4, monthsPerYear: 12 } /** * Map of accepted strings to unit * * @type {Object} */ var unitMap = { 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] * @return {number} */ function parseTimestring (string, returnUnit, opts) { opts = _.extend(_.clone(defaultOpts), opts || {}) var totalSeconds = 0 var unitValues = getUnitValues(opts) var groups = string .toLowerCase() .replace(/[^.\w+-]+/g, '') .match(/[-+]?[0-9]+[a-z]+/g) if (groups !== null) { _.each(groups, function (group) { var value = group.match(/[0-9]+/g)[0] var 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) { var 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.weeksPerMonth * unitValues.w unitValues.y = opts.monthsPerYear * unitValues.mth return unitValues } /** * Get the key for a unit * * @param {string} unit * @returns {string} */ function getUnitKey (unit) { for (var k in unitMap) { for (var u in unitMap[k]) { if (unit === unitMap[k][u]) { return k } } } 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) { var baseValue = unitValues[getUnitKey(unit)] return value * baseValue } /** * 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) { var baseValue = unitValues[getUnitKey(unit)] return value / baseValue }