I have a method in a class, which checks if a file is older than a day. It achieves this by getting the last change date of the file and comparing it with "now":
private function checkFileOutdated(string $filePath): bool
{
if (file_exists($filePath)) {
$fileTimeStamp = filectime($filePath);
$now = new DateTimeImmutable();
$fileDate = new DateTimeImmutable('@' . $fileTimeStamp);
$diff = (int) $now->format('Ymd') - (int) $fileDate->format('Ymd');
return $diff > 0;
}
return true;
}
I want to write a Unittest faking an outdated file. I tried to change the file date with touch:
$location = '/var/www/var/xls/myfile.xlsx';
$handle = fopen($location, 'wb');
fclose($handle);
exec('touch -a -m -t 202109231158 ' . $location);
exec('ls -hl ' . $location, $output);
var_dump($output);
The output gives me the information that in fact my file is from "Sep 23 11:58", Yeay.....
But my test is failing and when I debug my file date is today and not September, the 23rd.
Using filemtime results in the same.
Is it possible to fake a file timestamp?
My system runs on an alpine linux.
CodePudding user response:
Note you don't have to create the file first, because touch does that for you. And there is a PHP built-in for touch()
, you don't have to shell exec:
touch('/tmp/foo', strtotime('-1 day'));
echo date('r', fileatime('/tmp/foo')), "\n";
echo date('r', filectime('/tmp/foo')), "\n";
echo date('r', filemtime('/tmp/foo')), "\n";
This yields:
Tue, 02 Nov 2021 12:18:17 -0400
Wed, 03 Nov 2021 12:18:17 -0400
Tue, 02 Nov 2021 12:18:17 -0400
Applying your code but with filemtime
:
$fileTimeStamp = filemtime($filePath);
$now = new DateTimeImmutable();
$fileDate = new DateTimeImmutable('@' . $fileTimeStamp);
$diff = (int) $now->format('Ymd') - (int) $fileDate->format('Ymd');
var_dump($diff);
Yields the desired truthy value:
1
However, this is a rather roundabout comparison. I'd just compare the timestamp values directly:
return filemtime('/tmp/foo') <= strtotime('-1 day');