3v4l.org

run code in 200+ php & hhvm versions
Bugs & Features
<?php class Period { protected $start; protected $end; public function __construct($start, $end) { $this->start = $start; $this->end = $end; } public function getStart() { return $this->start; } public function getEnd() { return $this->end; } public function containsTime($time) { return $this->start <= $time && $this->end > $time; } public function containsPeriod(Period $period) { return $this->containsTime($period->getStart()) && $this->containsTime($period->getEnd()); } public function overlaps(Period $period) { return $this->containsTime($period->getStart()) || $this->containsTime($period->getEnd()) || $period->containsTime($this->start); } public function intersect(Period $other) { $ts = $this->start; $os = $other->start; $te = $this->end; $oe = $other->end; if ($this->containsTime($os)) { $start = $os; } else if ($other->containsTime($ts)) { $start = $ts; } else { return null; } if ($this->containsTime($oe)) { $end = $oe; } else if ($other->containsTime($te)) { $end = $te; } else { return null; } return new Period($start, $end); } } class Availability { protected $periods; public function __construct($periods) { $this->periods = $periods; } public function getPeriods(Period $range) { return array_filter($this->periods, function ($period) use ($range) { return $range->intersect($period); }); } } function st($s) { return strtotime($s); } function pd($s1, $s2) { return new Period(st($s1), st($s2)); } function av() { $p = func_get_args(); $p = array_map(function ($p) { return pd($p[0], $p[1]); }, $p); return new Availability($p); } function sTime($time) { return date('j.M.H:i:s', $time); } function strPeriod(Period $period) { return sprintf('%s - %s', sTime($period->getStart()), sTime($period->getEnd())); } function strResults($periods) { return implode(PHP_EOL, array_map('strPeriod', $periods)); } $availabilities = [ av( // Fridays between noon and 6pm ['2018-10-05 12:00:00', '2018-10-05 18:00:00'], ['2018-10-12 12:00:00', '2018-10-12 18:00:00'], ['2018-10-19 12:00:00', '2018-10-19 18:00:00'], ['2018-10-26 12:00:00', '2018-10-26 18:00:00'] ), av( // Mon 15th till Fri 19th full days ['2018-10-15 00:00:00', '2018-10-16 00:00:00'], ['2018-10-16 00:00:00', '2018-10-17 00:00:00'], ['2018-10-17 00:00:00', '2018-10-18 00:00:00'], ['2018-10-18 00:00:00', '2018-10-19 00:00:00'], ['2018-10-19 00:00:00', '2018-10-20 00:00:00'] ), av( // Wed 10th, Fri 19th and Wed 24th between 8am and 2pm ['2018-10-10 08:00:00', '2018-10-10 14:00:00'], ['2018-10-19 08:00:00', '2018-10-19 14:00:00'], ['2018-10-24 08:00:00', '2018-10-24 14:00:00'] ), ]; // Get periods for the whole month of October $periods = [ pd('2018-10-01 00:00:00', '2018-11-01 00:00:00') ]; foreach ($availabilities as $i => $avail) { printf('Availability #%d' . PHP_EOL, $i); $tPeriods = []; foreach ($periods as $period) { printf(' > Getting available periods in %s'.PHP_EOL, strPeriod($period)); $aPeriods = $avail->getPeriods($period); printf(' > Got %d periods'.PHP_EOL, count($aPeriods)); $tPeriods = array_merge($tPeriods, $aPeriods); } $periods = $tPeriods; echo str_repeat('-', 80) . PHP_EOL; } echo 'RESULTS:' . PHP_EOL; echo strResults($periods);
Output for 7.3.0rc3
Availability #0 > Getting available periods in 1.Oct.00:00:00 - 1.Nov.00:00:00 > Got 4 periods -------------------------------------------------------------------------------- Availability #1 > Getting available periods in 5.Oct.12:00:00 - 5.Oct.18:00:00 > Got 0 periods > Getting available periods in 12.Oct.12:00:00 - 12.Oct.18:00:00 > Got 0 periods > Getting available periods in 19.Oct.12:00:00 - 19.Oct.18:00:00 > Got 1 periods > Getting available periods in 26.Oct.12:00:00 - 26.Oct.18:00:00 > Got 0 periods -------------------------------------------------------------------------------- Availability #2 > Getting available periods in 19.Oct.00:00:00 - 20.Oct.00:00:00 > Got 1 periods -------------------------------------------------------------------------------- RESULTS: 19.Oct.08:00:00 - 19.Oct.14:00:00