diff --git a/CHANGELOG.md b/CHANGELOG.md index d379b26..959755a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ -#Changelog +# Changelog + +## 3.0.0 + +- Remove `String.parseTime` +- Export function instead of object ## 2.0.0 @@ -6,7 +11,7 @@ - Remove bower / browser specific integrations - This module can still be used client side using modern development tools like webpack, browserify etc. - use `node-style-guide` coding style -##1.1.1 +## 1.1.1 - src now uses ES6 - use gulp instead of grunt @@ -19,7 +24,7 @@ - misc meta data updates - add sourcemaps -##1.1.0 +## 1.1.0 - add MIT license - add Changelog diff --git a/README.md b/README.md index 2152e97..790ebd2 100644 --- a/README.md +++ b/README.md @@ -20,21 +20,21 @@ npm install --save timestring ### Overview ```js +var timestring = require('timestring'); + var str = '1h 15m'; -var time = str.parseTime(); +var time = timestring(str); console.log(time); // will log 4500 ``` -In the example above `str` is just a plain old `String` object. A new method is added to the `String` objects prototype named `parseTime`. This method parses the string and returns a time based value. - -**By default the returned time value will be in seconds.** +**By default the returned time value from `timestring` will be in seconds.** The time string can contain as many time groups as needed: ```js var str = '1d 3h 25m 18s'; -var time = str.parseTime(); +var time = timestring(str); console.log(time); // will log 98718 ``` @@ -43,20 +43,11 @@ and can be as messy as you like: ```js var str = '1 d 3HOurS 25 min 1 8s'; -var time = str.parseTime(); +var time = timestring(str); console.log(time); // will log 98718 ``` -As well as using the `String` objects `parseTime` method you can create a `Timestring` object and parse the string manually: - -```js -var str = '1h 15m'; -var time = (new Timestring()).parse(str); - -console.log(time); // will log 4500 -``` - ### Keywords Timestring will parse the following keywords into time values: @@ -73,14 +64,14 @@ Keywords can be used interchangeably: ```js var str = '1day 15h 20minutes 15s'; -var time = str.parseTime(); +var time = timestring(str); console.log(time); // will log 141615 ``` ### Return Time Value -By default the return time value will be in seconds. This can be changed by passing one of the following strings as an argument to `String.parseTime` or `Timestring.parse`: +By default the return time value will be in seconds. This can be changed by passing one of the following strings as an argument to `timestring`: 1. `s` - Seconds 2. `m` - Minutes @@ -93,15 +84,9 @@ By default the return time value will be in seconds. This can be changed by pass ```js var str = '22h 16m'; -var hours = str.parseTime('h'); // 22.266666666666666 -var days = str.parseTime('d'); // 0.9277777777777778 -var weeks = str.parseTime('w'); // 0.13253968253968254 - -// or - -var hours = (new Timestring()).parse(str, 'h'); // 22.266666666666666 -var days = (new Timestring()).parse(str, 'd'); // 0.9277777777777778 -var weeks = (new Timestring()).parse(str, 'w'); // 0.13253968253968254 +var hours = timestring(str, 'h'); // 22.266666666666666 +var days = timestring(str, 'd'); // 0.9277777777777778 +var weeks = timestring(str, 'w'); // 0.13253968253968254 ``` ### Optional Configuration @@ -113,7 +98,7 @@ A few assumptions are made by default: 3. There are 4 weeks per month 4. There are 12 months per year -These options can be changed by passing a options object as an argument to `String.parseTime` or to the `Timestring` objects constructor. +These options can be changed by passing an options object as an argument to `timestring`. The following options are configurable: @@ -124,17 +109,11 @@ The following options are configurable: ```js var str = '1d'; - var opts = { hoursPerDay: 1 } -var time = str.parseTime('h', opts); - -// or - -var time = (new Timestring(opts)).parse(str, 'h'); - +var time = timestring(str, 'h', opts); console.log(time); // will log 1 ``` @@ -151,19 +130,8 @@ var opts = { daysPerWeek: 5 } -// get time values from form input -var today = document.querySelector('time-input').value, // '1d' - thisWeek = document.querySelector('time-input').value; // '1w' - -// parse times -var hoursToday = today.parseTime('h', opts), - daysThisWeek = thisWeek.parseTime('d', opts); - -// or - -var hoursToday = (new Timestring(opts)).parse(today, 'h'), - daysThisWeek = (new Timestring(opts)).parse(thisWeek, 'd'); - +var hoursToday = timestring('1d', 'h', opts); +var daysThisWeek = timestring('1w', 'd', opts); console.log(hoursToday); // will log 7.5 console.log(daysThisWeek); // will log 5 diff --git a/index.js b/index.js index 4ffc318..c29aad0 100644 --- a/index.js +++ b/index.js @@ -1,111 +1,142 @@ +var _ = require('lodash'); + /** * Exports */ -module.exports = Timestring; +module.exports = parseTimestring; /** - * Create a new Timestring instance + * Default options to use when parsing a timestring * - * @param {Object} opts - * @constructor + * @type {Object} */ -function Timestring(opts) { - var defaultOpts = { - hoursPerDay: 24, - daysPerWeek: 7, - weeksPerMonth: 4, - monthsPerYear: 12, - }; +var defaultOpts = { + hoursPerDay: 24, + daysPerWeek: 7, + weeksPerMonth: 4, + monthsPerYear: 12, +}; - opts = opts || {}; - this.opts = defaultOpts; - for (var s in opts) { this.opts[s] = opts[s]; } +/** + * Map of accepted strings to unit + * + * @type {Object} + */ - this.units = { - 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: ['mth', 'mths','month', 'months'], - y: ['y', 'yr', 'yrs', 'year', 'years'], - }; +var unitMap = { + 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: ['mth', 'mths','month', 'months'], + y: ['y', 'yr', 'yrs', 'year', 'years'], +}; - this.unitValues = { +/** + * 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 = { s: 1, m: 60, h: 3600, }; - this.unitValues.d = this.opts.hoursPerDay * this.unitValues.h; - this.unitValues.w = this.opts.daysPerWeek * this.unitValues.d; - this.unitValues.mth = this.opts.weeksPerMonth * this.unitValues.w; - this.unitValues.y = this.opts.monthsPerYear * this.unitValues.mth; + 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; } /** - * Parse a timestring + * Get the key for a unit * - * @param {string} string - * @param {string} returnUnit - * @return {string} + * @param {string} unit + * @returns {string} */ -Timestring.prototype.parse = function parse(string, returnUnit) { - function getUnitKey(unit) { - for (var k in this.units) { - for (var u in this.units[k]) { - if (unit === this.units[k][u]) { - return k; - } +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'); } - function convert(value, unit) { - var baseValue = this.unitValues[getUnitKey.call(this, unit)]; - - return value / baseValue; - } - - function getSeconds(value, unit) { - var baseValue = this.unitValues[getUnitKey.call(this, unit)]; - - return value * baseValue; - } - - var totalSeconds = 0; - var groups = string - .toLowerCase() - .replace(/[^\.\w+-]+/g, '') - .match(/[-+]?[0-9]+[a-z]+/g); - - if (groups !== null) { - for (var i = 0; i < groups.length; i++) { - var g = groups[i]; - var value = g.match(/[0-9]+/g)[0]; - var unit = g.match(/[a-z]+/g)[0]; - - totalSeconds += getSeconds.call(this, value, unit); - } - } - - return (returnUnit) ? - convert.call(this, totalSeconds, returnUnit) : - totalSeconds; -}; + throw new Error('The unit [' + unit + '] is not supported by timestring'); +} /** - * Parse a timestring + * Get the number of seconds for a value, based on the unit * - * @param {string} unit - * @param {Object} opts - * @return {string} + * @param {number} value + * @param {string} unit + * @param {Object} unitValues + * @returns {number} */ -String.prototype.parseTime = function parseTime(unit, opts) { - return (new Timestring(opts)).parse(this, unit); -}; + +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; +} diff --git a/package.json b/package.json index dd56d9e..411b3ed 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,12 @@ "url": "git://github.com/mike182uk/timestring.git" }, "scripts": { + "dev": "watch 'clear; npm test -s;' ./ -d", "sa": "jshint index.js && jscs index.js", "test": "mocha test.js" }, "main": "index.js", - "version": "2.0.0", + "version": "3.0.0", "devDependencies": { "chai": "^3.4.1", "codeclimate-test-reporter": "^0.2.0", @@ -22,6 +23,10 @@ "jscs": "^2.8.0", "jshint": "^2.9.1", "mocha": "^2.2.4", - "mocha-lcov-reporter": "1.0.0" + "mocha-lcov-reporter": "1.0.0", + "watch": "^0.17.1" + }, + "dependencies": { + "lodash": "^4.0.0" } } diff --git a/test.js b/test.js index 2e3f2fd..160971d 100644 --- a/test.js +++ b/test.js @@ -5,20 +5,18 @@ var timestring = require('./index'); describe('timestring', function() { it('can parse a timestring', function() { - var ts = new timestring(); - - expect(ts.parse('1s')).to.equal(1); - expect(ts.parse('1m')).to.equal(60); - expect(ts.parse('1h')).to.equal(3600); - expect(ts.parse('1d')).to.equal(86400); - expect(ts.parse('1w')).to.equal(604800); - expect(ts.parse('1mth')).to.equal(2419200); - expect(ts.parse('1y')).to.equal(29030400); + expect(timestring('1s')).to.equal(1); + expect(timestring('1m')).to.equal(60); + expect(timestring('1h')).to.equal(3600); + expect(timestring('1d')).to.equal(86400); + expect(timestring('1w')).to.equal(604800); + expect(timestring('1mth')).to.equal(2419200); + expect(timestring('1y')).to.equal(29030400); }); it('can return a value in a specified unit', function() { - expect((new timestring()).parse('5m', 's')).to.equal(300); - expect((new timestring()).parse('5m', 'm')).to.equal(5); + expect(timestring('5m', 's')).to.equal(300); + expect(timestring('5m', 'm')).to.equal(5); }); it('uses the passed options instead of the defaults', function() { @@ -29,35 +27,17 @@ describe('timestring', function() { monthsPerYear: 4 }; - var ts = new timestring(opts); - - expect(ts.parse('1d', 'h')).to.equal(1); - expect(ts.parse('1w', 'd')).to.equal(2); - expect(ts.parse('1mth', 'w')).to.equal(3); - expect(ts.parse('1y', 'mth')).to.equal(4); + expect(timestring('1d', 'h', opts)).to.equal(1); + expect(timestring('1w', 'd', opts)).to.equal(2); + expect(timestring('1mth', 'w', opts)).to.equal(3); + expect(timestring('1y', 'mth', opts)).to.equal(4); }); it('throws an error when an invalid unit is used in the timestring', function() { - var ts = new timestring(); - - expect(ts.parse.bind(ts, '1g')).to.throw(Error); + expect(function() { timestring('1g'); }).to.throw(Error); }); it('can parse a messy time string', function() { - expect((new timestring()).parse('5 D a YS 4 h 2 0 mI nS')).to.equal(447600); - }); - - it('should expose a method on String.prototype that will parse the string as a timestring', function(){ - var str = '1min'; - - // no arguments passed - expect(str.parseTime()).to.equal(60); - - // units argument passed - expect(str.parseTime('m')).to.equal(1); - - // units + options argument passed - str = '5h'; - expect(str.parseTime('d', { hoursPerDay: 5 })).to.equal(1); + expect(timestring('5 D a YS 4 h 2 0 mI nS')).to.equal(447600); }); });