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
|
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
|
#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.
|
Attempts to parse a human readable time string into a time based value.
|
||||||
|
|
||||||
##Overview
|
##Overview
|
||||||
@ -158,14 +162,21 @@ console.log(daysThisWeek); // will log 5
|
|||||||
|
|
||||||
###Browser
|
###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
|
```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
|
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",
|
"name": "timestring",
|
||||||
"description" : "Parse a human readable time string into a time based value",
|
"description": "Parse a human readable time string into a time based value",
|
||||||
"homepage" : "https://github.com/mike182uk/timestring",
|
"homepage": "https://github.com/mike182uk/timestring",
|
||||||
"keywords" : [
|
"author": "Michael David Barrett <mike182uk@gmail.com>",
|
||||||
"util",
|
"repository": {
|
||||||
"functional",
|
"type": "git",
|
||||||
"time"
|
"url": "git://github.com/mike182uk/timestring.git"
|
||||||
],
|
},
|
||||||
"author" : "Michael David Barrett <mike182uk@gmail.com>",
|
"main": "timestring.js",
|
||||||
"repository" : {
|
"version": "1.1.0",
|
||||||
"type": "git",
|
"devDependencies": {
|
||||||
"url": "git://github.com/mike182uk/timestring.git"
|
"chai": "^1.9.1",
|
||||||
},
|
"grunt": "^0.4.5",
|
||||||
"main" : "timestring.js",
|
"grunt-contrib-jshint": "^0.10.0",
|
||||||
"version" : "1.0.2"
|
"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(){
|
(function(){
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var Timestring = function(settings) {
|
var Timestring = function(settings) {
|
||||||
// default settings
|
// default settings
|
||||||
var defaults = {
|
var defaults = {
|
||||||
hoursPerDay: 24,
|
hoursPerDay: 24,
|
||||||
daysPerWeek: 7,
|
daysPerWeek: 7,
|
||||||
weeksPerMonth: 4,
|
weeksPerMonth: 4,
|
||||||
monthsPerYear: 12
|
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Timestring.prototype.parse = function(string, returnUnit) {
|
// merge default settings with user settings
|
||||||
// reference to this
|
settings = settings || {};
|
||||||
var self = this;
|
this.settings = defaults;
|
||||||
|
for (var s in settings) { this.settings[s] = settings[s]; }
|
||||||
|
|
||||||
// get unit key helper
|
// time units
|
||||||
function getUnitKey(unit) {
|
this.units = {
|
||||||
for (var key in self.units) {
|
s: ['s', 'sec', 'secs', 'second', 'seconds'],
|
||||||
for (var u in self.units[key]) {
|
m: ['m', 'min', 'mins', 'minute', 'minutes'],
|
||||||
if (unit === self.units[key][u]) {
|
h: ['h', 'hr', 'hrs', 'hour', 'hours'],
|
||||||
return key;
|
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
|
// time unit seconds mappings
|
||||||
throw 'The unit [' + unit + '] is not supported by timestring';
|
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
|
// throw error if invalid unit was passed
|
||||||
function convert(value, unit) {
|
throw new Error('The unit [' + unit + '] is not supported by timestring');
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add convenience method to string prototype
|
// convert a value to a specific unit
|
||||||
String.prototype.parseTime = function (unit, settings) {
|
function convert(value, unit) {
|
||||||
return (new Timestring(settings)).parse(this, unit);
|
var baseValue = that.unitValues[getUnitKey(unit)];
|
||||||
|
|
||||||
|
return value / baseValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// export Timestring object for either the browser or node
|
// get a value in seconds based on a specific unit
|
||||||
if (typeof module !== 'undefined' && module.exports) {
|
function getSeconds(value, unit) {
|
||||||
module.exports = Timestring;
|
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);
|
}).call(this);
|
||||||
|
Loading…
Reference in New Issue
Block a user