web-dev-qa-db-fra.com

Vérifier si la chaîne est un timestamp Unix

J'ai une chaîne et je dois savoir s'il s'agit d'un horodatage Unix ou non, comment puis-je le faire efficacement?

J'ai trouvé ce fil via Google, mais la réponse n'est pas très solide, j'en ai bien peur. (Et oui, j'ai écrit la question de l'affiche originale sur le fil susmentionné).

63
RHPT

Ok, après avoir manipulé cela pendant un certain temps, je retire la solution avec date('U') et suggère d'utiliser celle-ci à la place:

function isValidTimeStamp($timestamp)
{
    return ((string) (int) $timestamp === $timestamp) 
        && ($timestamp <= PHP_INT_MAX)
        && ($timestamp >= ~PHP_INT_MAX);
}

Cette vérification ne renverra que si le $timestamp donné est un string et consiste uniquement en chiffres et en un caractère moins facultatif. Le nombre doit également se situer dans la plage de bits d'un entier (EDIT: réellement inutile, comme indiqué ici ).

var_dump( isValidTimeStamp(1)             ); // false
var_dump( isValidTimeStamp('1')           ); // TRUE
var_dump( isValidTimeStamp('1.0')         ); // false
var_dump( isValidTimeStamp('1.1')         ); // false
var_dump( isValidTimeStamp('0xFF')        ); // false
var_dump( isValidTimeStamp('0123')        ); // false
var_dump( isValidTimeStamp('01090')       ); // false
var_dump( isValidTimeStamp('-1000000')    ); // TRUE
var_dump( isValidTimeStamp('+1000000')    ); // false
var_dump( isValidTimeStamp('2147483648')  ); // false
var_dump( isValidTimeStamp('-2147483649') ); // false

La vérification de PHP_INT_MAX permet de s’assurer que votre chaîne peut être utilisée correctement par date et les «j'aime», par exemple. cela garantit que cela n'arrive pas *:

echo date('Y-m-d', '2147483648');  // 1901-12-13
echo date('Y-m-d', '-2147483649'); // 2038-01-19

Sur les systèmes 64 bits, le nombre entier est évidemment supérieur à celui et la fonction ne retournera plus faux pour "2147483648" et "-2147483649" mais pour les plus grands nombres correspondants.


(*) Remarque: je ne suis pas sûr à 100%, la plage de bits correspond à la date d'utilisation possible

89
Gordon

Comme un horodatage Unix est un entier, utilisez is_int () . Cependant, étant donné que is_int () ne fonctionne pas sur les chaînes, nous vérifions s'il est numérique et que sa forme intergale est identique à sa forme originale. Exemple:

( is_numeric($stamp) && (int)$stamp == $stamp )
37
Yacoby

Je suis tombé sur la même question et j'ai créé la solution suivante pour moi-même, dans laquelle je n'ai pas à manipuler les expressions régulières ni les clauses if désordonnées:

/**
 * @param string $string
 * @return bool
 */
public function isTimestamp($string)
{
    try {
        new DateTime('@' . $string);
    } catch(Exception $e) {
        return false;
    }
    return true;
}
10
simplychrislike

cela ressemble à la voie à suivre:

function is_timestamp($timestamp) {
    if(strtotime(date('d-m-Y H:i:s',$timestamp)) === (int)$timestamp) {
        return $timestamp;
    } else return false;
}

vous pouvez également ajouter une vérification is_numeric () et toutes sortes d'autres vérifications.
mais cela devrait/pourrait être la base.

7
TD_Nijboer

Cela ne prend pas en compte les temps négatifs (avant 1970), ni les plages étendues (vous pouvez utiliser des entiers 64 bits pour qu'un horodatage puisse représenter une valeur bien après 2038).

$valid = ctype_digit($str) && $str <= 2147483647;
3
goat

Réponse améliorée à @TD_Nijboer.

Cela évitera qu'une exception ne soit levée si la chaîne fournie n'est pas un horodatage:

function isTimestamp($timestamp) {
    if(ctype_digit($timestamp) && strtotime(date('Y-m-d H:i:s',$timestamp)) === (int)$timestamp) {
        return true;
    } else {
        return false;
}
3

Vous voulez vérifier si une chaîne contient un nombre élevé?

is_numeric () est la clé

Ou bien convertissez-le en DateTime et effectuez quelques vérifications avec elle comme une plage de dates prévue.

1

Une autre possibilité:

$date_arg = time();
$date_is_ok = ($date_arg === strtotime(date('c', $date_arg)));
0
Chris
    //if anything else than digits inside the string then your string is no timestamp 
    //in which case maybe try to get the timestamp with strtotime

    if(preg_match('/[^\d]/', $str)) {
        $str = strtotime($str);

        if (false === $str) {
            //conversion failed - invalid time - invalid row
            return;
        }
    }
0
alex toader

ou 

if ($startDate < strtotime('-30 years') || $startDate > strtotime('+30 years')) {
    //throw exception
}
0
alex toader

Si vous pensez peut-être remplacer this solution par is_numeric () , veuillez considérer que la fonction native php fournit de faux positifs pour les chaînes d’entrée telles que "1.1", "0123", "0xFF" qui ne sont pas dans l’horodatage format.

0