moment-ranges
Fancy date ranges for Moment.js and moment-range.
Installation
moment-ranges works in both the browser and node.js.
Node / NPM
Install via npm:
// "moment-ranges" has two peer dependencies "moment" and "moment-range".npm install --save moment moment-range moment-ranges
ES6:
;;;;;
CommonJS:
const moment = ;const MomentRange = ;const MomentRanges = ;MomentRange;MomentRanges;
Browser
window'moment-range';window'moment-ranges';
Thanks to the fine people at cdnjs, you can link to moment-ranges from
the cdnjs servers.
Older browsers and IE11
This library makes use of Symbol.iterator
to provide the iteration
protocols now that there is broad support for them, if you need to support
older browsers (specifically IE11) you will need to include a polyfill. Any of
the following should work, depending on your project configuration:
Examples
Create
Create a date-ranges with date-range(s), and also sort and merge overlapping ranges:
const moment_a = 2009 1 8;const moment_c = 2012 3 7;const range_ac = moment;const moment_b = 2012 0 15;const moment_d = 2012 4 23;const range_bd = moment;const moment_e = 2019 10 26;const moment_f = 2019 11 3;const range_ef = moment;const ranges = moment;// => DateRanges [moment.range(moment_a, moment_d), moment.range(moment_e, moment_f)]// Arrays work too:const ranges = moment;
Because range_ac
overlaps with range_bd
, they merges into range_ad
.
range_ac [---------------------]range_bd [---------------------]range_ef [---------]ranges_ad_ef [--------------------------------] [---------] ...---------|----------|----------|----------|---|---------|---...moment a b c d e f
Inherit from Array
Date-Ranges is inherit from Array. So you can use any Array methods and attributes of Array:
const ranges = moment;// Print out all rangesranges// Filter out ranges duration more than 1 dayranges
Querying
Many of the following examples make use of these moments:
const moment_a = ;const moment_b = ;const moment_c = ;const moment_d = ;const range_ab = moment;const range_bc = moment;const range_cd = moment;const range_ad = moment;
Contains
Check to see if your date-ranges contains a date/moment/range. By default the start and end dates are included in the search. E.g.:
// Ranges-Rangeranges_ab_cd; // trueranges_ab_cd; // trueranges_ab_cd; // falseranges_ab_cd; // false// Ranges-Momentranges_ac; // true// Ranges-Rangesranges_ac; // true
ranges_ab_cd [----------] [----------] containsrange_ab [----------] => truerange_cd [----------] => truerange_bc [----------] => falserange_ad [--------------------------------] => false ranges_ad [--------------------------------] containsmoment_b | => trueranges_ab_cd [----------] [----------] => true ...---------|----------|----------|----------|---------...moment a b c d
You can also control whether the start or end dates should be excluded from the
search with the excludeStart
and excludeEnd
options:
// Ranges-Momentranges_ab_cd; // trueranges_ab_cd; // falseranges_ab_cd; // trueranges_ab_cd; // false// Ranges-Rangeranges_ab_cd; // false// Ranges-Rangesranges_ab_cd; // false
ranges_ab_cd [----------] [----------] containsmoment_c | => truemoment_b | => true ranges_ab_cd (----------] (----------] contains (exclude start)moment_c | => false ranges_ab_cd [----------) [----------) contains (exclude end)moment_b | => falserange_cd [----------] => falseranges_cd [----------] => false ...---------|----------|----------|----------|---------...moment a b c d
Note: You can obtain the same functionality by setting { excludeStart: true, excludeEnd: true }
Within
Find out if your moment or date-range falls within a date range:
b; // truerange_ac; // true
Overlaps
Does it overlap another range?
// Ranges-Rangesranges_ac; // true// Ranges-Rangeranges_ac; // true
ranges_ac (---------------------) overlapsranges_bd (---------------------) => truerange_bd (---------------------) => true ...---------|----------|----------|----------|---------...moment a b c d
Include adjacent ranges:
ranges_ac // trueranges_ac // falseranges_ac // true
ranges_ac (---------------------) overlapsrange_bc (----------) => truerange_cd (----------) => false ranges_ac [---------------------] overlaps (adjacent)range_cd [----------] => true ...---------|----------|----------|----------|---------...moment a b c d
Intersect
What is the intersecting range?
// Ranges-Rangeranges_ac; // DateRanges [moment.range(b, c)]// Ranges-Rangesranges_ac; // DateRanges [moment.range(b, c)]
ranges_ac [---------------------] intersectrange_bd(ranges_bd) [---------------------]↓↓ranges_bc [----------] ...---------|----------|----------|----------|---------...moment a b c d
IsRanges
Is it a Ranges?
moment; // truemoment; // false
Manipulation
Add
Add/combine/merge overlapping or adjacent ranges.
// Ranges-Rangeranges_ac; // DateRanges [moment.range(moment_a, moment_d)]// Merge into one date-range in date-ranges// Ranges-Rangesranges_cd; // DateRanges [moment.range(moment_a, moment_b), moment.range(moment_c moment_d)]// No merge but sorted
ranges_ac [---------------------] addrange_bd [---------------------]↓↓ranges_ad [--------------------------------] ranges_cd [----------] addranges_ab [----------]↓↓ranges_ab_cd [----------] [----------] ...---------|----------|----------|----------|---------...moment a b c d
Clone
Deep clone a ranges
const cloned_ranges_ab = ranges_ab;cloned_ranges_ab0start;cloned_ranges_ab0start === cloned_ranges_ab0start // false
ranges_ab [----------] clone↓↓cloned_ranges_ab [----------] ...---------|----------|---------...moment a b
Subtract
Subtracting one range from another ranges or range.
ranges_ad; // [moment.range(moment_a, moment_b) moment.range(moment_c, moment_d)]ranges_ac; // [moment.range(moment_a, moment_b)]ranges_ab; // [moment.range(moment_a, moment_b)]ranges_ab; // []
ranges_ad [--------------------------------] subtractrange_bc [----------]↓↓ranges_ab_cd [----------] [----------] ranges_ac [---------------------] subtractrange_bc [----------]↓↓ranges_ab [----------] ranges_ab [----------] subtractrange_bc [----------]↓↓ranges_ab [----------] ranges_ab [----------] subtractrange_ac [---------------------]↓↓ranges_empty ...---------|----------|----------|----------|---------...moment a b c d
Compare
Compare range lengths or whole ranges length. Or add them together with simple math:
const range1 = moment;const range2 = moment;const ranges1 = momentconst range3 = moment;const range4 = moment;const ranges2 = momentranges2 > ranges1 // trueranges2 > range3 // trueranges1 + ranges2 // duration of both ranges in millisecondsranges1 + range3 // duration of ranges and range in millisecondsMath; // difference of ranges in milliseconds
Equality
Check if two ranges are the same, i.e. their starts and ends are the same:
const range1 = moment;const range2 = moment;const range3 = moment;const range4 = moment;const range5 = moment;const range6 = moment;const ranges1 = momentconst ranges2 = momentconst ranges3 = momentranges1; // trueranges2; // falseranges1; // trueranges2; // false
Difference
The difference of the entire ranges given various units.
Any of the units accepted by moment.js' add
method may be used.
const start1 = 2011 2 5;const end1 = 2011 5 5;const range1 = moment;const start2 = 2014 3 5;const end2 = 2014 5 5;const range2 = moment;const ranges = moment;ranges; // 6ranges; // ?ranges; // ?
Optionally you may specify if the difference should not be truncated. By default it mimics moment-js' behaviour and truncates the values:
const d1 = Date;const d2 = Date;const range = moment;const ranges = moment;ranges // 4ranges // 4ranges // 4.75
#duration
is an alias for #diff
and they may be used interchangeably.
Conversion
toDate
Converts the DateRanges
to an Array
of Array
of the start and end Date
objects.
const range1 = moment;const range2 = moment;const ranges = moment;ranges;// [// [new Date(2011, 2, 5), new Date(2011, 5, 5)],// [new Date(2011, 3, 10), new Date(2011, 3, 20)]// ]
toString
Converting a DateRange
to a String
will format it as many ISO 8601 time
interval concatenated by comma:
const range1 = moment;const range2 = moment;const ranges = momentranges// "2015-01-17T09:50:04+08:00/2015-04-17T08:29:55+08:00,2015-03-10T02:70:04+08:00/2015-03-20T07:56:51+08:00"
valueOf
The difference between the end date and start date in milliseconds.
const range1 = moment;const range2 = moment;const ranges = moment;range1; // 7945200000range2; // 864000000ranges; // 8809200000// 7945200000 + 864000000 = 8809200000
Running Tests
Clone this bad boy:
git clone https://git@github.com/rotaready/moment-ranges.git
Install the dependencies:
yarn install
Do all the things!
yarn run checkyarn run testyarn run lint
Contributors
Contributors of moment-range
Many thanks to these contributors. They built the predecessor of this project.
- Gianni Chiappetta (https://butt.zone) (Author of [moment-range][moment-range])
- Adam Biggs (http://lightmaker.com)
- Mats Julian Olsen
- Matt Patterson (http://reprocessed.org/)
- Wilgert Velinga (http://neocles.io)
- Tomasz Bak (http://twitter.com/tomaszbak)
- Stuart Kelly
- Jeremy Forsythe
- Александр Гренишин
- @scotthovestadt
- Thomas van Lankveld
- nebel
- Kevin Ross (http://www.alienfast.com)
- Thomas Walpole
- Jonathan Kim (http://jkimbo.co.uk)
- Tymon Tobolski (http://teamon.eu)
- Aristide Niyungeko
- Bradley Ayers
- Ross Hadden (http://rosshadden.github.com/resume)
- Victoria French
- Jochen Diekenbrock
License
moment-ranges is MIT license.