检查日期期间是否与数组中的任何给定期间重叠

Check if period of date, is overlapping any of the given period in the array

我有一个销售人员模块,他们可以在其中添加自己的经理。这些将显示在 UI 的 ag-grid 中。要添加经理,我需要 select 给定经理的经理、期间开始日期和期间结束日期。但同时我还需要检查每个经理的时期,任何经理的日期都不应相互重叠,在此基础上确定状态。一个销售人员可以有 N 个经理,但每个销售人员一次只能有一个 Active 经理。

我目前在比较当前经理与数组中每个给定经理的日期时遇到问题。

我根据以下代码判断状态:

decideStatus(): string {
    let status = '';
    let currentDate = new Date();
    let fromDate = this.salesPersonForm.value.StartDate;
    let tillDate = this.salesPersonForm.value.EndDate;

    if(fromDate <= currentDate && (tillDate > currentDate || tillDate == null)) {
      return status = 'Active'
    } else if(fromDate > currentDate) {
      return status = 'Onhold'
    } else if(tillDate < currentDate) {
      return status = 'Inactive'
    }
  }

我有以下代码用于将管理器添加到网格。

addManagers(){
    if(this.salesPersonForm.value.SalesPerson) {
      if(this.salesPersonForm.value.StartDate) {
        if(this.salesPersonForm.value.EndDate == null || (this.salesPersonForm.value.EndDate > this.salesPersonForm.value.StartDate)) {
          let loggedInUser = userName;
          let manager = {
            Name: someName
            FromDate: this.salesPersonForm.value.StartDate 
            TillDate: this.salesPersonForm.value.EndDate 
            CreatedAt: new Date()
            CreatedBy: loggedInUser,
            Status: this.decideStatus()
          }
          this.managers.push(manager)
        } else {
          return;
        }
      } else {
        return;
      }
    } else {
      return
    }
    this.clear();
    setTimeout(() => {
      this.agGridReference.assignData(this.managers)
    }, 200);
  }

空闲用例:M1 - 2020 年 1 月 1 日至 2020 年 6 月 31 日 - 不活动 M2 - 01/08/2020 至 31/12/2021 - 停用 M3 - 01/01/2022 到某个未来值 - 活跃

如果日期比当前日期晚,将被视为暂停。

无效案例:M1 - 2020 年 1 月 1 日至 2020 年 6 月 31 日 - 无效 M2 - 01/05/2020 至 28/02/2021 - 停用 M3 - 2021 年 1 月 1 日至 2021 年 5 月 30 日 - 不活跃

好的,所以只有当新经理的间隔不与任何现有经理的间隔重叠时,您才将新经理推入 managers 数组。因此,需要在 this.managers.push(manager) 行之前进行检查,如下所示:

  • this.managers.push(manager) 替换为: this.compareDates(manager);

  • 添加这两个方法:

compareDates(newM) {
    let overlaps = 0;
    this.managers.forEach(m => {
      if (
        // first case:
        // saved manager starts before FromDate
        // and finishes after FromDate
        // of new manager:
        (this.prepareDate(m.FromDate) <= this.prepareDate(newM.FromDate) &&
          this.prepareDate(m.TillDate) >= this.prepareDate(newM.FromDate)) ||
        // second case:
        // saved manager starts after FromDate
        // and before the TillDate
        // of new manager:
        (this.prepareDate(m.FromDate) >= this.prepareDate(newM.FromDate) &&
          this.prepareDate(m.FromDate) <= this.prepareDate(newM.TillDate))
      ) {
        overlaps++;
      }
    });
    if (overlaps == 0) {
      // no overlaps, so push this new manager and do whatever else needs to be done
      this.managers.push(newM);
      console.log('Welcome, new manager!');
    } 
    else {
      // there is at least 1 overlap, so do something else
      // like: return with error message  
      console.log("This manager's interval overlaps with interval(s) of " 
      + overlaps +' other manager(s)!'
      );
    }
  }

以及前一个方法中每个日期的 return 时间戳的辅助方法:

prepareDate(date) {
    let parts = date.split('/');
    return Date.parse(parts[2] + '/' + parts[1] + '/' + parts[0]);
}

查看实际效果:https://stackblitz.com/edit/angular-ivy-j9ldef