3v4l.org

run code in 300+ PHP versions simultaneously
<?php error_reporting(E_ALL); ini_set('display_startup_errors', 1); ini_set('display_errors', 1); function getFillNotion(\DateTimeImmutable $fillStart, \DateTimeImmutable $fillEnd, \DateTimeInterface $gapStart, \DateTimeInterface $gapEnd) { //$gapInterval = $gapStart->diff($gapEnd); // Doesn't work $gapInterval = new \DateInterval('PT'.($gapEnd->getTimestamp() - $gapStart->getTimestamp()).'S'); if($gapStart > $fillStart) { //The fill is older than the gap so make the fill's endTime match the gap's endTime $fillEndModified = $fillEnd ->modify('previous '.$gapEnd->format('D')) ->setTime(...explode('.', $gapEnd->format('H.i.s.u'))); if($fillEndModified->diff($fillEnd)->format('%a') >= 7) { $fillEndModified = $fillEndModified->add(new \DateInterval('P7D')); } $fillStartModified = $fillEndModified->sub($gapInterval); if($fillStartModified < $fillStart) { return []; } } else { //The fill is newer than the gap so make the fill's startTime match the gap's startTime $fillStartModified = $fillStart ->modify('next '.$gapStart->format('D')) ->setTime(...explode('.', $gapStart->format('H.i.s.u'))); if($fillStart->diff($fillStartModified)->format('%a') >= 7) { $fillStartModified = $fillStartModified->sub(new \DateInterval('P7D')); } $fillEndModified = $fillStartModified->add($gapInterval); if($fillEndModified > $fillEnd) { return []; } } return [$fillStartModified, $fillEndModified]; } function getFillRequinix(\DateTime $fillStart, \DateTime $fillEnd, \DateTime $gapStart, \DateTime $gapEnd) { // // being with the original start $fillStartModified = clone $fillStart; // move to the next weekday and time $wdtStart = $gapStart->format("l H:i:s"); if ($fillStartModified->format("l H:i:s") != $wdtStart) { $fillStartModified->modify("next {$wdtStart}"); } // get the duration, minus a bit so we can do a "next <day>" after $days = $gapStart->diff($gapEnd)->days - 1; // get the weekday and time $wdtEnd = $gapEnd->format("l H:i:s"); // update $fillEndModified = clone $fillStartModified; $fillEndModified->modify("+${days} days"); $fillEndModified->modify("next {$wdtEnd}"); return $fillStartModified < $fillStart || $fillEndModified > $fillEnd?[]:[$fillStartModified, $fillEndModified]; } function isDifferent(?DateTimeInterface $requinix, $notion) { if($requinix xor $notion) { return true; } elseif(!$requinix && !$notion) { return false; } else { return $requinix->getTimestamp() !== $notion->getTimestamp(); } } /* Fill Sunday 2019-02-17 08:09:53 -> Saturday 2019-04-06 19:09:48 Gap Sunday 2019-04-14 20:33:00 -> Tuesday 2019-05-28 10:05:28 */ $max = 800*24*60*60; $int = 80*24*60*60; $score = ['requinix'=>0, 'notion'=>0, 'tie'=>0, 'nofill'=>0]; for ($i = 0; $i < 10000; $i++) { $fillEnd = time()-rand(0, $max); $fillStart = $fillEnd-rand(0, $int); $gapEnd = time()-rand(0, $max); $gapStart = $gapEnd-rand(0, $int); $fillEnd = new DateTime("@$fillEnd"); $fillStart = new DateTime("@$fillStart"); $gapEnd = new DateTime("@$gapEnd"); $gapStart = new DateTime("@$gapStart"); $fillRequinix = getFillRequinix($fillStart, $fillEnd, $gapStart, $gapEnd); $fillNotion = getFillNotion(DateTimeImmutable::createFromMutable( $fillStart ), DateTimeImmutable::createFromMutable( $fillEnd ), $gapStart, $gapEnd); if($fillRequinix && $fillNotion) { $gapStartTimestamp = $gapStart->getTimestamp(); $fillRequinixOffset = abs($gapStartTimestamp - $fillRequinix[0]->getTimestamp()); $fillNotionOffset = abs($gapStartTimestamp - $fillNotion[0]->getTimestamp()); if($fillRequinixOffset === $fillNotionOffset) { $score['tie']++; } elseif($fillRequinixOffset<$fillNotionOffset) { $score['requinix']++; } else { $score['notion']++; } } elseif($fillRequinix) { $score['requinix']++; } elseif($fillNotion) { $score['notion']++; } else { $score['nofill']++; } } $score['total'] = array_sum($score); print_r($score);

preferences:
36.2 ms | 402 KiB | 5 Q