Foros del Web » Programando para Internet » PHP »

[Aporte] Clase para tratar fechas

Estas en el tema de [Aporte] Clase para tratar fechas en el foro de PHP en Foros del Web. Hola compañeros, mi primer mensaje en el foro y me presento con este aporte. Se trata de una clase para tratar fechas en PHP que ...
  #1 (permalink)  
Antiguo 26/02/2012, 19:26
Avatar de CreativeMedia  
Fecha de Ingreso: febrero-2012
Ubicación: Cadiz
Mensajes: 3
Antigüedad: 12 años, 1 mes
Puntos: 0
[Aporte] Clase para tratar fechas

Hola compañeros,

mi primer mensaje en el foro y me presento con este aporte. Se trata de una clase para tratar fechas en PHP que estoy realizando al no tener mi servidor soporte aún para 5.3 y poder hacer uso de la clase nativa [URL="http://www.php.net/manual/es/class.datetime.php"]dateTime[/URL].

Aún la estoy testeando para implementar nuevas funcionalidades y que espero que con vuestra ayuda podamos mejorarla para uso de que quiera.

Código PHP:
<?php
    
    
/**
     * Author: Jesús Gómez @ http://www.CreativeMedia.es
     * Copyright: Jesús Gómez
     * Date: 27-02-2012
     */
    
class Fecha
    
{
        private 
$_segundos;
        private 
$_minutos;
        private 
$_horas;
        private 
$_dia;
        private 
$_mes;
        private 
$_ano;
        
        public function 
__construct($ano 1970$mes 1$dia 1$horas 0$minutos 0$segundos 0)
        {
            
$this->setFecha($ano$mes$dia$horas$minutos$segundos);
        }
        
        
/**
         * SETTERS
         */
        
public function setSegundos($s)
        {
            
$this->_segundos $s;
        }
        
        public function 
setMinutos($m)
        {
            
$this->_minutos $m;
        }
        
        public function 
setHoras($h)
        {
            
$this->_hora $h;
        }
        
        public function 
setDia($d)
        {
            
$this->_dia $d;
        }
        
        public function 
setMes($m)
        {
            
$this->_mes $m;
        }
        
        public function 
setAno($a)
        {
            
$this->_ano $a;
        }
        
        public function 
setFecha($ano 1970$mes 1$dia 1$horas 0$minutos 0$segundos 0)
        {
            
$this->_segundos $segundos;
            
$this->_minutos $minutos;
            
$this->_horas $horas;
            
$this->_dia $dia;
            
$this->_mes $mes;
            
$this->_ano $ano;
        }
        
        public function 
addSegundos($s)
        {
            
$this->_segundos += $s;
        }
        
        public function 
addMinutos($m)
        {
            
$this->_minutos += $m;
        }
        
        public function 
addHoras($h)
        {
            
$this->_horas += $h;
        }
        
        public function 
addDias($d)
        {
            
$this->_dia += $d;
        }
        
        public function 
addMeses($m)
        {
            
$this->_mes += $m;
        }
        
        public function 
addAnos($a)
        {
            
$this->_ano += $a;
        }
        
        
/**
         * GETTERS
         */
        /*
         * @param   string (formato date http://php.net/manual/es/function.date.php)
         * @return  integer
         */
        
public function getFormato($formato)
        {
            return 
date($formato, @mktime($this->_horas$this->_minutos$this->_segundos$this->_mes$this->_dia$this->_ano));
        }
        
        public function 
getSegundos()
        {
            return 
$this->_segundos;
        }
        
        public function 
getMinutos()
        {
            return 
$this->_minutos;
        }
        
        public function 
getHoras()
        {
            return 
$this->_horas;
        }
        
        public function 
getDia()
        {
            return 
$this->_dia;
        }
        
        public function 
getMes()
        {
            return 
$this->_mes;
        }
        
        public function 
getAno()
        {
            return 
$this->_ano;
        }
        
        
        
/**
         * MISCELÁNEOS
         */
        /*
         * @param   integer
         * @return  boolean
         */
        
public function isValid($ano$mes$dia)
        {
            if(!
checkdate($mes$dia$ano)) {
                return 
FALSE;
            }
            
            if(
$ano 1970 || $ano 2038) {
                return 
FALSE;
            }
            
            return 
TRUE;
        }
        
        
/*
         * Solo es necesario pasar $fecha1, si $fecha2 no es pasado se tomará la fecha actual.
         * Es indiferente que $fecha1 sea mayor a $fecha2 o a la inversa
         *
         * @param   timestamp
         * @return  integer (número de dias de diferencia)
         */
        
public function diferenciaDias($fecha1$fecha2 NULL)
        {
            if(empty(
$fecha2)) {
                
$fecha2 mktime(000date('m'), date('d'), date('Y'));
            }
            
            
$diferencia $fecha2 $fecha1;
            
            return (
$diferencia 0)
                ? 
floor($diferencia 86400)
                : 
absfloor($diferencia 86400) );
        }
        
        
/*
         * Calcula la edad a partir de la fecha dada y la actual
         *
         * @param   integer
         * @return  string | boolean (FALSE en caso de fecha futura)
         */
        
public function calcularEdad($a$m$d)
        {
            
$edad = ( date('md') < $m $d ) ? date('Y') - $a date('Y') - $a;
            
            if(
$edad 1) {
                return 
$edad ' años';
            }
            
            if(
$edad == 1) {
                return 
'1 año';
            }
            
            if(
$edad == 0) {
                
//El año dado es menor al actual y el mes actual es menor al de la fecha dada
                
if( date('Y') > $a && date('md') < $m $d ) {
                    
//El dia actual es mayor al dia dado, se suma este mes 
                    
if( date('d') >= $d ) {
                        return 
12 $m date('m') . ' meses';
                    }
                    
//El dia actual es inferior al dia del mes dado, no le sumamos este mes
                    
return 12 $m date('m') - ' meses';
                }
                
                
//El año dado es el actual, el mes y dia actual es mayor al mes y dia dados y la diferencia entre el mes actual y el dado es mayor que 1
                
if( date('Y') == $a && date('md') > $m $d && (date('m') - $m 1)) {
                    
//El dia actual es mayor al dado por lo tanto ha cumplido un mes mas hace dias
                    
if(date('d') > $d) {
                        return 
date('m') - $m ' meses';
                    }
                    
//El dia actual es menor al dado y la diferencia entre el mes actual y el dado es mayor que 2
                    
if(date('m') - $m 2) {
                        return 
date('m') - $m ' meses';
                    }
                    
//El dia actual es menor al dado y la diferencia entre el mes actual y el dado es 1
                    
return date('m') - $m ' mes';
                }
                
                
//El mes actual es mayor al dado y el dia actual es mayor al dado (mas de un mes) o el mes actual es mayor al dado y el dia actual es el mismo (un mes exacto)
                
if( date('m') > $m && date('d') > $d || date('m') > $m && date('d') == $d ) {
                    return 
'1 mes';
                }
                
                
//El mes actual es mayor y el dia actual es menor (no se ha completado un mes) o el mes es el mismo y el dia actual es mayor (cuestión de dias) o el mes y el dia son los mismos (XDDD misma fecha!!)
                
if( date('m') > $m && date('d') < $d || date('m') == $m && date('d') > $d || date('m') == $m && date('d') == $d ) {
                    return 
'menos de un mes';
                }
            }
            
            
//Para cualquier fecha no válida, en este caso fechas negativas
            
return FALSE;
        }
        
    }
Ejemplos de uso:

Cambio de formato:
Código PHP:
$fecha = new Fecha(20120227);
//Para establecer una fecha posteriormente $fecha->setFecha($ano, $mes, $dia);
echo $fecha->getFormato('d-m-Y'); 
Validar fecha:
Código PHP:
$fecha = new Fecha();
if(
$fecha->isValid(2012525)) echo 'Fecha valida'
Diferencia de dias:
Código PHP:
$fecha = new Fecha();
$fSegundos strtotime('2012-01-27');
echo 
$fecha->diferenciaDias($fSegundos); 
Lo ideal sería que hiciera una pequeña documentación pero ando escaso de tiempo para ello. De todas formas es una clase simple.

Espero vuestras aportaciones y opiniones
  #2 (permalink)  
Antiguo 26/02/2012, 19:54
Avatar de gildus  
Fecha de Ingreso: agosto-2003
Mensajes: 1.495
Antigüedad: 20 años, 8 meses
Puntos: 105
Respuesta: [Aporte] Clase para tratar fechas

Holas,

Interesante, a esa clase le faltaria imprimir en letras segun el locale del server.

Saludos y gracias por el aporte.
__________________
.: Gildus :.
  #3 (permalink)  
Antiguo 26/02/2012, 19:54
Avatar de andresdzphp
Colaborador
 
Fecha de Ingreso: julio-2011
Ubicación: $this->Colombia;
Mensajes: 2.749
Antigüedad: 12 años, 9 meses
Puntos: 793
Respuesta: [Aporte] Clase para tratar fechas

Está buena la clase, usaría el método chaining para no tener que hacer tantas líneas con los setters y poder hacer $fecha->setAno()->setMes() etc... y el poder poner fechas en español.

pero lo que no me gusta tener que llevar el problema del 2038

Código PHP:
Ver original
  1. if($ano < 1970 || $ano > 2038) {
  2.                 return FALSE;
  3. }

no puedes sumar por ejemplo 50 años porque te sale el famoso 1969

Yo ya voy dejando en el pasado a versiones anteriores de PHP 5.3.0 que está con nosotros desde el año 2009 y está muy cerca el PHP 5.4. Pero como dices útil por problemas de versión para los que tienen PHP 5.3+ yo les recomiendo la clase DateTime.

PD: La clase se puede usar desde PHP 5.2 y necesita PHP 5.3.0 para algunos métodos.

Saludos.
__________________
Si sabemos como leer e interpretar el manual será mucho más fácil aprender PHP. En lugar de confiar en ejemplos o copiar y pegar - PHP

Última edición por andresdzphp; 26/02/2012 a las 20:00
  #4 (permalink)  
Antiguo 27/02/2012, 19:24
Avatar de CreativeMedia  
Fecha de Ingreso: febrero-2012
Ubicación: Cadiz
Mensajes: 3
Antigüedad: 12 años, 1 mes
Puntos: 0
Respuesta: [Aporte] Clase para tratar fechas

Mmm desconocia el chaining pero se ve interesante, lo implementaré.

Si, DateTime tiene algunos métodos solo en PHP 5.3 y es hay donde se me hace imposible su uso

Para
Código PHP:
if($ano 1970 || $ano 2038) { 

                return 
FALSE


en concreto el isValid no toma fechas que maneje la clase por lo que se puede modificar esa línea sin problemas para que admita cualquier fecha extensa que valide checkdate.


gildus estudiaré el caso para implementarlo.


Gracias por vuestras opiniones
  #5 (permalink)  
Antiguo 27/02/2012, 20:45
Avatar de andresdzphp
Colaborador
 
Fecha de Ingreso: julio-2011
Ubicación: $this->Colombia;
Mensajes: 2.749
Antigüedad: 12 años, 9 meses
Puntos: 793
Respuesta: [Aporte] Clase para tratar fechas

Bueno yo no me refiero a ese condicional, me refiero a esto:

Tu clase:

Código PHP:
Ver original
  1. $fecha = new Fecha(2012, 02, 27);
  2. $fecha->addAnos(50);
  3. echo $fecha->getFormato('d-m-Y');

Cita:
Resultado: 31-12-1969 ¿?¿?¿?
con DateTime

Código PHP:
Ver original
  1. $fecha = new DateTime('2012-02-27');
  2. echo $fecha->modify('+50 year')->format('d-m-Y');

Cita:
Resultado: 27-02-2062
Problema del año 2038: http://es.wikipedia.org/wiki/Problema_del_a%C3%B1o_2038

Saludos.
__________________
Si sabemos como leer e interpretar el manual será mucho más fácil aprender PHP. En lugar de confiar en ejemplos o copiar y pegar - PHP
  #6 (permalink)  
Antiguo 28/02/2012, 10:07
Avatar de CreativeMedia  
Fecha de Ingreso: febrero-2012
Ubicación: Cadiz
Mensajes: 3
Antigüedad: 12 años, 1 mes
Puntos: 0
Respuesta: [Aporte] Clase para tratar fechas

Si es uno de los problemas que acarrea PHP desde las versiones inferiores a la 5.3, aunque es solucionable como el ejemplo de la clase Date de Zend

Etiquetas: clase, fecha
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 22:25.