------------------------------------------------------------------------------- $Id$ -----------------------------------------------------------------------------*/ require_once 'MLIB/Tiempo/Hora.php'; /** * Representa un Intervalo entre 2 horas del mismo dia * * @package HE * @version $Rev$ * @author Gonzalo Merayo */ class MLIB_Tiempo_Intervalo { /** * * Hora de inicio del intervalo * * @var object Hora */ var $inicio; /** * * Hora de fin del intervalo * * @var object Hora */ var $fin; /** * Constructor. * * @param Hora $inicio Hora de inicio (por defecto cero). * @param Hora $fin Hora de fin (por defecto cero). * @param bool $chequear Invierte el intervalo si la hora de * fin es anterior a la de inicio. * */ function MLIB_Tiempo_Intervalo($inicio = null, $fin = null, $chequear = true) { if (!$inicio) { $inicio = new MLIB_Tiempo_Hora; } if (!$fin) { $fin = new MLIB_Tiempo_Hora; } $this->inicio = $inicio; $this->fin = $fin; if ($chequear) { $this->_chequear(); } } function _chequear() { $a = $this->fin; if($a->lower($this->inicio)) { $tmp = $this->fin; $this->fin = $this->inicio; $this->inicio = $tmp; } } function invertido() { return $this->fin->lower($this->inicio); } function setInicio($inicio) { $this->inicio = $inicio; $this->_chequear(); } /** * * setFin * * @param var $fin * */ function setFin($fin) { $this->fin = $fin; $this->_chequear(); } function getDuracion() { $c = new MLIB_Tiempo_Hora; $c->copy($this->fin); $c->subtract($this->inicio); return $c; } /** * Chequea si el intervalo se superpone con otros. * @param $intervalos Intervalo o array de Intervalo con los cuales chequear. * @return true si se superpone con uno o más intervalos. */ function seSuperpone($intervalos) { if (!is_array($intervalos)) { $intervalos = array($intervalos); } foreach ($intervalos as $i) { if ($i->fin->greater($this->inicio) && $this->fin->greater($i->inicio)) { return true; } if ($this->fin->greater($i->inicio) && $i->fin->greater($this->inicio)) { return true; } } return false; } /** * Chequea si el intervalo es adyacente a otro. * Ejemplo: *
     *       A            B
     * |-----------|------------|  Adyacentes
     *
     *       A              B
     * |-----------|   |--------|  No adyacentes
     * 
* @param $intervalo Intervalo con el cual chequear. * @return true si se son adyacentes. */ function esAdyacente($intervalo) { if ($intervalo->fin->equal($this->inicio) || $this->fin->equal($intervalo->inicio)) { return true; } return false; } function fusionar($i) { if (!$this->seSuperpone($i) && !$this->esAdyacente($i)) { return false; } if ($i->fin->greater($this->fin)) { $this->fin = $i->fin; } if ($i->inicio->lower($this->inicio)) { $this->inicio = $i->inicio; } return true; } function superponer($i) { $inicio = $this->inicio; $fin = $this->fin; if ($this->inicio->lower($i->inicio)) { $inicio = $i->inicio; } if ($this->fin->greater($i->fin)) { $fin = $i->fin; } $fin->subtract($inicio); return $fin; } /** * Corta un intervalo, devolviendo el intervalo previo al punto de corte. * El intervalo actual queda con el intervalo posterior al punto de corte. * El punto de corte puede ser tanto una hora como un intervalo. * * @param mixed $c Donde cortar. * * @return object Intervalo Intervalo anterior al punto de corte. */ function cortar($c) { if(is_a($c, 'MLIB_tiempo_hora')) { return $this->cortarHora($c); } elseif (is_a($c, 'MLIB_tiempo_intervalo')) { return $this->cortarIntervalo($c); } else { return false; } } /** * Corta un intervalo, devolviendo el intervalo previo a la hora de corte. * El intervalo actual queda con el intervalo posterior a la hora de corte. * * @param mixed $h Donde cortar. * * @return object Intervalo Intervalo anterior a la hora de corte. */ function cortarHora($h) { $class = get_class($this); $r = new $class; $r->copy($this); if($this->inicio->greater($h)) { $r->setFin($r->inicio); return $r; } if($this->fin->lowerEqual($h)) { $this->setInicio($this->fin); } else { $this->setInicio($h); $r->setFin($h); } return $r; } /** * Corta un intervalo, devolviendo el intervalo previo al intervalo de corte. * El intervalo actual queda con el intervalo posterior al intervalo de corte. * * @param mixed $i Donde cortar. * * @return object Intervalo Intervalo anterior al intervalo de corte. */ function cortarIntervalo($i) { $ant = $this->cortarHora($i->inicio); $this->cortarHora($i->fin); return $ant; } function toString() { return 'inicio: ' . $this->inicio->format() . ' | fin: ' . $this->fin->format(); } function copy($i) { $this->inicio = $i->inicio->__clone(); $this->fin = $i->fin->__clone(); return true; } function __clone() { $class = get_class($this); $i = new $class; $i->copy($this); return $i; } } ?>