moment-range

Fancy date ranges for Moment.js

moment-range

Fancy date ranges for Moment.js.

Detailed API documentation can be found at: http://gf3.github.io/moment-range/DateRange.html

Create a date range:

var start = new Date(2012, 0, 15);
var end   = new Date(2012, 4, 23);
var range = moment.range(start, end);

You can also create a date range with moment objects:

var start = moment("2011-04-15", "YYYY-MM-DD");
var end   = moment("2011-11-27", "YYYY-MM-DD");
var range = moment.range(start, end);

Arrays work too:

var dates = [moment("2011-04-15", "YYYY-MM-DD"), moment("2011-11-27", "YYYY-MM-DD")];
var range = moment.range(dates);

You can also create a range from an ISO 8601 time interval string:

var timeInterval = "2015-01-17T09:50:04+00:00/2015-04-17T08:29:55+00:00";
var range = moment.range(timeInterval);

Check to see if your range contains a date/moment:

var start  = new Date(2012, 4, 1);
var end    = new Date(2012, 4, 23);
var lol    = new Date(2012, 4, 15);
var wat    = new Date(2012, 4, 27);
var range  = moment.range(start, end);
var range2 = moment.range(lol, wat);
 
range.contains(lol); // true 
range.contains(wat); // false 

A optional second parameter indicates if the end of the range should be excluded when testing for inclusion

range.contains(end) // true 
range.contains(end, false) // true 
range.contains(end, true) // false 

Find out if your moment falls within a date range:

var start = new Date(2012, 4, 1);
var end   = new Date(2012, 4, 23);
var when  = moment("2012-05-10", "YYYY-MM-DD");
var range = moment.range(start, end);
 
when.within(range); // true 

Does it overlap another range?

range.overlaps(range2); // true 

What are the intersecting ranges?

range.intersect(range2); // [moment.range(lol, end)] 

Add/combine/merge overlapping ranges.

range.add(range2); // [moment.range(start, wat)] 
 
var range3 = moment.range(new Date(2012, 3, 1), new Date(2012, 3, 15);
range.add(range3); // [null] 

Subtracting one range from another.

range.subtract(range2); // [moment.range(start, lol)] 

Iterate over your date range by an amount of time or another range:

var start = new Date(2012, 2, 1);
var two   = new Date(2012, 2, 2);
var end   = new Date(2012, 2, 5);
var range1 = moment.range(start, end);
var range2 = moment.range(start, two); // One day 
var acc = [];
 
range1.by('days', function(moment) {
  // Do something with `moment` 
});

Any of the units accepted by moment.js' add method may be used.

You can also iterate by another range:

range1.by(range2, function(moment) {
  // Do something with `moment` 
  acc.push(moment);
});
 
acc.length == 5 // true 

Iteration also supports excluding the end value of the range by setting the last parameter to true.

var acc = [];
 
range1.by('d', function (moment) {
  acc.push(moment)
}, true);
 
acc.length == 4 // true 

Compare range lengths or add them together with simple math:

var r_1 = moment.range(new Date(2011, 2, 5), new Date(2011, 3, 15));
var r_2 = moment.range(new Date(1995, 0, 1), new Date(1995, 12, 25));
 
r_2 > r_1 // true 
 
r_1 + r_2 // duration of both ranges in milliseconds 
 
Math.abs(r_1 - r_2); // difference of ranges in milliseconds 

Check if two ranges are the same, i.e. their starts and ends are the same:

var r_1 = moment.range(new Date(2011, 2, 5), new Date(2011, 3, 15));
var r_2 = moment.range(new Date(2011, 2, 5), new Date(2011, 3, 15));
var r_3 = moment.range(new Date(2011, 3, 5), new Date(2011, 6, 15));
 
r_1.isSame(r_2); // true 
r_2.isSame(r_3); // false 

The difference of the entire range given various units.

Any of the units accepted by moment.js' add method may be used.

var start = new Date(2011, 2, 5);
var end   = new Date(2011, 5, 5);
var dr    = moment.range(start, end);
 
dr.diff('months'); // 3 
dr.diff('days'); // 92 
dr.diff(); // 7945200000 

Converts the DateRange to an Array of the start and end Date objects.

var start = new Date(2011, 2, 5);
var end   = new Date(2011, 5, 5);
var dr    = moment.range(start, end);
 
dr.toDate(); // [new Date(2011, 2, 5), new Date(2011, 5, 5)] 

Converting a DateRange to a String will format it as an ISO 8601 time interval:

var start = '2015-01-17T09:50:04+00:00';
var end   = '2015-04-17T08:29:55+00:00';
var range = moment.range(moment.utc(start), moment.utc(end));
 
range.toString() // "2015-01-17T09:50:04+00:00/2015-04-17T08:29:55+00:00" 

The difference between the end date and start date in milliseconds.

var start = new Date(2011, 2, 5);
var end   = new Date(2011, 5, 5);
var range = moment.range(start, end);
 
range.valueOf(); // 7945200000 

Calculate the center of a range

var start = new Date(2011, 2, 5);
var end   = new Date(2011, 3, 5);
var dr    = moment.range(start, end);
 
dr.center(); // 1300622400000 

Deep clone a range

var start = new Date(2011, 2, 5);
var end   = new Date(2011, 3, 5);
var dr    = moment.range(start, end);
 
var dr2 = dr.clone();
dr2.start.add(2, 'days');
 
dr2.start.toDate() === dr.start.toDate() // false 

moment-range works in both the browser and node.js.

Install via npm:

npm install moment-range --save-dev

And then require it:

var moment = require('moment');
require('moment-range');

Simply include moment-range after moment.js:

<script src="moment.js"></script>
<script src="moment-range.js"></script>

Thanks to the fine people at cdnjs, you can link to moment-range from the cdnjs servers.

bower install moment-range

Note: Include moment-range after moment.

Clone this bad boy:

git clone https://git@github.com/gf3/moment-range.git

Install the dependencies:

npm install

Do all the things!

npm run-script build
npm run-script test
npm run-script jsdoc

moment-range is UNLICENSED.