timestring/index.js

140 lines
2.7 KiB
JavaScript
Raw Normal View History

2016-01-15 12:00:03 +01:00
/**
* Exports
*/
2016-12-16 20:52:21 +01:00
module.exports = parseTimestring
2016-01-15 11:00:12 +01:00
2016-01-15 12:00:03 +01:00
/**
2016-01-15 21:05:30 +01:00
* Default options to use when parsing a timestring
2016-01-15 12:00:03 +01:00
*
2016-01-15 21:05:30 +01:00
* @type {Object}
2016-01-15 12:00:03 +01:00
*/
2017-04-22 15:07:52 +02:00
const DEFAULT_OPTS = {
2016-01-15 21:05:30 +01:00
hoursPerDay: 24,
daysPerWeek: 7,
weeksPerMonth: 4,
monthsPerYear: 12,
daysPerYear: 365.25
2016-12-16 20:52:21 +01:00
}
2016-01-15 11:00:12 +01:00
2016-01-15 21:05:30 +01:00
/**
* Map of accepted strings to unit
*
* @type {Object}
*/
2017-04-22 15:07:52 +02:00
const UNIT_MAP = {
2016-07-30 16:56:51 +02:00
ms: ['ms', 'milli', 'millisecond', 'milliseconds'],
2016-01-15 21:05:30 +01:00
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'],
2016-12-16 20:52:21 +01:00
mth: ['mon', 'mth', 'mths', 'month', 'months'],
y: ['y', 'yr', 'yrs', 'year', 'years']
}
2016-01-15 21:05:30 +01:00
/**
* Parse a timestring
*
2017-04-22 15:07:52 +02:00
* @param {String} string
* @param {String} returnUnit
* @param {Object} opts
* @return {Number}
2016-01-15 21:05:30 +01:00
*/
2016-12-16 20:52:21 +01:00
function parseTimestring (string, returnUnit, opts) {
2017-04-22 15:07:52 +02:00
opts = Object.assign({}, DEFAULT_OPTS, opts || {})
2016-01-15 21:05:30 +01:00
2017-04-22 15:07:52 +02:00
let totalSeconds = 0
let unitValues = getUnitValues(opts)
let groups = string
2016-01-15 21:05:30 +01:00
.toLowerCase()
2016-12-16 20:52:21 +01:00
.replace(/[^.\w+-]+/g, '')
2018-05-14 10:30:57 +02:00
.match(/[-+]?[0-9.]+[a-z]+/g)
2016-01-15 21:05:30 +01:00
if (groups === null) {
throw new Error(`The string [${string}] could not be parsed by timestring`)
2016-01-15 21:05:30 +01:00
}
groups.forEach(group => {
let value = group.match(/[0-9.]+/g)[0]
let unit = group.match(/[a-z]+/g)[0]
totalSeconds += getSeconds(value, unit, unitValues)
})
2016-01-15 21:05:30 +01:00
if (returnUnit) {
2016-12-16 20:52:21 +01:00
return convert(totalSeconds, returnUnit, unitValues)
2016-01-15 21:05:30 +01:00
}
2016-12-16 20:52:21 +01:00
return totalSeconds
2016-01-15 21:05:30 +01:00
}
2016-01-15 11:00:12 +01:00
2016-01-15 21:05:30 +01:00
/**
* Get unit values based on the passed options
*
2017-04-22 15:07:52 +02:00
* @param {Object} opts
2016-01-15 21:05:30 +01:00
* @returns {Object}
*/
2016-12-16 20:52:21 +01:00
function getUnitValues (opts) {
2017-04-22 15:07:52 +02:00
let unitValues = {
2016-07-30 16:56:51 +02:00
ms: 0.001,
2016-01-15 11:00:12 +01:00
s: 1,
m: 60,
2016-12-16 20:52:21 +01:00
h: 3600
}
2016-01-15 11:00:12 +01:00
2016-12-16 20:52:21 +01:00
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
2016-01-15 21:05:30 +01:00
2016-12-16 20:52:21 +01:00
return unitValues
2016-01-15 11:00:12 +01:00
}
2016-01-15 12:00:03 +01:00
/**
2016-01-15 21:05:30 +01:00
* Get the key for a unit
2016-01-15 12:00:03 +01:00
*
2017-04-22 15:07:52 +02:00
* @param {String} unit
* @returns {String}
2016-01-15 12:00:03 +01:00
*/
2016-01-15 11:00:12 +01:00
2016-12-16 20:52:21 +01:00
function getUnitKey (unit) {
2017-04-22 15:07:52 +02:00
for (let key of Object.keys(UNIT_MAP)) {
if (UNIT_MAP[key].indexOf(unit) > -1) {
return key
2016-01-15 11:00:12 +01:00
}
}
2017-04-22 15:07:52 +02:00
throw new Error(`The unit [${unit}] is not supported by timestring`)
2016-01-15 21:05:30 +01:00
}
2016-01-15 11:00:12 +01:00
2016-01-15 21:05:30 +01:00
/**
* Get the number of seconds for a value, based on the unit
*
2017-04-22 15:07:52 +02:00
* @param {Number} value
* @param {String} unit
* @param {Object} unitValues
* @returns {Number}
2016-01-15 21:05:30 +01:00
*/
2016-01-15 11:00:12 +01:00
2016-12-16 20:52:21 +01:00
function getSeconds (value, unit, unitValues) {
2017-04-22 15:07:52 +02:00
return value * unitValues[getUnitKey(unit)]
2016-01-15 21:05:30 +01:00
}
2016-01-15 11:00:12 +01:00
2016-01-15 21:05:30 +01:00
/**
* Convert a value from its existing unit to a new unit
*
2017-04-22 15:07:52 +02:00
* @param {Number} value
* @param {String} unit
* @param {Object} unitValues
* @returns {Number}
2016-01-15 21:05:30 +01:00
*/
2016-01-15 11:00:12 +01:00
2016-12-16 20:52:21 +01:00
function convert (value, unit, unitValues) {
2017-04-22 15:07:52 +02:00
return value / unitValues[getUnitKey(unit)]
2016-01-15 21:05:30 +01:00
}