PHP 5.2以下strtotime()存在年份截断风险,应优先改用带时间后缀的格式或手动mktime()解析,并校验四位年份;PHP 4.x须手写拆分日期并转整数防八进制误读;时区需硬编码偏移;兼容方案应封装仅支持标准分隔符的safe_strtotime函数。
strtotime() 要小心年份截断PHP 5.1 及更早版本的 strtotime() 对四位年份支持不稳定,遇到 "2025-10-05" 这类字符串可能返回 false 或错误解析成 1923 年。根本原因是底层 C 库(如 GNU libc)在旧 PHP 绑定时未启用完整年份解析逻辑。
"2025-10-05" 改成 "2025-10-05 00:00:00" 再传给 strtotime()
"20251005" —— 旧版几乎一定失败if (preg_match('/^(\d{4})-(\d{1,2})-(\d{1,2})/', $dateStr, $m)) { ... }mktime() 拆解日期字符串PHP 4 没有 DateTime 类,strtotime() 对中文、带符号、非 ISO 格式极不友好。唯一可靠路径是手动提取年月日,再喂给 mktime()。
"2025/10/05" 或 "2025-10-05",用 explode() + intval() 安全拆分"09" 会被当八进制解析(PHP 4 默认行为)$parts = explode('-', $dateStr);
$year = intval($parts[0]);
$month = intval($parts[1]);
$day = intval($parts[2]);
$timestamp = mktime(0, 0, 0, $month, $day, $year);PHP 5.1 才引入 date_default_timezone_set(),更早版本连这个函数都没有。所有 date()、mktime() 返回的时间都按系统本地时区算,且无法运行时切换。
$timestamp += 8 * 3600;
gmdate() 是唯一能稳定输出 UTC 时间的函数,但输入仍是本地时间戳,不能反向修正输入putenv("TZ=Asia/Shanghai") —— PHP 4 和部分 5.0 环境下该调用被忽略面对混合环境(可能跑在 PHP 4.4 也可能在 5.2),不要依赖版本检测,直接用最保守写法覆盖全部旧版。
立即学习“PHP免费学习笔记(深入)”;
YYYY-MM-DD、YYYY/MM/DD、YYYY.MM.DD 三种格式false
mktime() 路径,绕过 strtotime() 的不可控行为function safe_strtotime($dateStr) {
if (!preg_match('/^(\d{4})[-\/\.](\d{1,2})[-\/\.](\d{1,2})$/', $dateStr, $m)) {
return false;
}
$y = (int)$m[1]; $mth = (int)$m[2]; $d = (int)$m[3];
return mktime(0, 0, 0, $mth, $d, $y);
}