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é).
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
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 )
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;
}
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.
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;
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;
}
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.
Une autre possibilité:
$date_arg = time();
$date_is_ok = ($date_arg === strtotime(date('c', $date_arg)));
//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;
}
}
ou
if ($startDate < strtotime('-30 years') || $startDate > strtotime('+30 years')) {
//throw exception
}
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.