JavaScript Find Total Time Duration

Excluding overlapping and idle times

Talha Awan I'm open to new opportunities! For a full-time role, contract position, or freelance work, reach out at talha@talhaawan.net or LinkedIn.

Say we have a an array of objects with start and end times in each. This could be anything, ranging from work experience (the way LinkedIn shows per job), to education, to sports career. We want to sum all these small experiences, excluding overlapping and idle times, and give out the total duration, which can further be converted into years, months, or days.

Here’s the coded example with comments to understand the algorithm.

const getTotalExperienceInYears = (experience) => {

  // convert start & end strings to dates.
  // then sort by start date
  const sortedExperience =
    experience.map(e => ({
      ...e,
      startDate: new Date(e.startDate),
      endDate: new Date(e.endDate)
    }))
      .sort((a, b) => a.startDate - b.startDate);


  // this array will only have non-overlapping experiences
  // and each end start date difference
  const uniqueExperience = [];

  sortedExperience.forEach(ex => {
    // push if first, or non-overlapping
    if (!uniqueExperience.length
      || ex.startDate > uniqueExperience[uniqueExperience.length - 1].endDate) {
      uniqueExperience.push({
        startDate: ex.startDate,
        endDate: ex.endDate,
        diff: ex.endDate - ex.startDate
      });
    } // else last unique experience's endDate becomes the start date of new entry
    else if (ex.startDate < uniqueExperience[uniqueExperience.length - 1].endDate) {
      uniqueExperience.push({
        startDate:
          uniqueExperience[uniqueExperience.length - 1].endDate,
        endDate: ex.endDate,
        diff:
          ex.endDate - uniqueExperience[uniqueExperience.length - 1].endDate
      })
    }
  });


  const sumOfExperience =
    uniqueExperience.reduce((partialSum, a) => partialSum + a.diff, 0);

  const sumOfExperienceInYears =
    sumOfExperience / (1000 * 60 * 60 * 24 * 365);

  const yearsRoundedOff =
    Math.round((sumOfExperienceInYears + Number.EPSILON) * 100) / 100;

  return yearsRoundedOff;
}

For the above algorithm the assumption is that each experience object will have valid start and end dates and the key names are startDate & endDate.

The code can be run with the following example data:

const workExperience = [
  {
    title: "Software Internee",
    organization: "ABC",
    startDate: "2010-02-02",
    endDate: "2010-08-11",
  },
  {
    title: "Software Internee",
    organization: "DEF",
    startDate: "2010-07-20",
    endDate: "2011-01-15",
  },
  {
    title: "Associate Software Engineer",
    organization: "A",
    startDate: "2011-04-10",
    endDate: "2013-06-25",
  },
  {
    title: "Associate Software Engineer",
    organization: "B",
    startDate: "2013-06-01",
    endDate: "2014-06-01",
  },
  {
    title: "Software Engineer",
    organization: "B",
    startDate: "2014-06-02",
    endDate: "2016-06-01",
  },
  {
    title: "Senior Software Engineer",
    organization: "B",
    startDate: "2016-06-02",
    endDate: "2016-12-31",
  },
  {
    title: "Backend Team Lead",
    organization: "C",
    startDate: "2017-02-01",
    endDate: "2019-12-31",
  },
  {
    title: "Engineering Manager",
    organization: "D",
    startDate: "2019-12-01",
    endDate: "2022-06-08"
  },
];



console.log(
  getTotalExperienceInYears(workExperience)
);

// => 12.03

The total number of experience in our particular example, excluding overlaps and idle times, is around 12 years.

We can also use some library to further humanize the total duration information, for example: “8 years, 2 months”.




See also

When you purchase through links on techighness.com, I may earn an affiliate commission.
We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies. More info cookie script