How to create a function to validate time in PHP

6

I'm trying to validate a time field in PHP, and with the help this topic on an external site I came across this script:

function validaHoras($campo){
    if (preg_match('/^[0-9]{2}:[0-9]{2}$/', $campo)) {
        $horas = substr($campo, 0, 2);
        $minutos = substr($campo, 3, 2);
        if (($horas > "23") OR ($minutos > "59")) {
            $campo = false;
        }
    }
}

The input should receive the field in the format '00: 00 ', but it has no validation in JS, and the user may enter an invalid time.

So I want to change the value of the variable to false when it comes with a wrong time (type 99:99), but it is not working. Testing the script below with input 99:99, the value of the variable is not changed ...

function validaHoras($campo){
    if (preg_match('/^[0-9]{2}:[0-9]{2}$/', $campo)) {
        $horas = substr($campo, 0, 2);
        $minutos = substr($campo, 3, 2);
        if (($horas > "23") OR ($minutos > "59")) {
            $campo = false;
        }
    }
}

// SEGUNDA

$val1 = isset($_POST["Tsegs"]) && !empty($_POST["Tsegs"]) ? $_POST["Tsegs"] : false;

validaHoras($val1);
echo $val1;

//saida: 99:99
//saida desejada: false
    
asked by anonymous 21.04.2017 / 21:43

3 answers

6

There is a misunderstanding in the function's call to Time, it is passing the parameter but does not return anything after execution. The variable you print is the same as you passsa as a parameter (by value), it will not change. Try this:

<?php

function validaHoras($campo){
    if (preg_match('/^[0-9]{2}:[0-9]{2}$/', $campo)) {
        $horas = substr($campo, 0, 2);
        $minutos = substr($campo, 3, 2);
        if (($horas > "23") OR ($minutos > "59")) {
            return false;
        }

        return true;
    }

    return false;
}

// SEGUNDA
$val1 = isset($_POST["Tsegs"]) && !empty($_POST["Tsegs"]) ? $_POST["Tsegs"] : false;

if(validaHoras($val1) === true){
    echo 'hora valida ' . $val1;
}else {
    echo 'hora invalida ' . $val1;
}
    
22.04.2017 / 17:51
8

You can only validate the format and content with regular expressions if you wish. ^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]) .

The first group captures the time in format (00-23) it defines three types 'categories', the first group identifies values from 00 to 09, the second from 10 to

19 and the last from 20 to 23.

^(0[0-9]|1[0-9]|2[0-3]) = > The second group covers minutes that have a slightly different logic of hours. Captures a digit that can be between zero and five and another that can be between zero and nine, which covers 00 to 59

function validaHoras($campo){
    return preg_match('/^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])/', $campo) ? $campo : false;
}


$arr = array('00:00', '19:59', '20:34', '24:33', '28:64', '07:59', '000:30', '30:50');

foreach($arr as $item) var_dump(validaHoras($item)) .'<br>';

Example - ideone

    
24.04.2017 / 15:20
3

An option with sanitization.

The routine sanitizes the user input, removing everything that is not a number, but preserves the : character.

It also converts full-width (zenkaku) numeric characters and accepts 1-digit hour and minute. Example: 1:10, 1: 6 (01:10, 01:06)

Sanitization makes validation more user friendly.

function numbers_only($str, $exception = '')
{
    return preg_replace('#[^0-9'.$exception.']#', '', mb_convert_kana($str, 'n'));
}

function valid_hour($n)
{
    $n = str_replace(':', ':', $n);
    $n = numbers_only($n, ':');

    $arr = explode(':', $n);
    if (count($arr) == 2) {
        $h = intval($arr[0]);
        $m = intval($arr[1]);
        if ($h <= 23 && $h >= 0 && $m <= 59 && $m >= 0) {
            return str_pad($h, 2, '0', STR_PAD_LEFT).':'.str_pad($m, 2, '0', STR_PAD_LEFT);
        }
    }
    return false;
}

$str[0] = '0000'; // (inválido pois é necessário o separador : )
$str[1] = '00:09'; // caracteres zenkaku (válido)
$str[2] = '00:00'; // (válido)
$str[3] = '0:06'; // (válido)
$str[4] = '0:0'; // (válido)
$str[5] = '00:0'; // (válido)
$str[6] = '01:60'; // (inválido pois os minutos ultrapassaram o limite)
$str[7] = '01:6.'; // (válido, pois o ponto no final é removido na sanitização)

/*
Quando for inválido, retorna booleano false.
Quando for válido, retorna a string do usuário sanitizada e formatada como hh:mm, mesmo que o usuário insira apenas 1 dígito para hora ou minuto.
*/

var_dump(valid_hour($str[7]));
    
27.04.2017 / 14:33