skip to Main Content

I’m trying to split the working time into working slots while excluding Break time.
We may have multiple working slots and multiple breaks but time could not overlap.

while excluding the break hours and splitting the working time.
To exclude the time slots Exclusion: True means exclude that time from the Exclusion: false object.

example: This is the array of objects with working hours and exclusion hours.

[
    {
       
        "startHours": "2023-07-13T01:00:44.000Z",
        "finishHours": "2023-07-13T13:00:08.000Z", 
        "exclusion": false
    },
    {
        
       
        "startHours": "2023-07-13T08:00:19.000Z",
        "finishHours": "2023-07-13T09:00:24.000Z",
        "exclusion": true
      
    },
    {
        
        
        "startHours": "2023-07-13T11:00:11.000Z",
        "finishHours": "2023-07-13T11:30:26.000Z",
        "exclusion": true
      
    }
]

And The output I want array of objects with updated working hours to display only working time slots.

[
    {
      
        "startHours": "2023-07-13T01:00:44.000Z",
        "finishHours": "2023-07-13T08:00:19.000Z",
    },
    {
        "startHours": "2023-07-13T09:00:24.000Z",
        "finishHours": "2023-07-13T11:00:26.000Z",
        
    },
    {
        "startHours": "2023-07-13T11:30:26.000Z",
        "finishHours": "2023-07-13T13:00:08.000Z",
        
    }
]

Then I am converting the time to display on the table like in the below example. This is for just understanding.
These are the working hours.

06:00-13:00
14:00-16:00 
16:30-18:00

2

Answers


  1. Converting strings to Date and vice versa, and comparing dates are all doable with Date objects, so I won’t get into that.

    If we remove that from the problem, it comes down to finding the segments out of this array:

    const myArray = [
      {
        start: 1,
        end: 100,
        excluded: false,
      },
      {
        start: 6,
        end: 15,
        excluded: true,
      },
      {
        start: 35,
        end: 50,
        excluded: true,
      },
    ];
    

    The entire solution can be long but this is roughly how you can do it:

    • Sort all start and end values. In the above example, it becomes 1, 6, 15, 35, 50, 100.
    • Determine if each segment in the series should be excluded or not.
    • Create a new array with that info.
    • Merge two adjacent segments with the same excluded flag.
    Login or Signup to reply.
  2. I provided explanation with comments. Bear in mind that the results could very depending on your timezone. You could specify a time zone to get the same results everywhere but I didn’t know that was needed.

    var input = [
        {
           
            "startHours": "2023-07-13T01:00:44.000Z",
            "finishHours": "2023-07-13T13:00:08.000Z", 
            "exclusion": false
        },
        {
            
           
            "startHours": "2023-07-13T08:00:19.000Z",
            "finishHours": "2023-07-13T09:00:24.000Z",
            "exclusion": true
          
        },
        {
            
            
            "startHours": "2023-07-13T11:00:11.000Z",
            "finishHours": "2023-07-13T11:30:26.000Z",
            "exclusion": true
          
        }
    ];
    
    
    // Create a new function to add hours easily
    Date.prototype.addHours= function(h){
        this.setHours(this.getHours()+h);
        return this;
    }
    
    // Function to split up an array into chunks
    function chunkArrayInGroups(arr, size) {
      var result = [];
      for (var i=0; i<arr.length; i+=size)
        result.push(arr.slice(i, i+size));
      return result;
    }
    
    // This could be diffferent in your region
    const differenceTimezone = 3
    
    // Let's split up the working times and breaks
    var workingHours = input.filter(time => !time.exclusion)
    var breaks = input.filter(time => time.exclusion)
    var times = []
    
    // We want to start & end of the day
    var start = new Date(workingHours[0].startHours).addHours(3).getHours().toString().padStart(2,'0') + ':' + '00'
    var end = new Date(workingHours[0].finishHours).addHours(3).getHours().toString().padStart(2,'0') + ':' + '00'
    
    times.push(start)
    
    // Get all the breaks
    breaks.forEach(b => {
      var start = new Date(b.startHours).addHours(3).getHours() + ':' + new Date(b.startHours).addHours(3).getMinutes().toString().padEnd(2,'0')
      var end = new Date(b.finishHours).addHours(3).getHours() + ':' + new Date(b.finishHours).addHours(3).getMinutes().toString().padEnd(2,'0')
      times.push(start,end)
    })
    
    times.push(end)
    
    // The end result
    var result = chunkArrayInGroups(times, 2).map((r) => { return r[0] + '-' + r[1]})
    
    console.log(result)
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search