如何从一系列日期范围中找到一个人的工作经验年限,工作日期可能重叠

How to find the years of work experience of a person from an array of date ranges, with potentially overlapping work dates

目标是使用 Javascript 从一个人工作经历的日期范围数组中唯一地计算一个人工作经历的总年数。有重叠的日期范围(意思是,此人在重叠期间有多个工作)。下面是一个例子,日期格式是 yyyy-mm-dd;

从上面的日期范围来看,存在重叠的工作日期。 正确计算此人的工作年限应该是20年。

我遇到的问题是创建一个算法,该算法可以考虑该人四个工作经历中的重叠时期,而不是将它们算作单独的工作年数,例如,只是总结四个工作经历中的每一个之间的年份工作日期给出了 48 年,这是不正确的(经验超过 20 年)。

var time_diff=0, yrs_diff=0;

var jobExperience = [
  {date_began:'2001-02-01', date_ended:'2009-03-01'},
  {date_began:'2004-06-01', date_ended:'2020-08-01'},
  {date_began:'2005-04-01', date_ended:'2021-03-01'},
  {date_began:'2008-07-01', date_ended:'2016-06-01'}
];
for(let i=0; i<jobExperience.length; i++){
  let date_1, date_2;
  let began = jobExperience[i].date_began.split('-');
  let ended = jobExperience[i].date_ended.split('-');
  date_1 = new Date(began[1]+'/'+began[2]+'/'+began[0]);
  date_2 = new Date(ended[1]+'/'+ended[2]+'/'+ended[0]);
  time_diff += date_2.getTime() - date_1.getTime();
}
yrs_diff = parseInt(time_diff/(1000 * 3600 * 24 * 365));
console.log(yrs_diff);

上面的代码段只是盲目地将每条工作历史记录之间的年份相加(这是不正确的)。我需要一些帮助的地方是关于如何总结每条工作历史记录之间的年份的线索或更好的伪代码或完整代码,但要考虑工作历史日期之间的重叠,这样做,重叠时期只计算一次。

这是一种“蛮力”方法。

  • 提取所有唯一年份
  • 排序
  • 找出最晚年份与最旧年份之间的差异

(假设数据集中的所有年份都属于一个字段;不同的字段不应该是同一个数据集的一部分)

例如:[2001, 2004, 2005, 2008, 2009, 2016, 2020, 2021] => 工作20年。

使用此方法的 警告 是它无法解释 months

相同的解决方案是 [不确定] 将月份转换为一年 (month/12) 并将其添加到前一年(如 2001 年 2 月 => 2001.166)。

另一个 警告 是它没有考虑到中间发生的任何中断。 (正如评论中指出的那样)。

这是我在评论中概述的方法:

对于每个时期,将开始日期和结束日期变成唯一的“月值”,然后将一个时期的所有月份值添加到一个集合中。
集合的大小是想要的月数:

const jobExperience = [
  { date_began: '2001-02-01', date_ended: '2009-03-01' },
  { date_began: '2004-06-01', date_ended: '2020-08-01' },
  { date_began: '2005-04-01', date_ended: '2021-03-01' },
  { date_began: '2008-07-01', date_ended: '2016-06-01' }
];

const months = new Set();

// convert date into unique integer month value based on year 1900
function m1900(yyyymmdd) {
  const [_, y, m, d] = yyyymmdd.match(/^(\d{4})-(\d{2})-(\d{2})$/).map(Number);
  return (y - 1900) * 12 + m;
}

jobExperience.forEach(job => {
  const m1 = m1900(job.date_began);
  const m2 = m1900(job.date_ended);
  for (let m = m1; m < m2; m++) months.add(m);
});
console.log("years:", months.size / 12);