fork(4) download
  1. <?php
  2.  
  3. $opening_hours = [['08:00','12:00'], ['14:00','18:00']];
  4. $occupied_slots = [['09:30','11:00'], ['15:10','16:35']];
  5. $expected_result = [['08:00','09:30'], ['11:00','12:00'], ['14:00','15:10'], ['16:35','18:00']];
  6. $valid_timeslots = [];
  7.  
  8. #find empty timeslots during opening hours given occupied slots
  9.  
  10. function timeToNum($time) {
  11. preg_match('/(\d\d):(\d\d)/', $time, $matches);
  12. return 60*$matches[1] + $matches[2];
  13. }
  14.  
  15. function numToTime($num) {
  16. $m = $num%60;
  17. $h = intval($num/60) ;
  18. return ($h>9? $h:"0".$h).":".($m>9? $m:"0".$m);
  19.  
  20. }
  21.  
  22. // substraction interval $b from interval $a
  23. function sub($a,$b)
  24. {
  25. // case A: $b inside $a
  26. if($a[0]<=$b[0] and $a[1]>=$b[1]) return [ [$a[0],$b[0]], [$b[1],$a[1]] ];
  27.  
  28. // case B: $b is outside $a
  29. if($b[1]<=$a[0] or $b[0]>=$a[1]) return [ [$a[0],$a[1]] ];
  30.  
  31. // case C: $a inside $b
  32. if($b[0]<=$a[0] and $b[1]>=$a[1]) return [[0,0]]; // "empty interval"
  33.  
  34. // case D: left end of $b is outside $a
  35. if($b[0]<=$a[0] and $b[1]<=$a[1]) return [[$b[1],$a[1]]];
  36.  
  37. // case E: right end of $b is outside $a
  38. if($b[1]>=$a[1] and $b[0]>=$a[0]) return [[$a[0],$b[0]]];
  39. }
  40.  
  41. // flat array and change numbers to time and remove empty (zero length) interwals e.g. [100,100]
  42. // [[ [167,345] ], [ [433,644], [789,900] ]] to [ ["07:00","07:30"], ["08:00","08:30"], ["09:00","09:30"] ]
  43. // (number values are not correct in this example)
  44. function flatAndClean($interwals) {
  45. $result = [];
  46. foreach($interwals as $inter) {
  47. foreach($inter as $i) {
  48. if($i[0]!=$i[1]) {
  49. //$result[] = $i;
  50. $result[] = [numToTime($i[0]), numToTime($i[1])];
  51. }
  52. }
  53. }
  54. return $result;
  55. }
  56.  
  57. // calculate new_opening_hours = old_opening_hours - occupied_slot
  58. function cutOpeningHours($op_h, $occ_slot) {
  59. foreach($op_h as $oh) {
  60. $ohn = [timeToNum($oh[0]), timeToNum($oh[1])];
  61. $osn = [timeToNum($occ_slot[0]), timeToNum($occ_slot[1])];
  62. $subsn[] = sub($ohn, $osn);
  63. }
  64. return $subsn;
  65. }
  66.  
  67.  
  68. $oph = $opening_hours;
  69. foreach($occupied_slots as $os) {
  70. $oph = flatAndClean(cutOpeningHours($oph, $os ));
  71. }
  72.  
  73. $valid_timeslots = $oph;
  74.  
  75. var_dump(json_encode(["result"=>$valid_timeslots]));
  76.  
Success #stdin #stdout 0s 82624KB
stdin
Standard input is empty
stdout
string(84) "{"result":[["08:00","09:30"],["11:00","12:00"],["14:00","15:10"],["16:35","18:00"]]}"