phpzend-frameworkzend-date

Split time by day of the week with an interval defined by two Zend_Date


I have two Zend_Date that represent an interval :

$start = new Zend_Date($punch->getStart());
$end = new Zend_Date($punch->getEnd());

$nbHours = $start->sub($end , Zend_Date::HOUR);
$nbMinutes = $start->sub($end , Zend_Date::MINUTE);

$hoursTotal = $nbHours->get(Zend_Date::HOUR);
$minutesTotal = $nbMinutes->get(Zend_Date::MINUTE);

Is there an simple way to split the interval by day of the week with Zend_Date when the interval > 24 hours?

For example, if I have an interval from Monday 8am to Tuesday 4:30pm, I would like to have an array containing monday = 16h and tuesday = 16:30.


Solution

  • You don't need to use Zend_Date for this, in fact it is probably better not to. You should use the date/time classes in PHP instead.

    If I understand your question correctly you want an array of days and the hours worked for those days.

    I first created a mock class to reflect your code example, I have assumed it is returning timestamps:-

    class Punch
    {
        public function getStart()
        {
            return time();
        }
    
        public function getEnd()
        {
            return strtotime('+36 hours 45 minutes');
        }
    }
    

    Then we set up the DateTime objects-

    $Punch = new Punch();
    $start = new DateTime();
    $start->setTimestamp($Punch->getStart());
    $end = new DateTime();
    $end->setTimestamp($Punch->getEnd());
    

    Then we use a DateInterval object to generate our iterable DatePeriod:-

    $interval = new DateInterval('PT1M');
    $minutes = new DatePeriod($start, $interval, $end);
    

    Then we simply iterate over it counting the minutes worked in each day:-

    $format = 'l';
    foreach($minutes as $minute){
        if(!isset($result[$minute->format($format)])) $result[$minute->format($format)] = 0;
        $result[$minute->format($format)]++;
    }
    

    See the manual page for acceptable formats.

    We now have the number of minutes worked in each day, converting them to hours is trivial:-

    foreach($result as $key => $r){
        $result[$key] = $r/60;
    }
    var_dump($result);
    

    Output (Obviously, you will get a different result running it at a different time) :-

    array
      'Monday' => float 17.483333333333
      'Tuesday' => float 19.266666666667
    

    So on Monday 17.48 hours were worked and 19.27 on Tuesday.

    Alternatively:-

    foreach($result as $key => $r){
        $result[$key] = floor($r/60) . ':' . $r % 60;
    }
    

    Would give the following output if that is closer to what you want:-

    array
      'Monday' => string "17:29"
      'Tuesday' => string "19:16"
    

    That's the simplest way I can think of doing it.