I'm trying to get the overlapping months in two date intervals using date-fns:
const range1 = { start: new Date('2018-01-01'), end: new Date('2019-01-01') }
const range2 = { start: new Date('2018-07-03'), end: new Date('2019-12-01') }
getOverlappingMonthsInIntervals(a, b)) // 6
Looking at date-fns docs, I see the method getOverlappingDaysInIntervals
but no similar method for months. Is there a way to achieve this with date-fns or a workaround (other than getOverlappingDaysInIntervals/30
)
You can create your own overlapping months function using some of the other date-fns functions. See below for an example.
In my answer I make the assumption that two intervals have an overlapping month if both intervals span the entirety of that calendar month. Given your example ranges there are 5 overlapping months: August, September, October, November and December of 2018.
JFMAMJJASONDJFMAMJJASOND
1 |------+++++|
2 |+++++-----------|
areIntervalsOverlapping
function.differenceInCalendarMonths
(or,
differenceInMonths
) function for this.import {
areIntervalsOverlapping,
max,
min,
// differenceInMonths,
differenceInCalendarMonths,
} from 'date-fns'
const getOverlappingMonthsInterval = (r1, r2) => {
if (areIntervalsOverlapping(r1, r2)) {
const start = max([r1.start, r2.start])
const end = min([r1.end, r2.end])
return differenceInCalendarMonths(end, start) // or use `differenceInMonths`
} else return 0
}
const range1 = { start: new Date('2018-01-01'), end: new Date('2019-01-01') }
const range2 = { start: new Date('2018-07-01'), end: new Date('2019-12-01') }
console.log(getOverlappingMonthsInterval(range1, range2)) // 5
I like to use the conditional operator for functions like this:
// one-liner
const getOverlappingMonthsInterval = (r1, r2) =>
areIntervalsOverlapping(r1, r2)
? differenceInCalendarMonths(
min([r1.end, r2.end]),
max([r1.start, r2.start])
)
: 0