2016-11-10 3 views
2

У меня есть сотрудник, который должен служить 2 блюд каждого приема пищи может иметь разное время начала и различную продолжительностьCalculate часов работал с 2-х различных графиков с JavaScript

еды Мне нужно, чтобы получить общее время он работал, так скажем, одна еда составляет 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 
}] 
+0

что 1478787000000? какой тип единицы времени это? – repzero

+0

@repzero Milliseconds –

+0

Это метка javascript – sol

ответ

2

Ну, мое решение немного длительным. Возможно, код немного оптимизирован, но я думаю, что этот подход прав.

Вставьте здесь код, и вы можете проверить это jsfiddle, чтобы увидеть его работу. Откройте консоль, хотя.

Так вот код:

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/

2

// 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));