2

我正在尝试使用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

查看 date-fns 文档,我看到了该方法getOverlappingDaysInIntervals,但几个月没有类似的方法。有没有办法通过 date-fns 或解决方法来实现这一点(除了getOverlappingDaysInIntervals/30

4

1 回答 1

5

您可以使用其他一些date-fns函数创建自己的重叠月份 函数。请参阅下面的示例。

在我的回答中,我假设如果两个时间间隔跨越整个日历月,则两个时间间隔有一个重叠的月份。给定您的示例范围,有 5 个重叠月份:2018 年 8 月、9 月、10 月、11 月和 12 月。

  JFMAMJJASONDJFMAMJJASOND
1 |------+++++|
2       |+++++-----------|
  1. 首先我们需要确定两个区间是否重叠。
  2. 如果两个间隔重叠,则确定间隔重叠的开始和结束日期。
    • 如果两个间隔重叠,则重叠开始日期将是 两个间隔开始日期中的最大值。并且,重叠结束日期将是 两个间隔结束日期中的最小值
    • 为此,我们可以使用maxandmin函数。
  3. 一旦我们找到重叠的开始和结束,我们需要确定这个间隔有多少个月。
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

我喜欢对这样的函数使用条件运算符:

// one-liner
const getOverlappingMonthsInterval = (r1, r2) =>
  areIntervalsOverlapping(r1, r2)
    ? differenceInCalendarMonths(
        min([r1.end, r2.end]),
        max([r1.start, r2.start])
      )
    : 0
于 2020-02-05T15:02:48.303 回答