-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Kevin Stumpf
committed
Oct 16, 2015
1 parent
593d6a0
commit a88d633
Showing
5 changed files
with
208 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,61 @@ | ||
# frequency-formatter | ||
Formats time interval to human readable string | ||
# Moment Duration Format Frequency | ||
|
||
**Format plugin for the Moment Duration object.** | ||
|
||
This is a plugin to the Moment.js JavaScript date library to add frequency formatting to Moment Durations. | ||
|
||
|
||
--- | ||
|
||
## Installation | ||
|
||
**Node.js** | ||
|
||
`npm install moment-duration-format-frequency` | ||
|
||
|
||
## Usage | ||
|
||
### Module | ||
|
||
To use this plugin as a module, use the `require` function: | ||
``` | ||
require("moment-duration-format-frequency"); | ||
``` | ||
|
||
The plugin does not export anything, so there is no need to assign the require output to a variable. | ||
|
||
The plugin depends on moment.js. | ||
|
||
|
||
### Basics | ||
|
||
The duration format method can format moment durations as human readable frequencies: | ||
|
||
``` | ||
moment.duration(1.5, 'weeks').formatAsFrequency('weeks'); | ||
// "every 1-2 weeks" | ||
moment.duration(0.23, 'weeks').formatAsFrequency('weeks'); | ||
// "4-5 times per week" | ||
moment.duration(3, 'weeks').formatAsFrequency('weeks'); | ||
// "every 3 weeks" | ||
moment.duration(0.25, 'weeks').formatAsFrequency('weeks'); | ||
// "4 times per week" | ||
moment.duration(3, 'years').formatAsFrequency('years'); | ||
// "every 3 years" | ||
``` | ||
|
||
### Customization | ||
|
||
Individual strings can be customized: | ||
|
||
``` | ||
moment.duration.fn.formatAsFrequency.defaults.everyString = 'alle'; | ||
moment.duration(3, 'years').formatAsFrequency('years'); | ||
// "alle 3 years" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('./lib/frequencyFormatter'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* jshint node: true */ | ||
|
||
'use strict'; | ||
|
||
var moment = require('moment'); | ||
var util = require('util'); | ||
var _ = require('lodash'); | ||
var isNaturalNumber = require('is-natural-number'); | ||
|
||
(function(moment) { | ||
var roundNumber = function(number) { | ||
return parseFloat(number.toFixed(2)); | ||
}; | ||
|
||
var isApproximatelyNaturalNumber = function(number) { | ||
return isNaturalNumber(roundNumber(number)); | ||
}; | ||
|
||
moment.duration.fn.formatAsFrequency = function(unit, options) { | ||
options = options || {}; | ||
_.defaults(options, this.formatAsFrequency.defaults); | ||
|
||
var unitDuration = moment.duration(1, unit); | ||
var isValidUnit = unitDuration.asMilliseconds() > 0; | ||
if (!isValidUnit) { | ||
throw new Error(util.format('%s is not a valid moment unit', unit)); | ||
} | ||
|
||
var intervalInMs = this.asMilliseconds(); | ||
var unitDurationInMs = unitDuration.asMilliseconds(); | ||
|
||
var unitSingular = moment.normalizeUnits(unit); | ||
var unitPlural = unitSingular + 's'; | ||
|
||
if (intervalInMs === unitDurationInMs) { | ||
return util.format('%s %s', options.everyString, unitSingular); | ||
} | ||
|
||
if (intervalInMs < unitDurationInMs) { | ||
var numberOfIntervalsPerUnit = unitDurationInMs / intervalInMs; | ||
if (isApproximatelyNaturalNumber(numberOfIntervalsPerUnit)) { | ||
return util.format('%d %s %s %s', roundNumber(numberOfIntervalsPerUnit), options.timesString, options.perString, unitSingular); | ||
} | ||
|
||
return util.format('%d%s%d %s %s %s', Math.floor(numberOfIntervalsPerUnit), options.separatorString, Math.ceil(numberOfIntervalsPerUnit), options.timesString, options.perString, unitSingular); | ||
} | ||
|
||
var numberOfUnitsPerInterval = intervalInMs / unitDuration; | ||
if (isApproximatelyNaturalNumber(numberOfUnitsPerInterval)) { | ||
return util.format('%s %d %s', options.everyString, roundNumber(numberOfUnitsPerInterval), unitPlural); | ||
} | ||
|
||
return util.format('%s %d%s%d %s', options.everyString, Math.floor(numberOfUnitsPerInterval), options.separatorString, Math.ceil(numberOfUnitsPerInterval), unitPlural); | ||
|
||
}; | ||
|
||
moment.duration.fn.formatAsFrequency.defaults = { | ||
everyString: 'every', | ||
perString: 'per', | ||
timesString: 'times', | ||
separatorString: '-' | ||
}; | ||
})(moment); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "moment-duration-format-frequency", | ||
"version": "1.0.0", | ||
"description": "Formats time interval to human readable string", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha test" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/DispatcherInc/moment-duration-format-frequency.git" | ||
}, | ||
"keywords": [ | ||
"frequency", | ||
"format", | ||
"interval", | ||
"string" | ||
], | ||
"author": "Kevin Stumpf", | ||
"license": "ISC", | ||
"bugs": { | ||
"url": "https://github.com/DispatcherInc/moment-duration-format-frequency/issues" | ||
}, | ||
"homepage": "https://github.com/DispatcherInc/moment-duration-format-frequency#readme", | ||
"devDependencies": { | ||
"chai": "^3.3.0" | ||
}, | ||
"dependencies": { | ||
"is-natural-number": "^2.0.0", | ||
"lodash": "^3.10.1", | ||
"moment": ">=1.4.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* jshint node: true */ | ||
|
||
'use strict'; | ||
|
||
var chai = require('chai'); | ||
var expect = chai.expect; | ||
var moment = require('moment'); | ||
|
||
require('./../lib/momentDurationFormatFrequency'); | ||
|
||
describe('moment-duration-format-frequency', function() { | ||
it('should work with frequencies greater than 1 per unit', function() { | ||
var everyOneAndAHalfWeeks = moment.duration(1.5, 'weeks'); | ||
|
||
expect(everyOneAndAHalfWeeks.formatAsFrequency('weeks')).to.eql('every 1-2 weeks'); | ||
}); | ||
|
||
it('should work with frequencies less than 1 per unit', function() { | ||
var fourToFiveTimesPerWeek = moment.duration(0.23, 'weeks'); | ||
|
||
expect(fourToFiveTimesPerWeek.formatAsFrequency('weeks')).to.eql('4-5 times per week'); | ||
}); | ||
|
||
it('should work with frequencies of 1 per unit', function() { | ||
var everyThreeWeeks = moment.duration(3, 'weeks'); | ||
|
||
expect(everyThreeWeeks.formatAsFrequency('weeks')).to.eql('every 3 weeks'); | ||
}); | ||
|
||
it('should work with frequencies whose inverse is a natural number', function() { | ||
var fourTimesPerWeek = moment.duration(0.25, 'weeks'); | ||
|
||
expect(fourTimesPerWeek.formatAsFrequency('weeks')).to.eql('4 times per week'); | ||
}); | ||
|
||
it('should work with years unit as well', function() { | ||
var everyThreeYears = moment.duration(3, 'years'); | ||
|
||
expect(everyThreeYears.formatAsFrequency('years')).to.eql('every 3 years'); | ||
}); | ||
|
||
describe('defaults', function() { | ||
it('everyString should be overwritable', function() { | ||
moment.duration.fn.formatAsFrequency.defaults.everyString = 'alle'; | ||
|
||
var everyThreeYears = moment.duration(3, 'years'); | ||
expect(everyThreeYears.formatAsFrequency('years')).to.eql('alle 3 years'); | ||
}); | ||
}); | ||
}); |