贝利信息

PHP字符串转日期支持纪元吗_PHP纪元串转日期法【知识】

日期:2026-01-13 00:00 / 作者:蓮花仙者
PHP解析

纪元时间关键在格式与时区:strtotime("1970-01-01T00:00:00Z")得0,"0"返回当日零点,"1970-01-01"依赖本地时区;最可靠方式是DateTime::createFromFormat()显式指定格式与UTC。

PHP 的 strtotime()DateTime 类默认不直接识别“纪元串”(如 "1970-01-01T00:00:00Z" 这类 ISO 8601 格式中的纪元时间),但能正确解析它——关键不在“是否支持纪元”,而在于字符串格式是否被 PHP 日期解析器认可。

为什么 "1970-01-01" 能转,但 "0""1970-01-01T00:00:00+00:00" 有时失败?

PHP 解析字符串依赖内部的时区感知和格式启发式匹配。"0" 被当成数字字面量,strtotime("0") 实际返回当前时间零点(不是纪元),这是历史行为陷阱;而带时区偏移的 ISO 字符串(如 "1970-01-01T00:00:00+00:00")在 PHP 5.2+ 完全支持,但若省略时区或写成 "1970-01-01T00:00:00",则按本地时区解释,可能得到非零秒数的时间戳。

DateTime::createFromFormat() 是最可控的纪元字符串解析方式

当输入格式固定(比如你明确知道字符串是 "Y-m-d\TH:i:s\Z" 或纯数字时间戳),用 createFromFormat() 可绕过模糊解析,避免时区误判。

var_dump(DateTime::createFromFormat('Y-m-d\TH:i:s\Z', '1970-01-01T00:00:00Z')->getTimestamp());
// int(0)

var_dump(DateTime::createFromFormat('U', '0')->getTimestamp());
// int(0) —— 直接传入时间戳字符串也行

从字符串到纪元时间戳:三步验证法

别只看输出是否为 0,要确认它真代表 UTC 纪元起点。推荐组合判断:

$dt = DateTime::createFromFormat('Y-m-d\TH:i:s\Z', '1970-01-01T00:00:00Z');
$ts = $dt ? $dt->getTimestamp() : false;
if ($ts === 0 && date('c', $ts) === '1970-01-01T00:00:00+00:00') {
    echo "Confirmed epoch";
}

忽略时区上下文、混用 strtotime() 和无时区 DateTime 构造,是实际项目中最常导致“看似转成功、实则偏移 8 小时”的根源。