moment-range
Advanced tools
Comparing version 2.2.0 to 3.0.0-0
@@ -1,398 +0,442 @@ | ||
(function (root, factory) { | ||
if (typeof define === 'function' && define.amd) { | ||
// AMD. Register as an anonymous module unless amdModuleId is set | ||
define(["moment"], function (a0) { | ||
return (root['DateRange'] = factory(a0)); | ||
}); | ||
} else if (typeof exports === 'object') { | ||
// Node. Does not work with strict CommonJS, but | ||
// only CommonJS-like environments that support module.exports, | ||
// like Node. | ||
module.exports = factory(require("moment")); | ||
} else { | ||
root['DateRange'] = factory(moment); | ||
} | ||
}(this, function (moment) { | ||
(function webpackUniversalModuleDefinition(root, factory) { | ||
if(typeof exports === 'object' && typeof module === 'object') | ||
module.exports = factory(require("moment")); | ||
else if(typeof define === 'function' && define.amd) | ||
define("moment-range", ["moment"], factory); | ||
else if(typeof exports === 'object') | ||
exports["moment-range"] = factory(require("moment")); | ||
else | ||
root["moment-range"] = factory(root["moment"]); | ||
})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) { | ||
return /******/ (function(modules) { // webpackBootstrap | ||
/******/ // The module cache | ||
/******/ var installedModules = {}; | ||
/******/ | ||
/******/ // The require function | ||
/******/ function __webpack_require__(moduleId) { | ||
/******/ | ||
/******/ // Check if module is in cache | ||
/******/ if(installedModules[moduleId]) | ||
/******/ return installedModules[moduleId].exports; | ||
/******/ | ||
/******/ // Create a new module (and put it into the cache) | ||
/******/ var module = installedModules[moduleId] = { | ||
/******/ exports: {}, | ||
/******/ id: moduleId, | ||
/******/ loaded: false | ||
/******/ }; | ||
/******/ | ||
/******/ // Execute the module function | ||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||
/******/ | ||
/******/ // Flag the module as loaded | ||
/******/ module.loaded = true; | ||
/******/ | ||
/******/ // Return the exports of the module | ||
/******/ return module.exports; | ||
/******/ } | ||
/******/ | ||
/******/ | ||
/******/ // expose the modules object (__webpack_modules__) | ||
/******/ __webpack_require__.m = modules; | ||
/******/ | ||
/******/ // expose the module cache | ||
/******/ __webpack_require__.c = installedModules; | ||
/******/ | ||
/******/ // __webpack_public_path__ | ||
/******/ __webpack_require__.p = ""; | ||
/******/ | ||
/******/ // Load entry module and return exports | ||
/******/ return __webpack_require__(0); | ||
/******/ }) | ||
/************************************************************************/ | ||
/******/ ([ | ||
/* 0 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
//----------------------------------------------------------------------------- | ||
// Contstants | ||
//----------------------------------------------------------------------------- | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.DateRange = undefined; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
exports.extendMoment = extendMoment; | ||
var _moment = __webpack_require__(1); | ||
var _moment2 = _interopRequireDefault(_moment); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
//----------------------------------------------------------------------------- | ||
// Constants | ||
//----------------------------------------------------------------------------- | ||
var INTERVALS = { | ||
year: true, | ||
quarter: true, | ||
month: true, | ||
week: true, | ||
day: true, | ||
hour: true, | ||
minute: true, | ||
second: true | ||
}; | ||
//----------------------------------------------------------------------------- | ||
// Date Ranges | ||
//----------------------------------------------------------------------------- | ||
var DateRange = exports.DateRange = function () { | ||
function DateRange(start, end) { | ||
_classCallCheck(this, DateRange); | ||
var s = start; | ||
var e = end; | ||
if (arguments.length === 1 || end === undefined) { | ||
if ((typeof start === 'undefined' ? 'undefined' : _typeof(start)) === 'object' && start.length === 2) { | ||
var _start = _slicedToArray(start, 2); | ||
s = _start[0]; | ||
e = _start[1]; | ||
} else if (typeof start === 'string') { | ||
var _start$split = start.split('/'); | ||
var _start$split2 = _slicedToArray(_start$split, 2); | ||
s = _start$split2[0]; | ||
e = _start$split2[1]; | ||
} | ||
} | ||
this.start = s === null ? (0, _moment2.default)(-8640000000000000) : (0, _moment2.default)(s); | ||
this.end = e === null ? (0, _moment2.default)(8640000000000000) : (0, _moment2.default)(e); | ||
} | ||
_createClass(DateRange, [{ | ||
key: 'adjacent', | ||
value: function adjacent(other) { | ||
var sameStartEnd = this.start.isSame(other.end); | ||
var sameEndStart = this.end.isSame(other.start); | ||
return sameStartEnd && other.start.valueOf() <= this.start.valueOf() || sameEndStart && other.end.valueOf() >= this.end.valueOf(); | ||
} | ||
}, { | ||
key: 'add', | ||
value: function add(other) { | ||
if (this.overlaps(other)) { | ||
return new this.constructor(_moment2.default.min(this.start, other.start), _moment2.default.max(this.end, other.end)); | ||
} | ||
return null; | ||
} | ||
}, { | ||
key: 'by', | ||
value: function by(interval) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { exclusive: false, step: 1 }; | ||
var range = this; | ||
return _defineProperty({}, Symbol.iterator, function () { | ||
var exclusive = options.exclusive || false; | ||
var step = options.step || 1; | ||
var diff = Math.abs(range.start.diff(range.end, interval)) / step; | ||
var iteration = 0; | ||
return { | ||
next: function next() { | ||
var current = range.start.clone().add(iteration * step, interval); | ||
var done = exclusive ? !(iteration < diff) : !(iteration <= diff); | ||
iteration++; | ||
return { | ||
done: done, | ||
value: done ? undefined : current | ||
}; | ||
} | ||
}; | ||
}); | ||
} | ||
}, { | ||
key: 'byRange', | ||
value: function byRange(interval) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { exclusive: false, step: 1 }; | ||
var range = this; | ||
var step = options.step || 1; | ||
var diff = this.valueOf() / interval.valueOf() / step; | ||
var exclusive = options.exclusive || false; | ||
var unit = Math.floor(diff); | ||
var iteration = 0; | ||
return _defineProperty({}, Symbol.iterator, function () { | ||
if (unit === Infinity) { | ||
return { done: true }; | ||
} | ||
return { | ||
next: function next() { | ||
var current = (0, _moment2.default)(range.start.valueOf() + interval.valueOf() * iteration * step); | ||
var done = unit === diff && exclusive ? !(iteration < unit) : !(iteration <= unit); | ||
iteration++; | ||
return { | ||
done: done, | ||
value: done ? undefined : current | ||
}; | ||
} | ||
}; | ||
}); | ||
} | ||
}, { | ||
key: 'center', | ||
value: function center() { | ||
var center = this.start.valueOf() + this.diff() / 2; | ||
return (0, _moment2.default)(center); | ||
} | ||
}, { | ||
key: 'clone', | ||
value: function clone() { | ||
return new this.constructor(this.start, this.end); | ||
} | ||
}, { | ||
key: 'contains', | ||
value: function contains(other) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { exclusive: false }; | ||
var start = this.start.valueOf(); | ||
var end = this.end.valueOf(); | ||
var oStart = other.valueOf(); | ||
var oEnd = other.valueOf(); | ||
if (other instanceof DateRange) { | ||
oStart = other.start.valueOf(); | ||
oEnd = other.end.valueOf(); | ||
} | ||
var startInRange = start < oStart || start <= oStart && !options.exclusive; | ||
var endInRange = end > oEnd || end >= oEnd && !options.exclusive; | ||
return startInRange && endInRange; | ||
} | ||
}, { | ||
key: 'diff', | ||
value: function diff(unit, rounded) { | ||
return this.end.diff(this.start, unit, rounded); | ||
} | ||
}, { | ||
key: 'duration', | ||
value: function duration(unit, rounded) { | ||
return this.diff(unit, rounded); | ||
} | ||
}, { | ||
key: 'intersect', | ||
value: function intersect(other) { | ||
var start = this.start.valueOf(); | ||
var end = this.end.valueOf(); | ||
var oStart = other.start.valueOf(); | ||
var oEnd = other.end.valueOf(); | ||
if (start <= oStart && oStart < end && end < oEnd) { | ||
return new this.constructor(oStart, end); | ||
} else if (oStart < start && start < oEnd && oEnd <= end) { | ||
return new this.constructor(start, oEnd); | ||
} else if (oStart < start && start <= end && end < oEnd) { | ||
return this; | ||
} else if (start <= oStart && oStart <= oEnd && oEnd <= end) { | ||
return other; | ||
} | ||
return null; | ||
} | ||
}, { | ||
key: 'isEqual', | ||
value: function isEqual(other) { | ||
return this.start.isSame(other.start) && this.end.isSame(other.end); | ||
} | ||
}, { | ||
key: 'isSame', | ||
value: function isSame(other) { | ||
return this.isEqual(other); | ||
} | ||
}, { | ||
key: 'overlaps', | ||
value: function overlaps(other) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { adjacent: false }; | ||
var intersect = this.intersect(other) !== null; | ||
if (options.adjacent && !intersect) { | ||
return this.adjacent(other); | ||
} | ||
return intersect; | ||
} | ||
}, { | ||
key: 'reverseBy', | ||
value: function reverseBy(interval) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { exclusive: false, step: 1 }; | ||
var range = this; | ||
return _defineProperty({}, Symbol.iterator, function () { | ||
var exclusive = options.exclusive || false; | ||
var step = options.step || 1; | ||
var diff = Math.abs(range.start.diff(range.end, interval)) / step; | ||
var iteration = 0; | ||
return { | ||
next: function next() { | ||
var current = range.end.clone().subtract(iteration * step, interval); | ||
var done = exclusive ? !(iteration < diff) : !(iteration <= diff); | ||
iteration++; | ||
return { | ||
done: done, | ||
value: done ? undefined : current | ||
}; | ||
} | ||
}; | ||
}); | ||
} | ||
}, { | ||
key: 'reverseByRange', | ||
value: function reverseByRange(interval) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { exclusive: false, step: 1 }; | ||
var range = this; | ||
var step = options.step || 1; | ||
var diff = this.valueOf() / interval.valueOf() / step; | ||
var exclusive = options.exclusive || false; | ||
var unit = Math.floor(diff); | ||
var iteration = 0; | ||
return _defineProperty({}, Symbol.iterator, function () { | ||
if (unit === Infinity) { | ||
return { done: true }; | ||
} | ||
return { | ||
next: function next() { | ||
var current = (0, _moment2.default)(range.end.valueOf() - interval.valueOf() * iteration * step); | ||
var done = unit === diff && exclusive ? !(iteration < unit) : !(iteration <= unit); | ||
iteration++; | ||
return { | ||
done: done, | ||
value: done ? undefined : current | ||
}; | ||
} | ||
}; | ||
}); | ||
} | ||
}, { | ||
key: 'subtract', | ||
value: function subtract(other) { | ||
var start = this.start.valueOf(); | ||
var end = this.end.valueOf(); | ||
var oStart = other.start.valueOf(); | ||
var oEnd = other.end.valueOf(); | ||
if (this.intersect(other) === null) { | ||
return [this]; | ||
} else if (oStart <= start && start < end && end <= oEnd) { | ||
return []; | ||
} else if (oStart <= start && start < oEnd && oEnd < end) { | ||
return [new this.constructor(oEnd, end)]; | ||
} else if (start < oStart && oStart < end && end <= oEnd) { | ||
return [new this.constructor(start, oStart)]; | ||
} else if (start < oStart && oStart < oEnd && oEnd < end) { | ||
return [new this.constructor(start, oStart), new this.constructor(oEnd, end)]; | ||
} else if (start < oStart && oStart < end && oEnd < end) { | ||
return [new this.constructor(start, oStart), new this.constructor(oStart, end)]; | ||
} | ||
return []; | ||
} | ||
}, { | ||
key: 'toDate', | ||
value: function toDate() { | ||
return [this.start.toDate(), this.end.toDate()]; | ||
} | ||
}, { | ||
key: 'toString', | ||
value: function toString() { | ||
return this.start.format() + '/' + this.end.format(); | ||
} | ||
}, { | ||
key: 'valueOf', | ||
value: function valueOf() { | ||
return this.end.valueOf() - this.start.valueOf(); | ||
} | ||
}]); | ||
return DateRange; | ||
}(); | ||
//----------------------------------------------------------------------------- | ||
// Moment Extensions | ||
//----------------------------------------------------------------------------- | ||
function extendMoment(moment) { | ||
/** | ||
* Build a date range. | ||
*/ | ||
moment.range = function range(start, end) { | ||
var m = this; | ||
if (INTERVALS.hasOwnProperty(start)) { | ||
return new DateRange(moment(m).startOf(start), moment(m).endOf(start)); | ||
} | ||
return new DateRange(start, end); | ||
}; | ||
/** | ||
* Alias of static constructor. | ||
*/ | ||
moment.fn.range = moment.range; | ||
/** | ||
* Expose constructor | ||
*/ | ||
moment.range.constructor = DateRange; | ||
/** | ||
* Check if the current moment is within a given date range. | ||
*/ | ||
moment.fn.within = function (range) { | ||
return range.contains(this.toDate()); | ||
}; | ||
return moment; | ||
} | ||
/***/ }, | ||
/* 1 */ | ||
/***/ function(module, exports) { | ||
module.exports = __WEBPACK_EXTERNAL_MODULE_1__; | ||
var INTERVALS = { | ||
year: true, | ||
month: true, | ||
week: true, | ||
day: true, | ||
hour: true, | ||
minute: true, | ||
second: true | ||
}; | ||
//----------------------------------------------------------------------------- | ||
// Date Ranges | ||
//----------------------------------------------------------------------------- | ||
/** | ||
* DateRange class to store ranges and query dates. | ||
* | ||
* @constructor | ||
* @param {(Moment|Date)} start Start of interval | ||
* @param {(Moment|Date)} end End of interval | ||
*//** | ||
* DateRange class to store ranges and query dates. | ||
* | ||
* @constructor | ||
* @param {!Array} range Array containing start and end dates. | ||
*//** | ||
* DateRange class to store ranges and query dates. | ||
* | ||
* @constructor | ||
* @param {!String} range String formatted as an IS0 8601 time interval | ||
*/ | ||
function DateRange(start, end) { | ||
var parts; | ||
var s = start; | ||
var e = end; | ||
if (arguments.length === 1 || end === undefined) { | ||
if (typeof start === 'object' && start.length === 2) { | ||
s = start[0]; | ||
e = start[1]; | ||
} | ||
else if (typeof start === 'string') { | ||
parts = start.split('/'); | ||
s = parts[0]; | ||
e = parts[1]; | ||
} | ||
} | ||
this.start = (s === null) ? moment(-8640000000000000) : moment(s); | ||
this.end = (e === null) ? moment(8640000000000000) : moment(e); | ||
} | ||
/** | ||
* Constructor for prototype. | ||
* | ||
* @type {DateRange} | ||
*/ | ||
DateRange.prototype.constructor = DateRange; | ||
/** | ||
* Deep clone range. | ||
* | ||
* @return {!DateRange} | ||
*/ | ||
DateRange.prototype.clone = function() { | ||
return moment().range(this.start, this.end); | ||
}; | ||
/** | ||
* Determine if the current interval contains a given moment/date/range. | ||
* | ||
* @param {(Moment|Date|DateRange)} other Date to check | ||
* @param {!boolean} exclusive True if the to value is exclusive | ||
* | ||
* @return {!boolean} | ||
*/ | ||
DateRange.prototype.contains = function(other, exclusive) { | ||
var start = this.start; | ||
var end = this.end; | ||
if (other instanceof DateRange) { | ||
return start <= other.start && (end > other.end || (end.isSame(other.end) && !exclusive)); | ||
} | ||
else { | ||
return start <= other && (end > other || (end.isSame(other) && !exclusive)); | ||
} | ||
}; | ||
/** | ||
* Determine if the current date range overlaps a given date range. | ||
* | ||
* @param {!DateRange} range Date range to check | ||
* | ||
* @return {!boolean} | ||
*/ | ||
DateRange.prototype.overlaps = function(range) { | ||
return this.intersect(range) !== null; | ||
}; | ||
/** | ||
* Determine the intersecting periods from one or more date ranges. | ||
* | ||
* @param {!DateRange} other A date range to intersect with this one | ||
* | ||
* @return {DateRange} Returns the intersecting date or `null` if the ranges do | ||
* not intersect | ||
*/ | ||
DateRange.prototype.intersect = function(other) { | ||
var start = this.start; | ||
var end = this.end; | ||
if ((start <= other.start) && (other.start < end) && (end < other.end)) { | ||
return new DateRange(other.start, end); | ||
} | ||
else if ((other.start < start) && (start < other.end) && (other.end <= end)) { | ||
return new DateRange(start, other.end); | ||
} | ||
else if ((other.start < start) && (start <= end) && (end < other.end)) { | ||
return this; | ||
} | ||
else if ((start <= other.start) && (other.start <= other.end) && (other.end <= end)) { | ||
return other; | ||
} | ||
return null; | ||
}; | ||
/** | ||
* Merge date ranges if they intersect. | ||
* | ||
* @param {!DateRange} other A date range to add to this one | ||
* | ||
* @return {DateRange} Returns the new `DateRange` or `null` if they do not | ||
* overlap | ||
*/ | ||
DateRange.prototype.add = function(other) { | ||
if (this.overlaps(other)) { | ||
return new DateRange(moment.min(this.start, other.start), moment.max(this.end, other.end)); | ||
} | ||
return null; | ||
}; | ||
/** | ||
* Subtract one range from another. | ||
* | ||
* @param {!DateRange} other A date range to substract from this one | ||
* | ||
* @return {!Array<DateRange>} | ||
*/ | ||
DateRange.prototype.subtract = function(other) { | ||
var start = this.start; | ||
var end = this.end; | ||
if (this.intersect(other) === null) { | ||
return [this]; | ||
} | ||
else if ((other.start <= start) && (start < end) && (end <= other.end)) { | ||
return []; | ||
} | ||
else if ((other.start <= start) && (start < other.end) && (other.end < end)) { | ||
return [new DateRange(other.end, end)]; | ||
} | ||
else if ((start < other.start) && (other.start < end) && (end <= other.end)) { | ||
return [new DateRange(start, other.start)]; | ||
} | ||
else if ((start < other.start) && (other.start < other.end) && (other.end < end)) { | ||
return [new DateRange(start, other.start), new DateRange(other.end, end)]; | ||
} | ||
else if ((start < other.start) && (other.start < end) && (other.end < end)) { | ||
return [new DateRange(start, other.start), new DateRange(other.start, end)]; | ||
} | ||
}; | ||
/** | ||
* Build a n array of dates. | ||
* | ||
* @param {(!DateRange|String)} range Date range to be used for iteration or | ||
* shorthand string (shorthands: | ||
* http://momentjs.com/docs/#/manipulating/add/) | ||
* @param {!boolean} exclusive Indicate that the end of the range should not | ||
* be included in the iter. | ||
* | ||
* @return {!Array} | ||
*/ | ||
DateRange.prototype.toArray = function(by, exclusive) { | ||
var acc = []; | ||
this.by(by, function(unit) { | ||
acc.push(unit); | ||
}, exclusive); | ||
return acc; | ||
}; | ||
/** | ||
* Iterate over the date range by a given date range, executing a function | ||
* for each sub-range. | ||
* | ||
* @param {(!DateRange|String)} range Date range to be used for iteration or | ||
* shorthand string (shorthands: | ||
* http://momentjs.com/docs/#/manipulating/add/) | ||
* @param {!DateRange~by} hollaback Callback | ||
* @param {!boolean} exclusive Indicate that the end of the range should not | ||
* be included in the iter. | ||
* | ||
* @return {DateRange} `this` | ||
*/ | ||
DateRange.prototype.by = function(range, hollaback, exclusive) { | ||
if (typeof range === 'string') { | ||
_byString.call(this, range, hollaback, exclusive); | ||
} | ||
else { | ||
_byRange.call(this, range, hollaback, exclusive); | ||
} | ||
return this; | ||
}; | ||
/** | ||
* Callback executed for each sub-range. | ||
* | ||
* @callback DateRange~by | ||
* | ||
* @param {!Moment} current Current moment object for iteration | ||
*/ | ||
/** | ||
* @private | ||
*/ | ||
function _byString(interval, hollaback, exclusive) { | ||
var current = moment(this.start); | ||
while (this.contains(current, exclusive)) { | ||
hollaback.call(this, current.clone()); | ||
current.add(1, interval); | ||
} | ||
} | ||
/** | ||
* @private | ||
*/ | ||
function _byRange(interval, hollaback, exclusive) { | ||
var div = this / interval; | ||
var l = Math.floor(div); | ||
if (l === Infinity) { return; } | ||
if (l === div && exclusive) { | ||
l--; | ||
} | ||
for (var i = 0; i <= l; i++) { | ||
hollaback.call(this, moment(this.start.valueOf() + interval.valueOf() * i)); | ||
} | ||
} | ||
/** | ||
* Date range formatted as an [ISO8601 Time | ||
* Interval](http://en.wikipedia.org/wiki/ISO_8601#Time_intervals). | ||
* | ||
* @return {!String} | ||
*/ | ||
DateRange.prototype.toString = function() { | ||
return this.start.format() + '/' + this.end.format(); | ||
}; | ||
/** | ||
* Date range in milliseconds. Allows basic coercion math of date ranges. | ||
* | ||
* @return {!number} | ||
*/ | ||
DateRange.prototype.valueOf = function() { | ||
return this.end - this.start; | ||
}; | ||
/** | ||
* Center date of the range. | ||
* | ||
* @return {!Moment} | ||
*/ | ||
DateRange.prototype.center = function() { | ||
var center = this.start + this.diff() / 2; | ||
return moment(center); | ||
}; | ||
/** | ||
* Date range toDate | ||
* | ||
* @return {!Array<Date>} | ||
*/ | ||
DateRange.prototype.toDate = function() { | ||
return [this.start.toDate(), this.end.toDate()]; | ||
}; | ||
/** | ||
* Determine if this date range is the same as another. | ||
* | ||
* @param {!DateRange} other Another date range to compare to | ||
* | ||
* @return {!boolean} | ||
*/ | ||
DateRange.prototype.isSame = function(other) { | ||
return this.start.isSame(other.start) && this.end.isSame(other.end); | ||
}; | ||
/** | ||
* The difference of the end vs start. | ||
* | ||
* @param {number} unit Unit of difference, if no unit is passed in | ||
* milliseconds are returned. E.g.: `"days"`, `"months"`, | ||
* etc... | ||
* | ||
* @return {!number} | ||
*/ | ||
DateRange.prototype.diff = function(unit) { | ||
return this.end.diff(this.start, unit); | ||
}; | ||
//----------------------------------------------------------------------------- | ||
// Moment Extensions | ||
//----------------------------------------------------------------------------- | ||
/** | ||
* Build a date range. | ||
* | ||
* @param {(Moment|Date)} start Start of range | ||
* @param {(Moment|Date)} end End of range | ||
* | ||
* @this {Moment} | ||
* | ||
* @return {!DateRange} | ||
*/ | ||
moment.range = function(start, end) { | ||
if (start in INTERVALS) { | ||
return new DateRange(moment(this).startOf(start), moment(this).endOf(start)); | ||
} | ||
else { | ||
return new DateRange(start, end); | ||
} | ||
}; | ||
/** | ||
* Expose constructor | ||
* | ||
* @const | ||
*/ | ||
moment.range.constructor = DateRange; | ||
/** | ||
* @deprecated | ||
*/ | ||
moment.fn.range = moment.range; | ||
/** | ||
* Check if the current moment is within a given date range. | ||
* | ||
* @param {!DateRange} range Date range to check | ||
* | ||
* @this {Moment} | ||
* | ||
* @return {!boolean} | ||
*/ | ||
moment.fn.within = function(range) { | ||
return range.contains(this._d); | ||
}; | ||
//----------------------------------------------------------------------------- | ||
// Export | ||
//----------------------------------------------------------------------------- | ||
return DateRange; | ||
})); | ||
/***/ } | ||
/******/ ]) | ||
}); | ||
; | ||
//# sourceMappingURL=moment-range.js.map |
{ | ||
"name": "moment-range", | ||
"description": "Fancy date ranges for Moment.js", | ||
"author": "Gianni Chiappetta <gianni@runlevel6.org> (http://butt.zone)", | ||
"author": "Gianni Chiappetta <gianni@runlevel6.org> (https://butt.zone)", | ||
"contributors": [ | ||
@@ -21,29 +21,45 @@ "Adam Biggs <adam.biggs@lightmaker.com>", | ||
"main": "./dist/moment-range", | ||
"directories": { | ||
"lib": "./lib" | ||
}, | ||
"version": "2.2.0", | ||
"version": "3.0.0-0", | ||
"engines": { | ||
"node": "*" | ||
}, | ||
"files": [ | ||
"dist/" | ||
], | ||
"scripts": { | ||
"build": "grunt es6transpiler replace umd uglify", | ||
"jsdoc": "jsdoc -c .jsdoc", | ||
"test": "grunt mochaTest" | ||
"build": "webpack", | ||
"doctoc": "doctoc README.md --github", | ||
"lint": "eslint ./lib/", | ||
"prepublish": "npm run build; cp ./lib/moment-range.js.flow ./dist", | ||
"preversion": "npm run test && npm run lint", | ||
"test": "karma start ./karma.conf.js", | ||
"version": "npm run build; cp ./lib/moment-range.js.flow ./dist" | ||
}, | ||
"devDependencies": { | ||
"grunt": "~0.4.1", | ||
"grunt-cli": "^0.1.13", | ||
"grunt-contrib-uglify": "^0.6.0", | ||
"grunt-es6-transpiler": "^1.0.2", | ||
"grunt-mocha-test": "~0.7.0", | ||
"babel-core": "^6.18.2", | ||
"babel-eslint": "^7.1.1", | ||
"babel-loader": "^6.2.8", | ||
"babel-plugin-transform-flow-strip-types": "^6.18.0", | ||
"babel-polyfill": "^6.16.0", | ||
"babel-preset-es2015": "^6.18.0", | ||
"babel-preset-stage-0": "^6.16.0", | ||
"copy-webpack-plugin": "^4.0.1", | ||
"doctoc": "^1.2.0", | ||
"eslint": "^3.11.1", | ||
"eslint-loader": "^1.6.1", | ||
"flow-bin": "^0.36.0", | ||
"grunt-text-replace": "^0.4.0", | ||
"grunt-umd": "^2.3.3", | ||
"jsdoc": "^3.3.0", | ||
"mocha": "^2.1.0", | ||
"moment": ">= 1", | ||
"should": "^5.0.1" | ||
"karma": "^1.3.0", | ||
"karma-babel-polyfill": "0.0.5", | ||
"karma-chrome-launcher": "^2.0.0", | ||
"karma-expect": "^1.1.3", | ||
"karma-mocha": "^1.3.0", | ||
"karma-phantomjs-launcher": "^1.0.2", | ||
"karma-sourcemap-loader": "^0.3.7", | ||
"karma-webpack": "^1.8.0", | ||
"mocha": "^2.5.3", | ||
"webpack": "^1.13.3" | ||
}, | ||
"peerDependencies": { | ||
"moment": ">= 1" | ||
"moment": ">= 2" | ||
}, | ||
@@ -57,3 +73,6 @@ "repository": { | ||
"url": "https://github.com/gf3/moment-range/raw/master/UNLICENSE" | ||
}, | ||
"dependencies": { | ||
"expect.js": "^0.3.1" | ||
} | ||
} |
582
README.md
@@ -5,25 +5,35 @@ # moment-range | ||
Detailed API documentation can be found at: http://gf3.github.io/moment-range/DateRange.html | ||
<!-- START doctoc generated TOC please keep comment here to allow auto update --> | ||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> | ||
- [Installation](#installation) | ||
- [Node / NPM](#node--npm) | ||
- [Browser](#browser) | ||
- [Examples](#examples) | ||
- [Create](#create) | ||
- [Contains / Within / Overlaps / Intersect / Add / Subtract](#contains--within--overlaps--intersect--add--subtract) | ||
- [Iterate](#iterate) | ||
- [Attributes](#attributes) | ||
- [Querying](#querying) | ||
- [Adjacent](#adjacent) | ||
- [Center](#center) | ||
- [Contains](#contains) | ||
- [Within](#within) | ||
- [Overlaps](#overlaps) | ||
- [Intersect](#intersect) | ||
- [Manipulation](#manipulation) | ||
- [Add](#add) | ||
- [Clone](#clone) | ||
- [Subtract](#subtract) | ||
- [Iteration](#iteration) | ||
- [by](#by) | ||
- [byRange](#byrange) | ||
- [reverseBy](#reverseby) | ||
- [reverseByRange](#reversebyrange) | ||
- [Compare](#compare) | ||
- [Equality](#equality) | ||
- [Difference](#difference) | ||
- [Equality](#equality) | ||
- [Difference](#difference) | ||
- [Conversion](#conversion) | ||
- [`toArray`](#toarray) | ||
- [`toDate`](#todate) | ||
- [`toString`](#tostring) | ||
- [`valueOf`](#valueof) | ||
- [Center](#center) | ||
- [Clone](#clone) | ||
- [Installation](#installation) | ||
- [Browser](#browser) | ||
- [NPM](#npm) | ||
- [Bower](#bower) | ||
- [Running Tests](#running-tests) | ||
@@ -35,2 +45,48 @@ - [License](#license) | ||
## Installation | ||
moment-range works in both the browser and [node.js][node]. | ||
### Node / NPM | ||
Install via npm: | ||
``` sh | ||
npm install --save moment-range | ||
``` | ||
**ES6:** | ||
``` js | ||
import Moment from 'moment'; | ||
import { extendMoment } from 'moment-range'; | ||
const moment = extendMoment(Moment); | ||
``` | ||
**CommonJS:** | ||
``` js | ||
const Moment = require('moment'); | ||
const MomentRange = require('moment-range'); | ||
const moment = MomentRange.extendMoment(Moment); | ||
``` | ||
### Browser | ||
``` html | ||
<script src="moment.js"></script> | ||
<script src="moment-range.js"></script> | ||
``` | ||
``` js | ||
DateRange.extendMoment(moment); | ||
``` | ||
Thanks to the fine people at [cdnjs][cdnjs], you can link to moment-range from | ||
the [cdnjs servers][cdnjs-moment-range]. | ||
## Examples | ||
@@ -42,6 +98,6 @@ | ||
``` javascript | ||
var start = new Date(2012, 0, 15); | ||
var end = new Date(2012, 4, 23); | ||
var range = moment.range(start, end); | ||
``` js | ||
const start = new Date(2012, 0, 15); | ||
const end = new Date(2012, 4, 23); | ||
const range = moment.range(start, end); | ||
``` | ||
@@ -51,6 +107,6 @@ | ||
``` javascript | ||
var start = moment("2011-04-15", "YYYY-MM-DD"); | ||
var end = moment("2011-11-27", "YYYY-MM-DD"); | ||
var range = moment.range(start, end); | ||
``` js | ||
const start = moment('2011-04-15', 'YYYY-MM-DD'); | ||
const end = moment('2011-11-27', 'YYYY-MM-DD'); | ||
const range = moment.range(start, end); | ||
``` | ||
@@ -60,5 +116,5 @@ | ||
``` javascript | ||
var dates = [moment("2011-04-15", "YYYY-MM-DD"), moment("2011-11-27", "YYYY-MM-DD")]; | ||
var range = moment.range(dates); | ||
``` js | ||
const dates = [moment('2011-04-15', 'YYYY-MM-DD'), moment('2011-11-27', 'YYYY-MM-DD')]; | ||
const range = moment.range(dates); | ||
``` | ||
@@ -68,5 +124,5 @@ | ||
``` javascript | ||
var timeInterval = "2015-01-17T09:50:04+00:00/2015-04-17T08:29:55+00:00"; | ||
var range = moment.range(timeInterval); | ||
``` js | ||
const timeInterval = '2015-01-17T09:50:04+00:00/2015-04-17T08:29:55+00:00'; | ||
const range = moment.range(timeInterval); | ||
``` | ||
@@ -76,5 +132,5 @@ | ||
``` javascript | ||
var date = moment("2011-04-15", "YYYY-MM-DD"); | ||
var range = date.range("month"); | ||
``` js | ||
const date = moment('2011-04-15', 'YYYY-MM-DD'); | ||
const range = date.range('month'); | ||
``` | ||
@@ -84,19 +140,68 @@ | ||
``` javascript | ||
var rangeUntil = moment.range(null, "2011-05-05"); | ||
var rangeFrom = moment.range("2011-03-05", null); | ||
var rangeAllTime = moment.range(null, null); | ||
``` js | ||
const rangeUntil = moment.range(null, '2011-05-05'); | ||
const rangeFrom = moment.range('2011-03-05', null); | ||
const rangeAllTime = moment.range(null, null); | ||
``` | ||
### Contains / Within / Overlaps / Intersect / Add / Subtract | ||
*Note:* Dates and moment objects both use a timestamp of 00:00:000 if none is | ||
provided. To ensure your range includes any timestamp for the given end date, | ||
use `.setHours(23,59,59,999)` when constructing a Date object, or | ||
`.endOf('day')` when constructing a moment object. | ||
### Attributes | ||
You can access the start and end moments of the range easily enough: | ||
``` js | ||
const start = new Date(2012, 0, 15); | ||
const end = new Date(2012, 4, 23); | ||
const range = moment.range(start, end); | ||
range.start // moment | ||
range.end // moment | ||
``` | ||
### Querying | ||
#### Adjacent | ||
Check if two ranges are touching but not overlapping: | ||
``` js | ||
const a = moment('2016-03-15'); | ||
const b = moment('2016-03-29'); | ||
const c = moment('2016-03-10'); | ||
const d = moment('2016-03-15'); | ||
const range1 = moment.range(a, b); | ||
const range2 = moment.range(c, d); | ||
range1.adjacent(range2) // true | ||
``` | ||
#### Center | ||
Calculate the center of a range: | ||
``` js | ||
const start = new Date(2011, 2, 5); | ||
const end = new Date(2011, 3, 5); | ||
const dr = moment.range(start, end); | ||
dr.center(); // 1300622400000 | ||
``` | ||
#### Contains | ||
Check to see if your range contains a date/moment: | ||
``` javascript | ||
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); | ||
``` js | ||
const start = new Date(2012, 4, 1); | ||
const end = new Date(2012, 4, 23); | ||
const lol = new Date(2012, 4, 15); | ||
const wat = new Date(2012, 4, 27); | ||
const range = moment.range(start, end); | ||
const range2 = moment.range(lol, wat); | ||
@@ -107,18 +212,20 @@ range.contains(lol); // true | ||
A optional second parameter indicates if the end of the range | ||
should be excluded when testing for inclusion | ||
The `exclusive` options is used to indicate if the end of the range should be | ||
excluded when testing for inclusion: | ||
``` javascript | ||
``` js | ||
range.contains(end) // true | ||
range.contains(end, false) // true | ||
range.contains(end, true) // false | ||
range.contains(end, { exclusive: false }) // true | ||
range.contains(end, { exclusive: true }) // false | ||
``` | ||
#### Within | ||
Find out if your moment falls within a date range: | ||
``` javascript | ||
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); | ||
``` js | ||
const start = new Date(2012, 4, 1); | ||
const end = new Date(2012, 4, 23); | ||
const when = moment('2012-05-10', 'YYYY-MM-DD'); | ||
const range = moment.range(start, end); | ||
@@ -128,69 +235,104 @@ when.within(range); // true | ||
#### Overlaps | ||
Does it overlap another range? | ||
``` javascript | ||
``` js | ||
range.overlaps(range2); // true | ||
``` | ||
Include adjacent ranges: | ||
``` js | ||
const a = moment('2016-03-15'); | ||
const b = moment('2016-03-20'); | ||
const c = moment('2016-03-20'); | ||
const d = moment('2016-03-25'); | ||
const range1 = moment.range(a, b); | ||
const range2 = moment.range(c, d); | ||
range1.overlaps(range2) // false | ||
range1.overlaps(range2, { adjacent: false }) // false | ||
range1.overlaps(range2, { adjacent: true }) // true | ||
``` | ||
#### Intersect | ||
What are the intersecting ranges? | ||
``` javascript | ||
``` js | ||
range.intersect(range2); // [moment.range(lol, end)] | ||
``` | ||
### Manipulation | ||
#### Add | ||
Add/combine/merge overlapping ranges. | ||
``` javascript | ||
``` js | ||
range.add(range2); // [moment.range(start, wat)] | ||
var range3 = moment.range(new Date(2012, 3, 1), new Date(2012, 3, 15); | ||
const range3 = moment.range(new Date(2012, 3, 1), new Date(2012, 3, 15); | ||
range.add(range3); // [null] | ||
``` | ||
#### Clone | ||
Deep clone a range | ||
``` js | ||
const start = new Date(2011, 2, 5); | ||
const end = new Date(2011, 3, 5); | ||
const dr = moment.range(start, end); | ||
const dr2 = dr.clone(); | ||
dr2.start.add(2, 'days'); | ||
dr2.start.toDate() === dr.start.toDate() // false | ||
``` | ||
#### Subtract | ||
Subtracting one range from another. | ||
``` javascript | ||
``` js | ||
range.subtract(range2); // [moment.range(start, lol)] | ||
``` | ||
### Iterate | ||
### Iteration | ||
Iterate over your date range by an amount of time or another range: | ||
Each of the iteration methods return an [Iterable][iterable], providing | ||
a convenient and performant interface to iterating over your ranges by a given | ||
period. | ||
``` javascript | ||
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 = []; | ||
#### by | ||
range1.by('days', function(moment) { | ||
// Do something with `moment` | ||
}); | ||
``` | ||
Iterate over your range by a given period. Any of the units accepted by | ||
[moment.js' `add` method][add] may be used. E.g.: `'years' | 'quarters' | ||
| 'months' | 'weeks' | 'days' | 'hours' | 'minutes' | 'seconds' | ||
| 'milliseconds'` | ||
Any of the units accepted by [moment.js' `add` | ||
method](http://momentjs.com/docs/#/manipulating/add/) may be used. | ||
``` js | ||
const range = moment.range('2010-01-01', '2015-01-01'); | ||
You can also iterate by another range: | ||
for (let month of range.by('month')) { | ||
month.format('YYYY-MM-DD'); | ||
} | ||
``` javascript | ||
range1.by(range2, function(moment) { | ||
// Do something with `moment` | ||
acc.push(moment); | ||
}); | ||
acc.length == 5 // true | ||
const years = Array.from(range.by('year')); | ||
years.length == 5 // true | ||
years.map(m => m.format('YYYY')) // ['2010', '2011', '2012', '2013', '2014', '2015'] | ||
``` | ||
Iteration also supports excluding the end value of the range by setting the | ||
last parameter to `true`. | ||
`exclusive` option to `true`. | ||
``` javascript | ||
var acc = []; | ||
``` js | ||
const start = new Date(2012, 2, 1); | ||
const end = new Date(2012, 2, 5); | ||
const range1 = moment.range(start, end); | ||
range1.by('d', function (moment) { | ||
acc.push(moment) | ||
}, true); | ||
const acc = Array.from(range1.by('day', { exclusive: true })); | ||
@@ -200,166 +342,231 @@ acc.length == 4 // true | ||
### Compare | ||
Additionally it's possible to iterate by a given step that defaults to `1`: | ||
Compare range lengths or add them together with simple math: | ||
``` js | ||
const start = new Date(2012, 2, 2); | ||
const end = new Date(2012, 2, 6); | ||
const range1 = moment.range(start, end); | ||
``` javascript | ||
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)); | ||
let acc = Array.from(range1.by('day', { step: 2 })); | ||
r_2 > r_1 // true | ||
acc.map(m => m.format('DD')) // ['02', '04', '06'] | ||
r_1 + r_2 // duration of both ranges in milliseconds | ||
acc = Array.from(range1.by('day', { exclusive: true, step: 2 })); | ||
Math.abs(r_1 - r_2); // difference of ranges in milliseconds | ||
acc.map(m => m.format('DD')) // ['02', '04'] | ||
``` | ||
### Equality | ||
#### byRange | ||
Check if two ranges are the same, i.e. their starts and ends are the same: | ||
``` js | ||
const start = new Date(2012, 2, 1); | ||
const two = new Date(2012, 2, 2); | ||
const end = new Date(2012, 2, 5); | ||
const range1 = moment.range(start, end); | ||
const range2 = moment.range(start, two); // One day | ||
``` | ||
``` javascript | ||
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)); | ||
Iterate by another range: | ||
r_1.isSame(r_2); // true | ||
r_2.isSame(r_3); // false | ||
``` js | ||
const acc = Array.from(range1.by(range2)); | ||
acc.length == 5 // true | ||
``` | ||
### Difference | ||
Exclude the end value: | ||
The difference of the entire range given various units. | ||
``` js | ||
const acc = Array.from(range1.by(range2, { exclusive: true })); | ||
Any of the units accepted by [moment.js' `add` | ||
method](http://momentjs.com/docs/#/manipulating/add/) may be used. | ||
acc.length == 4 // true | ||
``` | ||
``` javascript | ||
var start = new Date(2011, 2, 5); | ||
var end = new Date(2011, 5, 5); | ||
var dr = moment.range(start, end); | ||
By step: | ||
dr.diff('months'); // 3 | ||
dr.diff('days'); // 92 | ||
dr.diff(); // 7945200000 | ||
``` js | ||
let acc = Array.from(range1.by(range2, { step: 2 })); | ||
acc.map(m => m.format('DD')) // ['01', '03', '05'] | ||
acc = Array.from(range1.by(range2, { exlusive, true, step: 2 })); | ||
acc.map(m => m.format('DD')) // ['01', '03'] | ||
``` | ||
### Conversion | ||
#### reverseBy | ||
#### `toArray` | ||
Iterate over a range in reverse: | ||
Converts the `DateRange` to an `Array` of `Date` objects. | ||
``` js | ||
const range = moment.range('2012-01-01', '2015-01-01'); | ||
const acc = Array.from(range.reverseBy('years')); | ||
acc.map(m => m.format('YYYY')) // ['2015', '2014', '2013', '2012'] | ||
``` | ||
``` javascript | ||
var start = new Date(2011, 2, 5); | ||
var end = new Date(2011, 5, 5); | ||
var dr = moment.range(start, end); | ||
Exclude the end value: | ||
dr.toArray('days'); // [new Date(2011, 2, 5), new Date(2011, 3, 5), new Date(2011, 4, 5), new Date(2011, 5, 5)] | ||
``` js | ||
const range = moment.range('2012-01-01', '2015-01-01'); | ||
const acc = Array.from(range.reverseBy('years', { exclusive: true })); | ||
acc.map(m => m.format('YYYY')) // ['2015', '2014', '2013'] | ||
``` | ||
#### `toDate` | ||
By step: | ||
Converts the `DateRange` to an `Array` of the start and end `Date` objects. | ||
``` js | ||
const start = new Date(2012, 2, 2); | ||
const end = new Date(2012, 2, 6); | ||
const range1 = moment.range(start, end); | ||
``` javascript | ||
var start = new Date(2011, 2, 5); | ||
var end = new Date(2011, 5, 5); | ||
var dr = moment.range(start, end); | ||
let acc = Array.from(range1.reverseBy('day', { step: 2 })); | ||
dr.toDate(); // [new Date(2011, 2, 5), new Date(2011, 5, 5)] | ||
acc.map(m => m.format('DD')) // ['06', '04', '02'] | ||
acc = Array.from(range1.reverseBy('day', { exclusive: true, step: 2 })); | ||
acc.map(m => m.format('DD')) // ['06', '04'] | ||
``` | ||
#### `toString` | ||
#### reverseByRange | ||
Converting a `DateRange` to a `String` will format it as an [ISO 8601 time | ||
interval][interval]: | ||
``` js | ||
const start = new Date(2012, 2, 1); | ||
const two = new Date(2012, 2, 2); | ||
const end = new Date(2012, 2, 5); | ||
const range1 = moment.range(start, end); | ||
const range2 = moment.range(start, two); // One day | ||
``` | ||
``` javascript | ||
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)); | ||
Iterate by another range in reverse: | ||
range.toString() // "2015-01-17T09:50:04+00:00/2015-04-17T08:29:55+00:00" | ||
``` js | ||
const acc = Array.from(range1.by(range2)); | ||
acc.length == 5 // true | ||
acc.map(m => m.format('DD')) // ['05', '04', '03', '02', '01'] | ||
``` | ||
#### `valueOf` | ||
Exclude the end value: | ||
The difference between the end date and start date in milliseconds. | ||
``` js | ||
const acc = Array.from(range1.by(range2, { exclusive: true })); | ||
``` javascript | ||
var start = new Date(2011, 2, 5); | ||
var end = new Date(2011, 5, 5); | ||
var range = moment.range(start, end); | ||
acc.length == 4 // true | ||
acc.map(m => m.format('DD')) // ['05', '04', '03', '02'] | ||
``` | ||
range.valueOf(); // 7945200000 | ||
By step: | ||
``` js | ||
let acc = Array.from(range1.reverseByRange(range2, { step: 2 })); | ||
acc.map(m => m.format('DD')) // ['05', '03', '01'] | ||
acc = Array.from(range1.reverseByRange(range2, { exlusive, true, step: 2 })); | ||
acc.map(m => m.format('DD')) // ['05', '03'] | ||
``` | ||
### Center | ||
### Compare | ||
Calculate the center of a range | ||
Compare range lengths or add them together with simple math: | ||
``` javascript | ||
var start = new Date(2011, 2, 5); | ||
var end = new Date(2011, 3, 5); | ||
var dr = moment.range(start, end); | ||
``` js | ||
const range1 = moment.range(new Date(2011, 2, 5), new Date(2011, 3, 15)); | ||
const range2 = moment.range(new Date(1995, 0, 1), new Date(1995, 12, 25)); | ||
dr.center(); // 1300622400000 | ||
range2 > range1 // true | ||
range1 + range2 // duration of both ranges in milliseconds | ||
Math.abs(range1 - range2); // difference of ranges in milliseconds | ||
``` | ||
### Clone | ||
#### Equality | ||
Deep clone a range | ||
Check if two ranges are the same, i.e. their starts and ends are the same: | ||
``` javascript | ||
var start = new Date(2011, 2, 5); | ||
var end = new Date(2011, 3, 5); | ||
var dr = moment.range(start, end); | ||
``` js | ||
const range1 = moment.range(new Date(2011, 2, 5), new Date(2011, 3, 15)); | ||
const range2 = moment.range(new Date(2011, 2, 5), new Date(2011, 3, 15)); | ||
const range3 = moment.range(new Date(2011, 3, 5), new Date(2011, 6, 15)); | ||
var dr2 = dr.clone(); | ||
dr2.start.add(2, 'days'); | ||
range1.isSame(range2); // true | ||
range2.isSame(range3); // false | ||
dr2.start.toDate() === dr.start.toDate() // false | ||
range1.isEqual(range2); // true | ||
range2.isEqual(range3); // false | ||
``` | ||
#### Difference | ||
## Installation | ||
The difference of the entire range given various units. | ||
moment-range works in both the browser and [node.js][node]. | ||
Any of the units accepted by [moment.js' `add` method][add] may be used. | ||
### Node / NPM | ||
``` js | ||
const start = new Date(2011, 2, 5); | ||
const end = new Date(2011, 5, 5); | ||
const dr = moment.range(start, end); | ||
Install via npm: | ||
``` sh | ||
npm install moment-range | ||
dr.diff('months'); // 3 | ||
dr.diff('days'); // 92 | ||
dr.diff(); // 7945200000 | ||
``` | ||
And then `require` it: | ||
Optionally you may specify if the difference should be rounded, by default it | ||
mimics moment-js' behaviour and rounds the values: | ||
``` javascript | ||
var moment = require('moment'); | ||
require('moment-range'); | ||
``` js | ||
const d1 = new Date(Date.UTC(2011, 4, 1)); | ||
const d2 = new Date(Date.UTC(2011, 4, 5, 12)); | ||
const range = moment.range(d1, d2); | ||
dr.diff('days') // 4 | ||
dr.diff('days', false) // 4 | ||
dr.diff('days', true) // 4.5 | ||
``` | ||
### Browser | ||
`#duration` is an alias for `#diff` and they may be used interchangeably. | ||
Simply include moment-range after moment.js: | ||
### Conversion | ||
``` html | ||
<script src="moment.js"></script> | ||
<script src="moment-range.js"></script> | ||
#### `toDate` | ||
Converts the `DateRange` to an `Array` of the start and end `Date` objects. | ||
``` js | ||
const start = new Date(2011, 2, 5); | ||
const end = new Date(2011, 5, 5); | ||
const dr = moment.range(start, end); | ||
dr.toDate(); // [new Date(2011, 2, 5), new Date(2011, 5, 5)] | ||
``` | ||
Thanks to the fine people at [cdnjs][cdnjs], you can link to moment-range from | ||
the [cdnjs servers][cdnjs-moment-range]. | ||
#### `toString` | ||
### Bower | ||
Converting a `DateRange` to a `String` will format it as an [ISO 8601 time | ||
interval][interval]: | ||
``` sh | ||
bower install moment-range | ||
``` js | ||
const start = '2015-01-17T09:50:04+00:00'; | ||
const end = '2015-04-17T08:29:55+00:00'; | ||
const 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' | ||
``` | ||
**Note:** Include `moment-range` _after_ `moment`. | ||
#### `valueOf` | ||
The difference between the end date and start date in milliseconds. | ||
``` js | ||
const start = new Date(2011, 2, 5); | ||
const end = new Date(2011, 5, 5); | ||
const range = moment.range(start, end); | ||
range.valueOf(); // 7945200000 | ||
``` | ||
## Running Tests | ||
@@ -369,3 +576,3 @@ | ||
``` bash | ||
``` sh | ||
git clone https://git@github.com/gf3/moment-range.git | ||
@@ -376,3 +583,3 @@ ``` | ||
``` bash | ||
``` sh | ||
npm install | ||
@@ -383,6 +590,5 @@ ``` | ||
``` bash | ||
npm run-script build | ||
npm run-script test | ||
npm run-script jsdoc | ||
``` sh | ||
npm run test | ||
npm run lint | ||
``` | ||
@@ -395,7 +601,9 @@ | ||
[add]: http://momentjs.com/docs/#/manipulating/add/ | ||
[cdnjs]: https://github.com/cdnjs/cdnjs | ||
[cdnjs-moment-range]: https://cdnjs.com/libraries/moment-range | ||
[interval]: http://en.wikipedia.org/wiki/ISO_8601#Time_intervals | ||
[iterable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#Syntaxes_expecting_iterables | ||
[moment]: http://momentjs.com/ | ||
[node]: http://nodejs.org/ | ||
[unlicense]: http://unlicense.org/ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
595
52531
2
23
5
376
1
+ Addedexpect.js@^0.3.1
+ Addedexpect.js@0.3.1(transitive)