filemtime() 返回服务器本地时区的 unix 时间戳(秒级),未经时区转换;其值取决于系统 st_mtime,而 date() 显示结果受 php 时区设置影响,与 ls -l 显示差异源于时区不一致。

filemtime() 返回的是服务器本地时区下的时间戳,不是 UTC,也不是你本地电脑的时区 —— 这是绝大多数人第一次用就出错的根源。
filemtime() 返回的时间戳到底代表什么
它调用的是系统 stat() 系统调用的 st_mtime 字段,本质是 Unix 时间戳(秒级),但 PHP 不做时区转换,直接原样返回。也就是说:
- 如果服务器时区设为
Asia/Shanghai,filemtime()值对应的就是东八区时间点的秒数(比如 2024-05-20 14:30:00 CST → 时间戳1716215400) - 如果服务器时区是
UTC,那它就是 UTC 时间点 -
date('Y-m-d H:i:s', filemtime($path))输出的结果,取决于date_default_timezone_set()的设置,而非filemtime()本身做了转换
为什么 date() 显示时间和文件属性里看到的不一样
Linux ls -l 默认按本地时区显示修改时间,而 PHP 的 date() 函数受 date_default_timezone_set() 控制 —— 两者时区不一致就会对不上。
- 检查服务器时区:
cat /etc/timezone或timedatectl - 检查 PHP 时区:
echo date_default_timezone_get(); - 常见坑:服务器是 UTC,但 PHP 设了
Asia/Shanghai,date()就会比ls -l多显示 8 小时 - 安全做法:统一用
date_default_timezone_set('UTC'),再显式格式化,避免隐式转换
filemtime() 失败时的典型错误和排查步骤
返回 false 是最常遇到的问题,不是函数坏了,而是权限或路径出了问题。
- 错误信息通常是:
Warning: filemtime(): stat failed for /path/to/file - 先确认路径存在且是文件:
is_file($path) && is_readable($path) - 注意符号链接:默认不追踪,要获取目标文件时间需先
realpath($path) - Web 服务器用户(如
www-data或nginx)可能无权读取该文件,尤其在 SELinux 或 Docker 容器中 - NFS 或某些网络文件系统可能禁用
mtime缓存更新,导致返回陈旧值甚至失败
需要比较文件新旧时,别直接比时间戳字符串
时间戳本身就是整数,直接比大小最可靠;转成字符串再解析纯属自找麻烦,还容易因时区/格式出错。
- ✅ 正确:
if (filemtime($a) > filemtime($b)) { ... } - ❌ 错误:
if (strtotime(date('c', filemtime($a))) > strtotime(date('c', filemtime($b)))) - 注意浮点精度陷阱:PHP 8.1+ 的
filemtime()仍只返回秒级整数,不支持毫秒;若需更高精度,得用filemtime()+stat()中的mtime字段组合(但移植性差) - 缓存考虑:PHP 会缓存文件状态,连续多次调用
filemtime()可能返回相同结果,必要时加clearstatcache(true, $path)
真正麻烦的从来不是怎么取时间戳,而是你没意识到服务器时区、PHP 时区、文件系统挂载方式、Web 用户权限这四者之间只要有一个不匹配,filemtime() 就会安静地给你一个“看似合理实则错位”的值。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











