Split a time range into pieces by other time ranges

前端 未结 3 768
灰色年华
灰色年华 2020-12-02 01:02

I have a complicated task that I have been beating my head against the wall now for a few days. I\'ve tried about 4 different approaches, however each seems to stall and it

3条回答
  •  攒了一身酷
    2020-12-02 01:23

    You need to do calculations of time-ranges. As the image shows this seems like a simple subtraction. It would be nice to just have objects that do these.

    I had no code for this ready, so the following concept is a bit rough although probably not that bad.

    A Range type that represents a time from-to. Those are as DateTime so that the benefits of these existing types can be used. I didn't use much of the benefits so far, however for the rest of the application this can make sense.

    The Range type already contains some basic comparison methods I thought were useful to do parts of the calculations.

    However as an object can not divide itself into two I also created a Ranges type which can represent one or more Ranges. This was necessary to have something that can be "divided".

    I cheated a little here because I implemented the difference calculation as a member of Range, returning an array with one or multiple Range objects. The final calculation then is just having a shift and substract the unavailable ranges from it:

    $shift = new Ranges(new DateTime('14:30:00'), new DateTime('18:30:00'));
    
    $unavailables = new Ranges([
        new Range(new DateTime('15:30:00'), new DateTime('16:30:00')),
        new Range(new DateTime('17:30:00'), new DateTime('18:30:00')),
    ]);
    
    $shift->subtract($unavailables);
    

    The shift then spans:

    14:30:00 - 15:30:00
    16:30:00 - 17:30:00
    

    Demo; Gist

    I can not say if it is worth the abstraction, what is nice with DateTime objects is that you can compare them with >, < and =. The real benefit from these classes might shed into light when you need more calculations between Range and Ranges. Maybe the interface is not sweet yet, however the basic calculations behind are outlined in the code already.

    One caveat: The difference between 14:00-15:00 and 14:00-15:00 in my code will result to 14:00-14:00. I keep the start time to not run empty, but you can run empty, too. The Ranges object should handle it nicely.

提交回复
热议问题