简体   繁体   English

使用JavaScript计算2个不同时间表的工作时间

[英]Calculate hours worked from 2 different schedules with JavaScript

I have an employee that needs to serve 2 meals each meal can have a different start time and a different meal duration 我有一个员工需要每顿饭2顿饭,开始时间和进餐时间可能不同

I need to get the total time he worked, so let's say one meal is 60 minutes and another meal is also 60 minutes the total would be 120 minutes, but if the second meal started still in the time of the first meal it should be counted as one, so if the second meal started let's say 10 minutes after the first meal the total should be 70 min 我需要得到他工作的总时间,所以假设一顿饭是60分钟,另一顿饭也是60分钟,总共是120分钟,但是如果第二顿饭还是在第一顿饭的时间开始,那应该算在内因此,如果第二顿饭开始,假设第一顿饭后10分钟,总时间应为70分钟

var meals = [{
    "mealStartTime": 1478787000000, //9:00 AM
    "mealDuration": 60,
    "mealEndSearvingTime": 1478790600000
}, {
    "mealStartTime": 1478786400000, //9:10 AM
    "mealDuration": 60,    
    "mealEndSearvingTime": 1478790000000
}]

 // It might be a good idea to use a library like BigDecimal.js // to prevent any float point errors, or use momentjs to calculate // the distance between to times function msToMins(ms) { return ms / 1000.0 / 60.0; } // It's important to note that this algo assumes that: // * Two meals never start at the same time // * Meals always end after meals that started before them function timeWorked(meals) { // sort by start time const sortedMeals = meals.sort(m => m.mealStartTime); const result = meals.reduce((prev, curr) => { let duration = curr.mealDuration; // extract the current meal duration // if the previous meal overlaps with this one const mealsOverlap = prev.mealEndServingTime > curr.mealStartTime; if (mealsOverlap) { // calculate the distance when the previous end and this one ends // the previos meal duration was fully added in the previous cycle duration = msToMins(curr.mealEndServingTime - prev.mealEndServingTime); } // return the totalDuration accumulation, with the current meal return Object.assign({ totalDuration: prev.totalDuration + duration }, curr); }, { totalDuration: 0 }); // initialize with empty object return result.totalDuration; } const allMeals = [ { mealStartTime: 1478787000000, mealDuration: 60, mealEndServingTime: 1478790600000 }, { mealStartTime: 1478786400000, mealDuration: 60, mealEndServingTime: 1478790000000 } ]; console.log(timeWorked(allMeals)); 

Well, my solution is a bit lengthy. 好吧,我的解决方案有点冗长。 The code could probably be a bit optimized but I think the approach is right. 该代码可能会进行一些优化,但是我认为这种方法是正确的。

I'll paste the code here and you can check out this jsfiddle to see it work. 我将代码粘贴到此处,您可以查看此jsfiddle来查看其工作原理。 Open the console though. 虽然打开控制台。

So here's the code: 所以这是代码:

function getTotalWorkHours(meals){
    var punches = [], startCount = 0, endCount = 0, accountablePunchPairs = [], hoursWorked = 0;

  //// Populate an array of all punches ///
  meals.forEach(function(meal) {
    punches.push({
        type:'start',
      timestamp: meal.mealStartTime, 
      inEnglishPlease: new Date(meal.mealStartTime).toLocaleString()
    });
    punches.push({
        type: 'end',
      timestamp: meal.mealEndServingTime, 
      inEnglishPlease: new Date(meal.mealEndServingTime).toLocaleString()
    });
    });

  /// Sort the punches by time ///
  punches.sort(function(a, b){
    return a.timestamp - b.timestamp;
    });


  /// Filter out only the accountable punches.
  /// We will save the punches as an array of start/end pairs.
  /// Accountable punches are those that did not occur
  /// while the employee was busy with other meals
  punches.forEach(function(punch){
    if(punch.type === 'start'){
        if(++startCount - endCount === 1) accountablePunchPairs.push([punch]);
    }
    if(punch.type === 'end'){
        if(++endCount === startCount) {
        accountablePunchPairs[accountablePunchPairs.length-1][1] = punch;
      }
    }
  });

  /// Now just calculating the total hours based
  /// on the accountable punch pairs
  accountablePunchPairs.forEach(function(punchPair){
    hoursWorked += (punchPair[1].timestamp - punchPair[0].timestamp) / 3600000;
  });

  return hoursWorked;
}

https://jsfiddle.net/friedman5764/4nyv5um0/ https://jsfiddle.net/friedman5764/4nyv5um0/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM