Pergunta

Existe uma maneira de verificar para ver se a data / hora é válida você pensaria que estes seriam fácil de verificar:

$date = '0000-00-00';
$time = '00:00:00';
$dateTime = $date . ' ' . $time;

if(strtotime($dateTime)) {
    // why is this valid?
}

o que realmente me deixa é a seguinte:

echo date('Y-m-d', strtotime($date)); 

resulta em: "1999-11-30",

hein? Eu fui de 0000-00-00 a 1999-11-30 ???

Eu sei que eu poderia fazer comparação para ver se a data é um desses valores é igual à data eu tenho, mas não é uma maneira muito robusta para verificar. Existe uma boa maneira de verificar para ver se eu tenho uma data válida? Alguém tem uma boa função para verificar isso?

Edit: As pessoas estão perguntando o que eu estou correndo: Rodando o PHP 5.2.5 (CLI) (construído Julho 23, 2008 11:32:27) no Linux localhost 2.6.18-53.1.14.el5 # 1 SMP Wed 05 de marco 11:36:49 EST 2008 i686 i686 i386 GNU / Linux

Foi útil?

Solução

A partir php.net

<?php
function isValidDateTime($dateTime)
{
    if (preg_match("/^(\d{4})-(\d{2})-(\d{2}) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $dateTime, $matches)) {
        if (checkdate($matches[2], $matches[3], $matches[1])) {
            return true;
        }
    }

    return false;
}
?>

Outras dicas

Como mencionado aqui: https://bugs.php.net/bug.php? id = 45647

Não há erro aqui, 00-00-00 meios 2000-00-00, que é 1999-12-00, que é 1999-11-30. Sem bug, perfeitamente normal.

E como mostrado com alguns testes, rolando comportamento trás é esperado, se um pouco inquietante:

>> date('Y-m-d', strtotime('2012-03-00'))
string: '2012-02-29'
>> date('Y-m-d', strtotime('2012-02-00'))
string: '2012-01-31'
>> date('Y-m-d', strtotime('2012-01-00'))
string: '2011-12-31'
>> date('Y-m-d', strtotime('2012-00-00'))
string: '2011-11-30'

eco data ( 'Y-m-d', strtotime ($ data));

resulta em: "1999-11-30"

O resultado da strtotime é 943920000 - este é o número de segundos, mais ou menos, entre a época Unix (base a partir dos quais o tempo é medido) para 1999-11-30.

Há um documentado mysql bug em mktime(), localtime(), strtotime() tudo devolver este valor ímpar quando você tenta um tempo pré-época (incluindo "0000-00-00 00:00:00"). Há algum debate sobre o fio ligado para saber se este é realmente um erro:

Uma vez que o carimbo de tempo é iniciado de 1970, eu não acho que deveria trabalho em qualquer forma.

Abaixo está uma função que eu use para converter datetimes como o acima para um timestamp para comparações, etc, que podem ser de alguma utilidade para você, para datas além "0000-00-00 00:00:00"

/**
 * Converts strings of the format "YYYY-MM-DD HH:MM:SS" into php dates
 */
function convert_date_string($date_string)
{
    list($date, $time) = explode(" ", $date_string);
    list($hours, $minutes, $seconds) = explode(":", $time);
    list($year, $month, $day) = explode("-", $date);
    return mktime($hours, $minutes, $seconds, $month, $day, $year);
}

Não espere resultados coerentes quando você está fora do intervalo:

strtotime

Gnu Calendário-data-itens .html

"Durante meses numéricos, a ISO 8601 formato ‘ano-mês-dia’ é permitido, onde no ano é qualquer número positivo, mês é um número entre 01 e 12 e dia é um número entre 01 e 31 . UMA zero à esquerda deve estar presente se um número é inferior a dez. "

Assim, '0000-00-00' dá resultados estranhos, isso é! Lógico


"Além disso, não é tudo plataformas suportam timestamps negativos, portanto, o intervalo de datas pode ser limitado a não mais cedo do que o Unix época . Isto significa que, por exemplo, % E,% T, R e%% D (que pode ser mais) e datas anteriores a Janeiro 1 de 1970 não irá funcionar no Windows, alguns distribuições Linux, e alguns outros sistemas operacionais . "

strftime


Use a função checkdate vez (mais robusto):

mês: O mês é entre 1 e 12 inclusive .

dia: O dia está dentro do número permitido de dias para o dado mês. Leap Year s são tomadas em consideração.

ano: O ano é entre 1 e 32767 inclusiva .

Esta versão permite o campo estar vazio, tem datas em mm / dd / aa ou dd formato mm / / aaaa, permitem horas de um único dígito, acrescenta opcional am / pm, e corrige algumas falhas sutis no jogo do tempo .

Ainda permite que algumas vezes patológicos como '23:. 14 AM'

function isValidDateTime($dateTime) {
    if (trim($dateTime) == '') {
        return true;
    }
    if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{2,4})(\s+(([01]?[0-9])|(2[0-3]))(:[0-5][0-9]){0,2}(\s+(am|pm))?)?$/i', $dateTime, $matches)) {
        list($all,$mm,$dd,$year) = $matches;
        if ($year <= 99) {
            $year += 2000;
        }
        return checkdate($mm, $dd, $year);
    }
    return false;
}

Se você quiser apenas para lidar com uma conversão de data sem a hora de um campo de data mysql, você pode modificar este código grande como eu fiz. Na minha versão do PHP sem executar essa função eu recebo "0000-00-00" cada vez. Irritante.

function ConvertDateString ($DateString)
{
    list($year, $month, $day) = explode("-", $DateString);
    return date ("Y-m-d, mktime (0, 0, 0, $month, $day, $year));
}
<?php
function is_valid_date($user_date=false, $valid_date = "1900-01-01") {
    $user_date = date("Y-m-d H:i:s",strtotime($user_date));
    return strtotime($user_date) >= strtotime($valid_date) ? true : false;
}

echo is_valid_date("00-00-00") ? 1 : 0;    // return 0

echo is_valid_date("3/5/2011") ? 1 : 0;    // return 1

I foram apenas mudando a resposta martin acima, que irá validar qualquer tipo de data e retorno no formato que você quiser.

Apenas alterar o formato editando abaixo da linha de roteiro strftime ( "2012/10/10", strtotime ($ dt));

<?php
echo is_date("13/04/10");

function is_date( $str ) {
    $flag = strpos($str, '/');

    if(intval($flag)<=0){
        $stamp = strtotime( $str );
    } else {
        list($d, $m, $y) = explode('/', $str);    
        $stamp = strtotime("$d-$m-$y");
    } 
    //var_dump($stamp) ;

    if (!is_numeric($stamp)) {
        //echo "ho" ;
        return "not a date" ;        
    }

    $month = date( 'n', $stamp ); // use n to get date in correct format
    $day   = date( 'd', $stamp );
    $year  = date( 'Y', $stamp );

    if (checkdate($month, $day, $year)) {
        $dt = "$year-$month-$day" ;
        return strftime("%d-%b-%Y", strtotime($dt));
        //return TRUE;
    } else {
        return "not a date" ;
    }
}
?>

Eu tenho usado o seguinte código para datas Validar provenientes de aplicações ExtJS.

function check_sql_date_format($date) {
    $date = substr($date, 0, 10);
    list($year, $month, $day) = explode('-', $date);
    if (!is_numeric($year) || !is_numeric($month) || !is_numeric($day)) {
        return false;
    }
    return checkdate($month, $day, $year);
}
<?php

function is_date( $str ) {
    $stamp = strtotime( $str );

    if (!is_numeric($stamp)) {
        return FALSE;
    }
    $month = date( 'm', $stamp );
    $day   = date( 'd', $stamp );
    $year  = date( 'Y', $stamp );

    if (checkdate($month, $day, $year)) {
        return TRUE;
    }
    return FALSE;
}
?>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top