import toDate from '../toDate/index'
import requiredArgs from '../_lib/requiredArgs/index'
var MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000
/**
* @name getOverlappingDaysInIntervals
* @category Interval Helpers
* @summary Get the number of days that overlap in two time intervals
*
* @description
* Get the number of days that overlap in two time intervals
*
* ### v2.0.0 breaking changes:
*
* - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes).
*
* - The function was renamed from `getOverlappingDaysInRanges` to `getOverlappingDaysInIntervals`.
* This change was made to mirror the use of the word "interval" in standard ISO 8601:2004 terminology:
*
* ```
* 2.1.3
* time interval
* part of the time axis limited by two instants
* ```
*
* Also, this function now accepts an object with `start` and `end` properties
* instead of two arguments as an interval.
* This function now throws `RangeError` if the start of the interval is after its end
* or if any date in the interval is `Invalid Date`.
*
* ```javascript
* // Before v2.0.0
*
* getOverlappingDaysInRanges(
* new Date(2014, 0, 10), new Date(2014, 0, 20),
* new Date(2014, 0, 17), new Date(2014, 0, 21)
* )
*
* // v2.0.0 onward
*
* getOverlappingDaysInIntervals(
* { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },
* { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }
* )
* ```
*
* @param {Interval} intervalLeft - the first interval to compare. See [Interval]{@link docs/Interval}
* @param {Interval} intervalRight - the second interval to compare. See [Interval]{@link docs/Interval}
* @returns {Number} the number of days that overlap in two time intervals
* @throws {TypeError} 2 arguments required
* @throws {RangeError} The start of an interval cannot be after its end
* @throws {RangeError} Date in interval cannot be `Invalid Date`
*
* @example
* // For overlapping time intervals adds 1 for each started overlapping day:
* getOverlappingDaysInIntervals(
* { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },
* { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) }
* )
* //=> 3
*
* @example
* // For non-overlapping time intervals returns 0:
* getOverlappingDaysInIntervals(
* { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },
* { start: new Date(2014, 0, 21), end: new Date(2014, 0, 22) }
* )
* //=> 0
*/
export default function getOverlappingDaysInIntervals(
dirtyIntervalLeft,
dirtyIntervalRight
) {
requiredArgs(2, arguments)
var intervalLeft = dirtyIntervalLeft || {}
var intervalRight = dirtyIntervalRight || {}
var leftStartTime = toDate(intervalLeft.start).getTime()
var leftEndTime = toDate(intervalLeft.end).getTime()
var rightStartTime = toDate(intervalRight.start).getTime()
var rightEndTime = toDate(intervalRight.end).getTime()
// Throw an exception if start date is after end date or if any date is `Invalid Date`
if (!(leftStartTime <= leftEndTime && rightStartTime <= rightEndTime)) {
throw new RangeError('Invalid interval')
}
var isOverlapping =
leftStartTime < rightEndTime && rightStartTime < leftEndTime
if (!isOverlapping) {
return 0
}
var overlapStartDate =
rightStartTime < leftStartTime ? leftStartTime : rightStartTime
var overlapEndDate = rightEndTime > leftEndTime ? leftEndTime : rightEndTime
var differenceInMs = overlapEndDate - overlapStartDate
return Math.ceil(differenceInMs / MILLISECONDS_IN_DAY)
}