Merge branch 'dev-1.1'
This commit is contained in:
commit
0ff75942b9
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
test
|
||||
node_modules
|
||||
|
@ -1 +1,5 @@
|
||||
test
|
||||
.editorconfig
|
||||
.jshintrc
|
||||
Gruntfile.js
|
||||
.DS_Store
|
||||
|
7
.travis.yml
Normal file
7
.travis.yml
Normal file
@ -0,0 +1,7 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.11"
|
||||
before_script:
|
||||
- npm install -g grunt-cli
|
||||
script: grunt test
|
17
CHANGELOG.md
Normal file
17
CHANGELOG.md
Normal file
@ -0,0 +1,17 @@
|
||||
#Changelog
|
||||
|
||||
##1.1.0
|
||||
|
||||
- Added MIT license
|
||||
- Added Changelog
|
||||
- Added Grunt config
|
||||
- Added editorconfig
|
||||
- Added Tests
|
||||
- Fixed JSHint errors
|
||||
- Formatted code as per editorconfig
|
||||
- Fixed bug with conversion from year(s) to another unit
|
||||
- Make sure `Error` (type) is thrown when invalid unit is encountered
|
||||
- Added minified distributable version
|
||||
- Updated package.json
|
||||
- Added bower config
|
||||
- Added travis config
|
43
Gruntfile.js
Normal file
43
Gruntfile.js
Normal file
@ -0,0 +1,43 @@
|
||||
module.exports = function(grunt) {
|
||||
// measure the time each task takes
|
||||
require('time-grunt')(grunt);
|
||||
|
||||
// autoload Grunt tasks
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
// main project config
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
uglify: {
|
||||
dist: {
|
||||
files: {
|
||||
'dist/<%= pkg.name %>.min.js': '<%= pkg.name %>.js'
|
||||
}
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
options: {
|
||||
jshintrc: true
|
||||
},
|
||||
files: [
|
||||
'Gruntfile.js',
|
||||
'<%= pkg.name %>.js',
|
||||
'test/**/*.js'
|
||||
]
|
||||
},
|
||||
mochaTest: {
|
||||
test: {
|
||||
options: {
|
||||
reporter: 'spec'
|
||||
},
|
||||
src: ['test/**/*.js']
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// user defined tasks
|
||||
grunt.registerTask('test', ['mochaTest']);
|
||||
grunt.registerTask('lint', ['jshint']);
|
||||
grunt.registerTask('build', ['uglify']);
|
||||
grunt.registerTask('default', ['jshint', 'mochaTest', 'uglify']);
|
||||
};
|
19
LICENSE
Normal file
19
LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) Michael David Barrett
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
19
README.md
19
README.md
@ -1,5 +1,9 @@
|
||||
#Timestring
|
||||
|
||||
[![Build Status](https://travis-ci.org/mike182uk/timestring.svg?branch=master)](https://travis-ci.org/mike182uk/timestring)
|
||||
|
||||
[![NPM](https://nodei.co/npm/timestring.png?downloads=true&stars=true)](https://nodei.co/npm/timestring/)
|
||||
|
||||
Attempts to parse a human readable time string into a time based value.
|
||||
|
||||
##Overview
|
||||
@ -158,14 +162,21 @@ console.log(daysThisWeek); // will log 5
|
||||
|
||||
###Browser
|
||||
|
||||
All you need to do to get timestring working in the browser is download / clone this repo and make sure you include the `timestring.js` script on your page:
|
||||
All you need to do to get timestring working in the browser is download / clone this repo and make sure you include the `dist/timestring.min.js` script on your page:
|
||||
|
||||
```html
|
||||
<script src="<path-to-src>/timestring.js"></script>
|
||||
<script src="<path-to-src>/timestring.min.js"></script>
|
||||
```
|
||||
### Node
|
||||
|
||||
To install for a node project, navigate to the projects root folder and in your terminal type the following:
|
||||
Alternatively you can you use bower to manage this dependency for you:
|
||||
|
||||
```
|
||||
bower install timestring --save
|
||||
```
|
||||
|
||||
###Node
|
||||
|
||||
To install for a node application, navigate to the projects root folder and in your terminal type the following:
|
||||
|
||||
```
|
||||
npm install timestring
|
||||
|
16
bower.json
Normal file
16
bower.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "timestring",
|
||||
"main": "timestring.js",
|
||||
"version": "1.1.0",
|
||||
"description": "Parse a human readable time string into a time based value",
|
||||
"homepage": "https://github.com/mike182uk/timestring",
|
||||
"authors": [
|
||||
"Michael David Barrett <mike182uk@gmail.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"test"
|
||||
]
|
||||
}
|
1
dist/timestring.min.js
vendored
Normal file
1
dist/timestring.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(function(){"use strict";var a=function(a){var b={hoursPerDay:24,daysPerWeek:7,weeksPerMonth:4,monthsPerYear:12};a=a||{},this.settings=b;for(var c in a)this.settings[c]=a[c];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"]},this.unitValues={s:1,m:60,h:3600},this.unitValues.d=this.settings.hoursPerDay*this.unitValues.h,this.unitValues.w=this.settings.daysPerWeek*this.unitValues.d,this.unitValues.mth=this.settings.weeksPerMonth*this.unitValues.w,this.unitValues.y=this.settings.monthsPerYear*this.unitValues.mth};a.prototype.parse=function(a,b){function c(a){for(var b in f.units)for(var c in f.units[b])if(a===f.units[b][c])return b;throw new Error("The unit ["+a+"] is not supported by timestring")}function d(a,b){var d=f.unitValues[c(b)];return a/d}function e(a,b){var d=f.unitValues[c(b)];return a*d}var f=this,g=0,h=a.toLowerCase().replace(/[^\.\w+-]+/g,"").match(/[-+]?[0-9]+[a-z]+/g);if(null!==h)for(var i=0;i<h.length;i++){var j=h[i],k=j.match(/[0-9]+/g)[0],l=j.match(/[a-z]+/g)[0];g+=e(k,l)}return b?d(g,b):g},String.prototype.parseTime=function(b,c){return new a(c).parse(this,b)},"undefined"!=typeof module&&module.exports?module.exports=a:this.Timestring=a}).call(this);
|
35
package.json
35
package.json
@ -1,17 +1,22 @@
|
||||
{
|
||||
"name" : "timestring",
|
||||
"description" : "Parse a human readable time string into a time based value",
|
||||
"homepage" : "https://github.com/mike182uk/timestring",
|
||||
"keywords" : [
|
||||
"util",
|
||||
"functional",
|
||||
"time"
|
||||
],
|
||||
"author" : "Michael David Barrett <mike182uk@gmail.com>",
|
||||
"repository" : {
|
||||
"type": "git",
|
||||
"url": "git://github.com/mike182uk/timestring.git"
|
||||
},
|
||||
"main" : "timestring.js",
|
||||
"version" : "1.0.2"
|
||||
"name": "timestring",
|
||||
"description": "Parse a human readable time string into a time based value",
|
||||
"homepage": "https://github.com/mike182uk/timestring",
|
||||
"author": "Michael David Barrett <mike182uk@gmail.com>",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/mike182uk/timestring.git"
|
||||
},
|
||||
"main": "timestring.js",
|
||||
"version": "1.1.0",
|
||||
"devDependencies": {
|
||||
"chai": "^1.9.1",
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-contrib-jshint": "^0.10.0",
|
||||
"grunt-contrib-uglify": "^0.5.0",
|
||||
"grunt-mocha-test": "^0.11.0",
|
||||
"load-grunt-tasks": "^0.6.0",
|
||||
"mocha": "^1.20.1",
|
||||
"time-grunt": "^0.4.0"
|
||||
}
|
||||
}
|
||||
|
75
test/timestring.js
Normal file
75
test/timestring.js
Normal file
@ -0,0 +1,75 @@
|
||||
var chai = require('chai');
|
||||
var expect = chai.expect;
|
||||
var timestring = require('../timestring');
|
||||
|
||||
describe('timestring', function() {
|
||||
it('can parse a timestring', function(done) {
|
||||
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);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('can return a value in a specified unit', function(done) {
|
||||
expect((new timestring()).parse('5m', 's')).to.equal(300);
|
||||
expect((new timestring()).parse('5m', 'm')).to.equal(5);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('uses the passed settings instead of the defaults', function(done) {
|
||||
var settings = {
|
||||
hoursPerDay: 1,
|
||||
daysPerWeek: 2,
|
||||
weeksPerMonth: 3,
|
||||
monthsPerYear: 4
|
||||
};
|
||||
|
||||
var ts = new timestring(settings);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('throws an error when an invalid unit is used in the timestring', function(done) {
|
||||
var ts = new timestring();
|
||||
|
||||
expect(ts.parse.bind(ts, '1g')).to.throw(Error);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('can parse a messy time string', function(done) {
|
||||
expect((new timestring()).parse('5 D a YS 4 h 2 0 mI nS')).to.equal(447600);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should expose a method on String.prototype that will parse the string as a timestring', function(done){
|
||||
var str = '1min';
|
||||
|
||||
// no arguments passed
|
||||
expect(str.parseTime()).to.equal(60);
|
||||
|
||||
// units argument passed
|
||||
expect(str.parseTime('m')).to.equal(1);
|
||||
|
||||
// units + settings argument passed
|
||||
str = '5h';
|
||||
expect(str.parseTime('d', { hoursPerDay: 5 })).to.equal(1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
191
timestring.js
191
timestring.js
@ -1,111 +1,112 @@
|
||||
(function(){
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
var Timestring = function(settings) {
|
||||
// default settings
|
||||
var defaults = {
|
||||
hoursPerDay: 24,
|
||||
daysPerWeek: 7,
|
||||
weeksPerMonth: 4,
|
||||
monthsPerYear: 12
|
||||
};
|
||||
|
||||
// merge default settings with user settings
|
||||
var settings = settings || {};
|
||||
this.settings = {};
|
||||
for (var property in defaults) { this.settings[property] = defaults[property]; }
|
||||
for (var property in settings) { this.settings[property] = settings[property]; }
|
||||
|
||||
// time units
|
||||
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']
|
||||
};
|
||||
|
||||
// time unit seconds mappings
|
||||
this.unitValues = {
|
||||
s: 1,
|
||||
m: 60,
|
||||
h: 3600
|
||||
};
|
||||
|
||||
// dynamic time unit seconds mappings
|
||||
// these are dynamic based on the settings
|
||||
this.unitValues.d = this.settings.hoursPerDay * this.unitValues.h;
|
||||
this.unitValues.w = this.settings.daysPerWeek * this.unitValues.d;
|
||||
this.unitValues.mth = this.settings.weeksPerMonth * this.unitValues.w;
|
||||
this.unitValues.y = this.settings.monthsPerYear * this.unitValues.w;
|
||||
var Timestring = function(settings) {
|
||||
// default settings
|
||||
var defaults = {
|
||||
hoursPerDay: 24,
|
||||
daysPerWeek: 7,
|
||||
weeksPerMonth: 4,
|
||||
monthsPerYear: 12
|
||||
};
|
||||
|
||||
Timestring.prototype.parse = function(string, returnUnit) {
|
||||
// reference to this
|
||||
var self = this;
|
||||
// merge default settings with user settings
|
||||
settings = settings || {};
|
||||
this.settings = defaults;
|
||||
for (var s in settings) { this.settings[s] = settings[s]; }
|
||||
|
||||
// get unit key helper
|
||||
function getUnitKey(unit) {
|
||||
for (var key in self.units) {
|
||||
for (var u in self.units[key]) {
|
||||
if (unit === self.units[key][u]) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
// time units
|
||||
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']
|
||||
};
|
||||
|
||||
// throw exception if invalid unit is passed
|
||||
throw 'The unit [' + unit + '] is not supported by timestring';
|
||||
// time unit seconds mappings
|
||||
this.unitValues = {
|
||||
s: 1,
|
||||
m: 60,
|
||||
h: 3600
|
||||
};
|
||||
|
||||
// dynamic time unit seconds mappings
|
||||
// these are dynamic based on the settings
|
||||
this.unitValues.d = this.settings.hoursPerDay * this.unitValues.h;
|
||||
this.unitValues.w = this.settings.daysPerWeek * this.unitValues.d;
|
||||
this.unitValues.mth = this.settings.weeksPerMonth * this.unitValues.w;
|
||||
this.unitValues.y = this.settings.monthsPerYear * this.unitValues.mth;
|
||||
};
|
||||
|
||||
Timestring.prototype.parse = function(string, returnUnit) {
|
||||
// reference to this
|
||||
var that = this;
|
||||
|
||||
// get unit key helper
|
||||
function getUnitKey(unit) {
|
||||
for (var k in that.units) {
|
||||
for (var u in that.units[k]) {
|
||||
if (unit === that.units[k][u]) {
|
||||
return k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert a value to a specific unit
|
||||
function convert(value, unit) {
|
||||
var baseValue = self.unitValues[getUnitKey(unit)];
|
||||
return value / baseValue;
|
||||
}
|
||||
|
||||
// get a value in seconds based on a specific unit
|
||||
function getSeconds(value, unit) {
|
||||
var baseValue = self.unitValues[getUnitKey(unit)];
|
||||
return value * baseValue;
|
||||
}
|
||||
|
||||
// seconds counter
|
||||
var totalSeconds = 0;
|
||||
|
||||
// split string into groups and get total seconds for each group
|
||||
var groups = string
|
||||
.toLowerCase() // convert words to lower case
|
||||
.replace(/[^\.\w+-]+/g, '') // remove white space
|
||||
.match(/[-+]?[0-9]+[a-z]+/g); // match time groups (digit followed by time unit - i.e 5d 15m = 2 time groups)
|
||||
|
||||
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(value, unit);
|
||||
}
|
||||
}
|
||||
|
||||
// return total, convert if needed
|
||||
return (returnUnit) ? convert(totalSeconds, returnUnit) : totalSeconds;
|
||||
// throw error if invalid unit was passed
|
||||
throw new Error('The unit [' + unit + '] is not supported by timestring');
|
||||
}
|
||||
|
||||
// add convenience method to string prototype
|
||||
String.prototype.parseTime = function (unit, settings) {
|
||||
return (new Timestring(settings)).parse(this, unit);
|
||||
// convert a value to a specific unit
|
||||
function convert(value, unit) {
|
||||
var baseValue = that.unitValues[getUnitKey(unit)];
|
||||
|
||||
return value / baseValue;
|
||||
}
|
||||
|
||||
// export Timestring object for either the browser or node
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = Timestring;
|
||||
// get a value in seconds based on a specific unit
|
||||
function getSeconds(value, unit) {
|
||||
var baseValue = that.unitValues[getUnitKey(unit)];
|
||||
|
||||
return value * baseValue;
|
||||
}
|
||||
else {
|
||||
this.Timestring = Timestring;
|
||||
|
||||
// seconds counter
|
||||
var totalSeconds = 0;
|
||||
|
||||
// split string into groups and get total seconds for each group
|
||||
var groups = string
|
||||
.toLowerCase() // convert words to lower case
|
||||
.replace(/[^\.\w+-]+/g, '') // remove white space
|
||||
.match(/[-+]?[0-9]+[a-z]+/g); // match time groups (digit followed by time unit - i.e 5d 15m = 2 time groups)
|
||||
|
||||
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(value, unit);
|
||||
}
|
||||
}
|
||||
|
||||
// return total, convert if needed
|
||||
return (returnUnit) ? convert(totalSeconds, returnUnit) : totalSeconds;
|
||||
};
|
||||
|
||||
// add convenience method to string prototype
|
||||
String.prototype.parseTime = function (unit, settings) {
|
||||
return (new Timestring(settings)).parse(this, unit);
|
||||
};
|
||||
|
||||
// export Timestring object
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = Timestring;
|
||||
}
|
||||
else {
|
||||
this.Timestring = Timestring;
|
||||
}
|
||||
|
||||
}).call(this);
|
||||
|
Loading…
Reference in New Issue
Block a user