afterFind - beforeSave

Hola comunidad

un consulta

para mostrar fechas y almacenarlas lo que hago es

en el afterFind le pongo la mascara dd/mm/yyyy

y en el beforeSave la transformo a yyyy/mm/dd

mi pregunta es

es necesario poner

return parent::afterFind()

return parent::beforeSave()

al final de cada funcion?

o con poner parent::afterFind(), parent::beforeSave() funciona igual (sin return)

la otra consulta seria

como trabajan uds con fechas? yo probe usar la extension http://www.yiiframew…etime-behavior/

pero me trajo problemas de memoria ( http://www.yiiframew…mory-consuming/)

ejemplo de mi codigo





public function afterFind(){


    $this->fecha_ini = Varios::dateconvert($this->fecha_ini,2);

    $this->fecha_fin = Varios::dateconvert($this->fecha_fin,2);

    $this->fecha = Varios::dateconvert($this->fecha,2);


    return parent::afterFind();

	}




public function beforeSave() {


    $this->fecha_ini = Varios::dateconvert($this->fecha_ini,1);

    $this->fecha_fin = Varios::dateconvert($this->fecha_fin,1);

    $this->fecha = Varios::dateconvert($this->fecha,1);

    return parent::beforeSave();

}



saludos y gracias

Con respecto a poner return parent::afterFind() o parent::beforeSave() si. Es necesario poner el return porque la primera en ser llamada es tu afterFind() la que a su vez llama a parent::afterFind(). Si en tu afterFind() no retornas el valor de parent::afterFind() este queda "olvidado" en tu afterFind(). Espero haberme explicado bien, pero ya tenes una idea.

hola PoL

perfecto, pongo

return parent::… al final de cada funcion

y la forma de manejar las fechas?

asi trabajan generalmente uds?

un ejemplo me vendría muy bien

Particularmente trabajo con el tipo Date de MySQL (o Datetime si necesito tambien las horas, minutos y segundos)

Y cuando hay que filtrar por fechas etc… dejo que el motor de la base de datos haga las comparaciones. En php solo muestro (o capturo la entrada del usuario) para las fechas, pero trato lo mayor posible de evitar comparaciones de fechas y horas en php. En el peor de los casos (en el que tenga que validar alguna fecha que es mayor que otra etc… uso las funciones incorporadas de php (las funciones de fecha que tiene php5)

coincido en eso

para hacer comparaciones de fecha estoy usando algo como




        

         //b_fecha es criterio de busqueda ingresado por el usuario

        //en las busquedas el usuario puede ingresar

        // "%/06/2009"  fechas de junio/2009

        //"%/%/2009" fechas del año 2009

       // "%/10/%" fechas de octubre


         if  (isset($_GET['b_fecha']) and $_GET['b_fecha']!="") {

                $conditions[] = 'date_FORMAT( fecha,\'%d/%m/%Y\' ) like :fecha';

                $params[':fecha'] = '%'.$_GET['b_fecha'].'%';

                $criterios['b_fecha']=$_GET['b_fecha'];

            }




igualmente mi pregunta estaba orientada a como mostrar / validar / almacenar las fechas

en mysql se almacenan como año-mes-dia

y al usuario se le muestra dia-mes-año

y para ingreso o modificacion, el usuario ingresa dia-mes-año

y se almacena año-mes-dia

uds hacen algo parecido a lo que hago yo?

(el codigo esta en este post y es el codigo de la extension http://www.yiiframew…etime-behavior/)

gracias por responder y compartir

soy nuevo en esto y quiero encontrar la mejor forma de hacer las cosas, sobre todo estas que son generales a cualquier sistema

todavia estoy a tiempo de cambiar lo que ya hice(despues cuesta un poco , je je)

saludos

[edit]

este es el codigo de la clase Varios, relacionado a fechas




/*

 * me devuelve la fecha con "/" como separador 

 */

    public static function agregarBarras($date_in) {


        $date_out=$date_in;

        $date_aux = str_replace(array('\'', '-', '.', ','), '/', $date_in);

        $date_arr = explode('/', $date_aux);


        if(count($date_arr) == 1 and strlen($date_arr[0])== <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' /> // No tokens

            {

                $date_out=substr($date_arr[0], 0, 2).'/'.substr($date_arr[0], 2, 2).'/'.substr($date_arr[0], 4, 4);

            }

        elseif(count($date_arr) == 1 and strlen($date_arr[0])== 6) // No tokens

            {

                $date_out=substr($date_arr[0], 0, 2).'/'.substr($date_arr[0], 2, 2).'/'.substr($date_arr[0], 4, 2);

            }


        return $date_out;


    }


    public static function is_date($date)

    {

     try {

        $date = str_replace(array('\'', '-', '.', ','), '/', $date);

        $date = explode('/', $date);


        //no es lo mejor, pero para el 2100 espero estar jubilado

        if (count($date) == 3 and $date[2]==0) $date[2]=2000;


        if(    count($date) == 3

            and    is_numeric($date[0])

            and    is_numeric($date[1])

            and    is_numeric($date[2])

            and    checkdate($date[1], $date[0], $date[2])

            //(    checkdate($date[0], $date[1], $date[2]) //mmddyyyy

            //or   checkdate($date[1], $date[0], $date[2]) //ddmmyyyy

            //or   checkdate($date[1], $date[2], $date[0]))//yyyymmdd

        )

        {

            return true;

        }


        if (count($date) == 1 and strlen($date[0])== 6 and substr($date[0], 4, 2)==0)

            //no es lo mejor, pero para el 2100 espero estar jubilado

            $date[0]=substr($date[0], 0, 4).'2000';

            


        if(    count($date) == 1 // No tokens  10022006

            and    is_numeric($date[0])

            and    strlen($date[0])== 8 and

            (    checkdate(substr($date[0], 2, 2)

                        , substr($date[0], 0, 2)

                        , substr($date[0], 4, 4)))

        )

        {

            return true;

        }




        if(    count($date) == 1 // No tokens  100206

            and    is_numeric($date[0])

            and    strlen($date[0])== 6 and

            (    checkdate(substr($date[0], 2, 2)

                        , substr($date[0], 0, 2)

                        , substr($date[0], 4, 2)))

        )

        {

            return true;

        }





        return false;

    }

        catch(Exception $e) {return false;};

    }





        public function dateconvert($date,$func) {

// valores nulos

                if ($date =='00-00-0000' or $date =='00/00/0000' or $date =='0000-00-00' or $date =='0000/00/00' or  $date ==null) return null;

                if ($func == 1){ //insert conversion

                        list($day, $month, $year) = split('[/.-]', $date);

                        //si ingresa 10/8/9, pongo 10/08/09, sino me pone 0009 en vez de 2009

                        if (strlen($year)==1) $year='0'.$year;


                        $date = "$year-$month-$day";

                        return $date;

                }

                if ($func == 2){ //output conversion

                        list($year, $month, $day) = split('[-.]', $date);

                        $date = "$day/$month/$year";

                        return $date;

        }

    }



Hola,

No me gusta hacer Cross posting, y menos todavia si es en otro sitio! Pero estoy con tu misma duda, que la publiqué en http://groups.google.com/group/yii-spanish/browse_thread/thread/aab271e153e80b2f

Reproduzco aquí lo que hago:

Gente,

Tengo algunas dudas sobre como manejar las fechas. Finalmente logro

que en la vista se tome la fecha en un formato, y en el controlador se

grabe como corresponde, pero no estoy seguro si la forma en que lo

estoy haciendo es la mejor.

El tema es el siguiente:

Estoy usando MySQL (tengo poca experiencia en MySQL).

Por prueba y error validé que efectivamente, como la mayoría de los

motores de bases de datos, al insertar una fecha, usa el formato ISO:

yyyy-MM-dd.

Ahora, en mi modelo, tengo un atributo fecha definido asi:

array(‘DateOfBirth’, ‘type’, ‘type’=>‘date’,‘dateFormat’=>'dd/MM/

yyyy’,‘message’ => ‘¡{attribute} no es una fecha válida!’,),

Y además, en mi vista, tengo definido:

            &#036;this-&gt;widget('zii.widgets.jui.CJuiDatePicker', array(


                'name' =&gt; 'FCUserProfile[DateOfBirth]',


                // additional javascript options for the date

picker plugin

                'options' =&gt; array(


                    'showAnim' =&gt; 'fold',


                    'changeMonth' =&gt; 'true',


                    'dateFormat' =&gt; 'dd/mm/yy',


                    'changeYear' =&gt; 'true',


                    'defaultDate' =&gt; '-13y',


                    'maxDate' =&gt; '-13y',


                    'prevText' =&gt; 'Ant',


                    'nextText' =&gt; 'Prox',


                ),


                'model' =&gt; &#036;userProfileModel,


                'attribute' =&gt; 'DateOfBirth',


                'htmlOptions' =&gt; array(


                    'style' =&gt; 'height:20px;'


                ),


            ));

En mi controlador, despues de validar, y antes de guardar el AR, hago

esto:

            &#036;timestamp=CDateTimeParser::parse(&#036;userProfileModel-

>DateOfBirth,‘dd/MM/yyyy’);

            &#036;dtf = new CDateFormatter(yii::app()-&gt;getLocale());


            &#036;formattedTimeStamp = &#036;dtf-&gt;format('yyyy-MM-dd',

$timestamp);

            &#036;userProfileModel-&gt;DateOfBirth = &#036;formattedTimeStamp

Mi duda es:

  1. Consideran correcto hacer esto en el action?

  2. Hay alguna manera de hace esto automático? es decir, indicarle de

alguna forma al modelo que su formato de vista es uno y el formato de

persistencia es otro?

  1. Es mejor hacer algo en el modelo? COmo seria???

AH, de paso, también soy novato en PHP…

Gracias!

Bueno, acabo de probar la extensión que mencionas:

http://www.yiiframework.com/extension/i18n-datetime-behavior

Definitivamente, mucho más facil que lo que hacía yo.

Igualmente, lo que hice sobre formateo de fecha en las reglas, vale, y el JuiDatePicker tambien ;)

Con colocar la configuración de comportamiento en el modelo, ya no tengo que manejar en el action el formateo particular para cada fecha.