Note that there are some explanatory texts on larger screens.

plurals
  1. POCalculating time blocks from given date range
    text
    copied!<p>I'm trying to calculate time blocks from given date range. Here's my attempt:</p> <pre><code>&lt;?php class timeRangeCalculator { /** * Start time of block * * @var DateTime */ private $blockStart; /** * Block duration in seconds * * @var int */ private $blockDuration; /** * Start of range * * @var DateTime */ private $rangeStart; /** * End of range * * @var DateTime */ private $rangeEnd; /** * */ public function __construct() { if (!class_exists('DateTime')) { throw new Exception('Built-in DateTime class not found'); } } /** * Set whole time range * * @param DateTime $start * @param DateTime $end */ public function setRange(DateTime $start, DateTime $end) { if ($end &lt; $start) { throw new Exception('End cannot be before start'); } if ($start === $end) { throw new Exception('Start and end cannot be same'); } $this-&gt;rangeStart = $start; $this-&gt;rangeEnd = $end; return true; } /** * Set time block. Ignore year and month. * * @param DateTime $start * @param int $duration duration in seconds */ public function setBlock(DateTime $start, $duration) { if (!is_int($duration)) { throw new Exception('Duration is not integer'); } if ($duration &gt; 86400) { throw new Exception('Duration is over one day'); } $this-&gt;blockStart = $start; $this-&gt;blockDuration = $duration; return true; } /** * Calculate time blocks from range * * @return array Returns array of blocks */ public function calculate() { $result = array(); $rangeStart = $this-&gt;rangeStart; $blockStart = $this-&gt;blockStart; $blockDuration = $this-&gt;blockDuration; do { // Reset end range $rangeEnd = $this-&gt;rangeEnd; // Set block's starting date to range's start date $blockStart-&gt;setDate($rangeStart-&gt;format('Y'), $rangeStart-&gt;format('m'), $rangeStart-&gt;format('d')); $blockEnd = clone $blockStart; $blockEnd-&gt;modify("+$blockDuration seconds"); $rangeEnd-&gt;setDate($blockEnd-&gt;format('Y'), $blockEnd-&gt;format('m'), $blockEnd-&gt;format('d')); if ($rangeStart &lt; $blockStart) { $rangeStart-&gt;setTime($blockStart-&gt;format('G'), $blockStart-&gt;format('i'), $blockStart-&gt;format('s')); } if ($rangeEnd &gt; $blockEnd) { $rangeEnd-&gt;setTime($blockEnd-&gt;format('G'), $blockEnd-&gt;format('i'), $blockEnd-&gt;format('s')); } if ($rangeStart &lt; $rangeEnd) { $result[] = array($rangeStart, $rangeEnd); } // Full day after first iteration $rangeStart-&gt;setTime(0, 0, 0); $rangeStart-&gt;modify("+1 day"); } while ($blockEnd &lt;= $this-&gt;rangeEnd); return $result; } } </code></pre> <p>I can't quite get what kind of loop I should do in ::calculate().</p> <p>Test case:</p> <pre><code>&lt;?php $block_start = new DateTime("2000-01-01 22:00:00"); $block_range = 60 * 60 * 8; $ranges = array( array(new DateTime("2009-01-01 00:00:00"), new DateTime("2009-01-02 00:00:00")), array(new DateTime("2009-01-01 00:00:00"), new DateTime("2009-01-07 00:00:00")) ); $trc = new timeRangeCalculator(); $trc-&gt;setBlock($block_start, $block_range); foreach ($ranges as $idx =&gt; $rangeInfo) { list($start, $end) = $rangeInfo; echo "Range " . $start-&gt;format("j.n.Y H:i:s") . " - " . $end-&gt;format("j.n.Y H:i:s") . "&lt;br /&gt;"; $trc-&gt;setRange($start, $end); $result = $trc-&gt;calculate(); if(is_array($result) &amp;&amp; !empty($result)) { echo "Has block 22-06: &lt;br /&gt;"; foreach ($result as $block) { list($bs, $be) = $block; echo "* " . $bs-&gt;format("j.n.Y H:i:s") . " - " . $be-&gt;format("j.n.Y H:i:s") . "&lt;br /&gt;"; } } echo "&lt;br /&gt;"; } </code></pre> <p>PHP version is 5.2.6 so some DateTime stuff like ::diff() cannot be used.</p> <p><em>Edit</em>:</p> <p>So range is for example</p> <pre><code>================================ </code></pre> <p>Block is </p> <pre><code>####### </code></pre> <p>So blocks from ranges is for example</p> <pre><code>=====###=====###====....=====### ^ ^ ^ ^ | | | | | - end of block 1 | - end of block N - start of block 1 - start of block N </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload