es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Comparando fechas en PHP

Estoy trabajando en un proyecto en el que tengo que comparar la fecha de vencimiento de un certificado médico con la fecha actual. Si la fecha de vencimiento es más de dos meses a partir de la fecha actual, debo establecer un icono verde en la página del usuario; si quedan menos de dos meses para la fecha de vencimiento, configuraría un icono amarillo, de lo contrario, si la fecha de vencimiento ha pasado, mostraría un icono rojo.

Para realizar la acción anterior, escribí el siguiente código:

$medical = new DateTime($data->medical_expiration);
$today = new DateTime();

$compare = $today->modify(‘+2 month’);

if($compare < $medical) {
$this->data[‘check_medical’] = ‘success’;
} elseif($compare >= $medical && $today <= $medical) {
$this->data[‘check_medical’] = ‘warning’;
} else {
$this->data[‘check_medical’] = ‘alarm’;
}

Pensé que el bloque else if debería establecer el ícono en amarillo…pero no funciona. Obtengo un ícono rojo cuando la fecha de vencimiento es inferior a dos meses a partir de hoy. ¿Qué está mal con el código?
Muchas gracias por cualquier comentario o sugerencia para mejorar el código anterior (no me gusta tener demasiados bloques if-else).

Tags:  ,

Answer

  1. Avatar for davy.ai

    Hay un par de problemas con el código que podrían estar causando el problema:

    1. La comparación en el bloque elseif podría ser incorrecta. En lugar de usar la comparación $compare >= $medical && $today <= $medical, sería mejor usar $medical > $today && $medical <= $compare. Esto comprobará si la fecha de caducidad está dentro del rango de dos meses a partir de hoy.
    2. La comparación en el bloque elseif también debería ser inclusiva del rango de dos meses, por lo que debería ser $medical <= $compare en lugar de $medical < $compare.

    Aquí está el código actualizado:

    $medical = new DateTime($data->medical_expiration);
    $today = new DateTime();
    $compare = $today->modify('+2 month');
    
    if ($medical > $compare) {
        $this->data['check_medical'] = 'success';
    } elseif ($medical <= $compare && $medical > $today) {
        $this->data['check_medical'] = 'warning';
    } else {
        $this->data['check_medical'] = 'alarm';
    }
    

    En cuanto a mejorar el código y reducir el número de bloques if-else, un enfoque posible es usar una declaración switch en su lugar:

    $medical = new DateTime($data->medical_expiration);
    $today = new DateTime();
    $compare = $today->modify('+2 month');
    $diff = $medical->diff($today);
    
    switch ($diff->invert) {
        case 1:
            $this->data['check_medical'] = 'success'; // la fecha de caducidad está en el futuro
            break;
        case 0:
            $days_left = $diff->days;
            if ($days_left > 60) {
                $this->data['check_medical'] = 'success'; // todavía quedan más de 2 meses
            } elseif ($days_left > 0) {
                $this->data['check_medical'] = 'warning'; // menos de 2 meses de vigencia
            } else {
                $this->data['check_medical'] = 'alarm'; // ya ha caducado
            }
            break;
    }
    

    Este enfoque calcula el número de días restantes entre la fecha de caducidad y hoy utilizando el método diff() del objeto DateTime. Si el número de días restantes es positivo (es decir, la fecha de caducidad está en el futuro), establece el icono verde. Si es cero o negativo, comprueba si quedan más de 60 días, si hay menos de 60 días o la fecha de caducidad ya ha pasado, y establece el icono correspondiente en consecuencia. Esto puede ayudar a reducir el número de bloques if-else y hacer que el código sea más legible.

Comments are closed.