Skip to content

Commit

Permalink
refactor internals
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Barrett committed Jan 15, 2016
1 parent 8099cf4 commit 32401a7
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 137 deletions.
11 changes: 8 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
#Changelog
# Changelog

## 3.0.0

- Remove `String.parseTime`
- Export function instead of object

## 2.0.0

- Keep it simple: revert back to ES5, remove gulp, browserify and build steps
- 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
Expand All @@ -19,7 +24,7 @@
- misc meta data updates
- add sourcemaps

##1.1.0
## 1.1.0

- add MIT license
- add Changelog
Expand Down
58 changes: 14 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ 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
```
Expand All @@ -34,7 +36,7 @@ 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
```
Expand All @@ -43,20 +45,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:
Expand All @@ -73,14 +66,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
Expand All @@ -93,15 +86,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
Expand All @@ -113,7 +100,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:

Expand All @@ -124,17 +111,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
```
Expand All @@ -151,19 +132,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
Expand Down
178 changes: 110 additions & 68 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,100 +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]; }

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'],
};
/**
* Map of accepted strings to unit
*
* @type {Object}
*/

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'],
};

/**
* 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;
}

this.unitValues = {
/**
* 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;
}
throw new Error('The unit [' + unit + '] is not supported by timestring');
}

function getSeconds(value, unit) {
var baseValue = this.unitValues[getUnitKey.call(this, unit)];
/**
* Get the number of seconds for a value, based on the unit
*
* @param {number} value
* @param {string} unit
* @param {Object} unitValues
* @returns {number}
*/

return value * baseValue;
}
function getSeconds(value, unit, unitValues) {
var baseValue = unitValues[getUnitKey(unit)];

var totalSeconds = 0;
var groups = string
.toLowerCase()
.replace(/[^\.\w+-]+/g, '')
.match(/[-+]?[0-9]+[a-z]+/g);
return value * baseValue;
}

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];
/**
* Convert a value from its existing unit to a new unit
*
* @param {number} value
* @param {string} unit
* @param {Object} unitValues
* @returns {number}
*/

totalSeconds += getSeconds.call(this, value, unit);
}
}
function convert(value, unit, unitValues) {
var baseValue = unitValues[getUnitKey(unit)];

return (returnUnit) ?
convert.call(this, totalSeconds, returnUnit) :
totalSeconds;
};
return value / baseValue;
}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"test": "mocha test.js"
},
"main": "index.js",
"version": "2.0.0",
"version": "3.0.0",
"devDependencies": {
"chai": "^3.4.1",
"codeclimate-test-reporter": "^0.1.0",
Expand All @@ -25,5 +25,8 @@
"mocha": "^2.2.4",
"mocha-lcov-reporter": "1.0.0",
"watch": "^0.17.1"
},
"dependencies": {
"lodash": "^4.0.0"
}
}
Loading

0 comments on commit 32401a7

Please sign in to comment.