X-Git-Url: https://git.llucax.com/mecon/meconlib.git/blobdiff_plain/71acf4950362871b3ad6bc168d08db422edf0509..c0cc0ddabd54d39b68079ef97f414b799211aa67:/lib/MECON/Tiempo/Intervalo.php diff --git a/lib/MECON/Tiempo/Intervalo.php b/lib/MECON/Tiempo/Intervalo.php index d69d534..0cc2068 100644 --- a/lib/MECON/Tiempo/Intervalo.php +++ b/lib/MECON/Tiempo/Intervalo.php @@ -4,12 +4,12 @@ meconlib ------------------------------------------------------------------------------- This file is part of meconlib. - + meconlib is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + meconlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -33,207 +33,237 @@ require_once 'MECON/Tiempo/Hora.php'; * @version $Rev$ * @author Gonzalo Merayo */ -class 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 Intervalo( $inicio = null, $fin = null, $chequear = true ) { - if (is_null($inicio)) $inicio = new Hora; - if (is_null($fin)) $fin = new Hora; - if(!is_a($inicio, 'hora')) return false; - if(!is_a($fin, 'hora')) return false; - $this->inicio = $inicio; - $this->fin = $fin; - if ($chequear) { +class MECON_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 MECON_Tiempo_Intervalo($inicio = null, $fin = null, $chequear = true) + { + if (!$inicio) { + $inicio = new MECON_Tiempo_Hora; + } + if (!$fin) { + $fin = new MECON_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 _chequear() - { - $a = $this->fin; - if($a->lower($this->inicio)) + function getDuracion() + { + $c = new MECON_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) { - $tmp = $this->fin; - $this->fin = $this->inicio; - $this->inicio = $tmp; - } - } - - function invertido() - { - return $this->fin->lower($this->inicio); - } - - function setInicio( $inicio ) { - if(! is_a($inicio, "hora")) return false; - $this->inicio = $inicio; - $this->_chequear(); - } - - /** - * - * setFin - * - * @param var $fin - * - */ - function setFin( $fin ) - { - if(! is_a($fin, "hora")) return false; - $this->fin = $fin; - $this->_chequear(); - } - - function getDuracion() - { - $c = new Hora; - $c->copy($this->fin); - $c->subtract($this->inicio); - return $c; - } - - // XXX - Amplié el método para comparar con varios intervalos a la vez, - // si el argumento no es un array, anda de todas maneras. - function seSuperpone( $intervalos ) - { - if (!is_array($intervalos)) $intervalos = array($intervalos); - foreach ($intervalos as $i) { - if (is_a($i, "intervalo")) { - if ($i->fin->greaterEqual($this->inicio) && - $this->fin->greaterEqual($i->inicio)) return true; - if ($this->fin->greaterEqual($i->inicio) && - $i->fin->greaterEqual($this->inicio)) return true; + 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; } - return false; - } - - function fusionar( $f ) - { - if(! is_a($f, "intervalo")) return false; - if(! $this->seSuperpone( $f )) return false; - if($f->fin->greater($this->fin)) - $this->fin = $f->fin; - if($f->inicio->lower($this->inicio)) - $this->inicio = $f->inicio; - return true; - } - - function superponer( $i ) - { - if(! is_a($i, "intervalo")) return false; - $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, 'hora')) { - return $this->cortarHora($c); - } elseif (is_a($c, 'intervalo')) { - return $this->cortarIntervalo($c); - } else { + + /** + * 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; } - } - - /** - * 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) - { - if (!is_a($h, 'hora')) return false; - $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) - { - if (!is_a($i, 'intervalo')) return false; - $ant = $this->cortarHora($i->inicio); - $this->cortarHora($i->fin); - return $ant; - } + + 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, 'mecon_tiempo_hora')) { + return $this->cortarHora($c); + } elseif (is_a($c, 'mecon_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($int = null) { - if (!(is_a($int, 'intervalo'))) return false; - $this->inicio = new Hora($int->inicio->get()); - $this->fin = new Hora($int->fin->get()); - return true; + 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->inicio = $this->inicio->__clone(); - $i->fin = $this->fin->__clone(); - return $i; - } + function __clone() + { + $class = get_class($this); + $i = new $class; + $i->copy($this); + return $i; + } }