Comunidad de diseño web y desarrollo en internet online

Crear listado de horas desde array

Citar            
MensajeEscrito el 13 Mar 2011 04:54 pm
Hola! ojala amablemente me pudiera dar una ayudadita alguien, Tengo un array creado de esta forma:

Código PHP :

Array
(
    [08:00:00] => Array
        (
            [0] => 08:00:00
            [1] => 08:30:00
            [2] => sandra d
            
        )

    [10:00:00] => Array
        (
            [0] => 10:00:00
            [1] => 10:45:00
            [2] => paloma s
          
        )

   
        )  

pero necesito mostrar lo de esta forma

08:00:00 08:30:00

08:30:00 08:45:00
08:45:00 09:00:00
09:00:00 09:15:00
09:15:00 09:30:00
09:30:00 09:45:00


10:00:00 10:45:00

es decir que el espacio entre las horas de los array me los muestre de 15 en 15 minutos, ya llevo dos días tratando de resolverlo y se me rebela, el problema principal es el de reconocer las horas intermedias entre los horarios del array que si estan dentro del lapso de tiempo

aqui abajo estan las funciones que uso

Código PHP :

$this->celda('08:00:00','08:15:00',$myArray); 


y la función celda es esta

Código PHP :


function celda($hora_a_comparar1,$hora_a_comparar2,$arreglo){


$rangos=$this->create_time_range($hora_a_comparar1,$hora_a_comparar2,'15 mins');
    
foreach ($rangos as $key => $time)
    
$hora_perdidas= date('H:i:s', $time);    

if( ($this->in_array_recursive($hora_a_comparar1,$arreglo)>0) ){
    
        echo '<strong style="color:#08c">'.$hora_a_comparar1.'</strong>';
        
        }else{
            
            
            if($hora_a_comparar1==$hora_perdidas){
            echo '';
            }else{
            
            echo $hora_perdidas;
            }
            }

} 

funcion in_array_recursive:

Código PHP :


function in_array_recursive($needle, $haystack) {

    $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($haystack));

    foreach($it as $element) {
        if($element == $needle) {
            return true;
        }
    }

    return false;
} 

Código PHP :

function create_time_range($start, $end, $by='15 mins') {

    $start_time = strtotime($start);
    $end_time   = strtotime($end);

    $current    = time();
    $add_time   = strtotime('+'.$by, $current);
    $diff       = $add_time-$current;

    $times = array();
    while ($start_time < $end_time) {
        $times[] = $start_time;
        $start_time += $diff;
    }
    $times[] = $start_time;
    return $times;
}  


es decir de las 10:00:00 a las 10:45:00 no me debe de mostrar 10:15:00 ni 10:30:00
agradezco la ayuda u orientación que me puedan proporcionar, mil gracias de antemano!

Por ben_mx

2 de clabLevel



 

firefox
Citar            
MensajeEscrito el 13 Mar 2011 06:06 pm
Según entiendo lo que quieres es mostrar un intervalo abierto por la derecha de las horas en períodos de 15 minutos a partir de un intervalo dado.

Código PHP :

function MostrarIntervalo($HoraDesde, $HoraHasta) {
   $HoraMin = $HoraDesde;
   echo $HoraMin['hora'].":".$HoraMin['min']."<br />";
   do {
   $HoraMin['min'] = $HoraMin['min'] + 15;
   if ($HoraMin['min'] >= 60) {
      $HoraMin['min'] = 0;
      $HoraMin['hora'] = $HoraMin['hora'] + 1;
      if ($HoraMin['hora'] >= 24) {
         $HoraMin['hora'] = 0;
      }
   }
   if (($HoraMin['hora'] >= $HoraHasta['hora']) and ($HoraMin['min'] >= $HoraHasta['min'])) { break; }
   else { echo $HoraMin['hora'].":".$HoraMin['min']."<br />"; }
   } while (true);
}

MostrarIntervalo(array('hora'=>8,'min'=>45), array('hora'=>10,'min'=>00));
}



La salida no está formateada apropiadamente y como muestras en los ejemplos los segundos son irrelevantes pero la idea es la que se muestra en mi código. Yo le paso dos arrays como parámetros porque me parece lo más cómodo, tú puedes adaptar la función como mejor te quede cómoda.

Saludos.

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 14 Mar 2011 01:34 am
Gracias DriverOp! tu funcion esta muy buena, pero disculpa mi ignorancia, pero aun no logro lo que necesito como logro que la funcion la ejecuten solo los ultimas de un nivel y primeras horas del otro nivel del array ??

es decir mi array es coomo este:

Código PHP :

Array 
( 
    [08:00:00] => Array 
        ( 
            [0] => 08:00:00 
            [1] => 08:30:00 
            [2] => sandra d 
             
        ) 
 
    [10:00:00] => Array 
        ( 
            [0] => 10:00:00 
            [1] => 10:45:00 
            [2] => paloma s 
           
        ) 
 
    
        )  


como logro que se ejecute la funcion asi:

function MostrarIntervalo(array('hora'=>8,'min'=>30),array('hora'=>10,'min'=>00));

??

ya estuve tratando de varias formas de recuperar los elementos del array separados para esto, pero no puedo :crap: :oops: , te explico mejor lo que quiero lograr,

necesito crear una especie de tabla o lista para mostrar los datos asi:

08:00:00 - 08:30:00

08:30:00 - 08:45:00
08:45:00 - 09:00:00
09:00:00- 09:15:00
09:15:00 -09:30:00
09:30:00 - 09:45:00
09:45:00 - 10:00:00

10:00:00 - 10:45:00

10:45:00 - 11:00:00
11:00:00 - 11:15:00

de antemano mil gracias otra vez por ayudarme !! (y)

Por ben_mx

2 de clabLevel



 

firefox
Citar            
MensajeEscrito el 14 Mar 2011 12:26 pm
Bueno, ahora me has cambiado las especificaciones. Ahora quieres un intervalo cerrado en ambos lados. No big deal anyway ;).

El problema es que no nos dices cuál es la condición de fin. En tu ejemplo de cómo debe ser la salida terminas el listado a las 11:15 ¿por qué esa hora y no otra?. Algo parecido sucede con el inicio, lo pones a las 8:00 pero supongo que es porque ese es el primer dato del array, sin embargo sigue siendo un misterio por qué terminar a las 11:15 y no a cualquier otra hora arbitraria.

Por DriverOp

Claber

2510 de clabLevel



 

opera
Citar            
MensajeEscrito el 14 Mar 2011 01:07 pm
DriverOp gracias por tu paciencia, si mira, en si el listado empieza a las 08:00 y termina hasta las 21:30 solo que por cuestiones de espacio aqui no lo pongo todo, en verdad aprecio mucho tu ayuda, aun sigo pensando en soluciones la última que intento es generer espacios o ventanas segun los datos del array, que por cierto varian, nunca son iguales y en base a eso revisar espacios de tiempo, aun no se si funcionará pero lo sigo intentando.

Por ben_mx

2 de clabLevel



 

firefox
Citar            
MensajeEscrito el 14 Mar 2011 06:58 pm
bueno me parecio interesante este post jeje me llamo la curiosidad, aunque php5.3 dispone de la clase DateInterval que haria lo que quieres obtener osea sumar de 15 minutos en 15 y en caso de encontrar un dato que coincida en la hora saltar o llenar automaticamente ese espacio de nombre
bueno empezemos
creamos una clase del tipo Vector,
en realidad es la clase arrayIterator extendida
nos ahorrara unos cuantos caracteres al escribir
Vector.clase.php

Código PHP :

<?php
/*
   $array = new ArrayIterator(array("el1","el2"));
   sera igual que
   $array = new Vector("el1","el2");
*/
class Vector extends arrayIterator
{
   public function __construct()
   {
      $argumentos =  & func_get_args();
      parent::__construct($argumentos);
   }
}
?>

ahora creamos nuestra magica clase que nos facilita lo de adicionar horas ,minutos,segundos y por si acaso dias
no sabia como llamarla asi que le puse "reloj"
reloj.clase.php

Código PHP :

<?php
/**
 * esta clase convierte strings en int y suma los minutos y horas adecuadamente
 * inspirado en el post de http://foros.cristalab.com/crear-listado-de-horas-desde-array-t95960/
 * @author tuadmin
 * @version 1.0
 * @package ejemplos
 **/
//namespace ejemplos
class reloj
{
   public $dia = 0;
   public $hora = 0;
   public $minuto = 0;
   public $segundo = 0;
   public static function newInstance($hora_string)
   {
      return new self($hora_string);
   }
   public function __construct($hora_string)
   {
      //sprintf("%02d:%02d:%02d", $hora_string,$this->hora, $this->minuto, $this->segundo);
      list($this->hora, $this->minuto, $this->segundo) = sscanf($hora_string, "%d:%d:%d");
   }
   /**
   * con esto volvemos a cambiar la hora
   * @param string $hora_string de la hora del formato 'hora:minuto:segundo'
   * @return void
   **/
   public function reajustar($hora_string)
   {
      list($this->hora, $this->minuto, $this->segundo) = sscanf($hora_string, "%d:%d:%d");
      return $this;
   }
   /**
   * con esto adicionamos dias la hora
   * @param int $dias numero de dias a agregar al hora actual
   * @return void
   **/
   public function addDias($dias)
   {
      $this->dia = $this->dia +$dias;
      return $this;
   }
   /**
   * con esto adicionamos horas a la hora
   * @param int $horas numero de horas a agregar al hora actual
   * @return void
   **/
   public function addHoras($horas)
   {
      $total = $this->hora + $horas;
      $dias = floor($total / 24);
      $this->hora = $total - ($dias * 24 );
      $this->addDias($dias);
      return $this;
   }
   /**
   * con esto adicionamos minutos la hora
   * @param int $minutos numero de minutos a agregar al hora actual
   * @return reloj
   **/
   public function addMinutos($minutos)
   {
      $total = $this->minuto + $minutos;
      $hora = floor($total / 60);
      $this->minuto = $total - ($hora * 60 );
      $this->addHoras($hora);
      return $this;
   }
   /**
   * con esto adicionamos segundos la hora
   * @param int $segundos numero de segundos a agregar a la hora actual
   * @return reloj
   **/
   public function addSegundos($segundos)
   {
      $total = $this->segundo + $segundos;
      $minuto = floor($total / 60);
      $this->segundo = $total - ($minuto * 60 );
      $this->addMinutos($minuto);
      return $this;
   }
   /**
   * el formato es del tipo que usa printf
   * @param string $format formato del string ej. "%02d:%02d:%02d"
   * @return string
   **/
   public function getFormat($format = "%02d:%02d:%02d")
   {
      return sprintf($format, $this->hora, $this->minuto, $this->segundo);
   }
}
?>

bueno ahora lo implementamos a la pregunta de nuestro amigo
que tiene de ejemplo estos datos
datos.php
observen q utilizo la clase vector noten la diferencia entre la clase q creamos Vector y la de ArrayIterator

Código PHP :

<?php
//todos los arrays hacen lo mismo con distinta forma de crearlos
$datos = new ArrayIterator(array(
    "08:00:00" => new Vector
        (  
            '08:00:00','08:30:00','sandra d'
        )  ,
  
    "10:00:00" => new ArrayIterator
        (  array(
           '10:00:00',
           '10:45:00',
            'paloma s' )
        ),
   "20:00:00" => new Vector("20:00:00","21:15:00","pedro pedrales");
));
?>

ahora ponemos todo en marcha
lo demas creo ya esta explicado en los comentarios
ejemplo1.php

Código PHP :

<?php
require 'Vector.clase.php';
require 'reloj.clase.php';
require 'datos.php';
//instanciamos de la forma larga
$reloj = new reloj("8:00:00");
//$reloj = reloj::newInstance("8:00:00");
//ponemos en un bucle condicinal hasta que se cumpla nuestra condicion
//while($reloj->hora < 23 AND $reloj->minutos < 60)
while($reloj->hora < 23)
{
   //almacenamos en una variable para ahorrar el proceso que hace getFormat()
   $formato = $reloj->getFormat();
   //verificamos que la hora exista en nuestro array de datos
   if($datos->offsetExists( $formato ))
   {
      //si existe obtenemos la posicion 2 del sub array que contiene el nombre
      $nombre = $datos->offsetGet( $formato )->offsetGet(2);
      //obtenemos tambien la hora de finalizacion del mismo q esta en
      // la posicion 1 del sub array 
      $reloj->reajustar($datos->offsetGet( $formato )->offsetGet(1));
      //mostramos en forma decorativa los horarios aunque esto se aplicaria mejor a un contenedor de tipo DIV de html
      echo '+' . str_repeat('-',38). '+';
      echo "\n";
      echo '+-' . str_pad("$formato : $nombre",37,' ',STR_PAD_RIGHT) . '+';
      echo "\n";
      echo '+-' . str_pad( $reloj->getFormat() . " : $nombre"  ,37,' ',STR_PAD_RIGHT) . '+';
      echo "\n";
      echo '+' . str_repeat('-',38). '+';
      echo "\n";
   }
   else
   {
      //mostramos el formato de hora actual
      echo "$formato\n";
   }   
   //incrementamos nuestra hora en 15 minutos
   $reloj->addMinutos(15);
}
?>

Por tuadmin

Claber

598 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 14 Mar 2011 08:48 pm
Muchas gracias tuadmin ! excelente solución, solo que no me queda claro un detalle como genero dinamicamente el archivo datos? si el array es el resultado de una consulta a una bd??

muchas gracias por molestarse tanto en ayudarme =)

Por ben_mx

2 de clabLevel



 

chrome
Citar            
MensajeEscrito el 14 Mar 2011 08:58 pm
y BD? estas usando y como extraes los datos.
bueno seria casi igual solo que el resultado debe ser retornado por un array asociativo
osea llave => valor
lo unico que tendrias que hacer seria reemplazar las condiciones del tipo

Código PHP :

$datos->offsetExists("key");

por su equivalente

Código PHP :

isset($datos["key"]);

y asi en todas los metodos de la clase ArrayIterator por funciones modulares como isset , y las llamadas del tipo $dats["key"];
bueno la solucion q te di lo hice para que modificaras y aplicaras a tus necesidades los foros no es COPY PASTE osea aqui nadie hace el trabajo de otro solo lo ilustra con ejemplos y soluciones simples para algo mas complejo
bueno bye bye
y recuerda que
una buena pregunta puede obtener una buena respuesta

Por tuadmin

Claber

598 de clabLevel



Genero:Masculino  

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.