php 应使用 date('y-m-d\th:i:sp') 输出严格 rfc3339 格式时间,其中 p 自动输出带冒号的时区偏移(如 +08:00),而 date('c') 不符合 rfc3339 因其偏移无冒号(如 +0800)。

PHP 怎么用 date() 输出 RFC3339 格式时间
RFC3339 时间格式(如 2024-05-22T14:30:45+08:00)本质是 ISO 8601 的一个子集,PHP 原生不提供直接叫 rfc3339 的格式常量,但可以用 date() 拼出来——关键是时区偏移要带冒号(+08:00),不能只写 +0800。
最稳妥的方式是:先用 date('c') 得到 ISO 8601 字符串(如 2024-05-22T14:30:45+0800),再手动补冒号:
date('Y-m-d\TH:i:sP') // ✅ 正确,P 自动输出 +08:00
P 是 PHP 5.1.3+ 引入的格式字符,专为 RFC3339 设计,它会自动处理夏令时、输出带冒号的时区偏移,比自己 str_replace 更可靠。
为什么 date('c') 不算严格 RFC3339
date('c') 输出的是完整 ISO 8601(如 2024-05-22T14:30:45+0800),但 RFC3339 明确要求时区偏移必须含冒号(+08:00)。很多 API(比如 Google Calendar、AWS、OpenAPI 规范)会严格校验这个格式,遇到 +0800 直接报错 Invalid RFC3339 timestamp。
-
date('c')→2024-05-22T14:30:45+0800(❌ 不通过校验) -
date('Y-m-d\TH:i:sP')→2024-05-22T14:30:45+08:00(✅ 合规)
使用 DateTime 对象时怎么输出 RFC3339
如果你用的是 DateTime 实例(比如从数据库读出或解析用户输入),别直接调 $dt->format('c'),同样得用 P:
$dt = new DateTime('now', new DateTimeZone('Asia/Shanghai'));
echo $dt->format('Y-m-d\TH:i:sP'); // 输出带冒号的偏移
注意点:
- 确保
DateTime对象的时区已正确设置(setTimezone()或构造时传入),否则P会按默认时区输出 - 不要用
getOffset()手动拼字符串——它返回秒数,还要自己换算成+08:00,容易出错 - 如果需要 UTC 时间,用
$dt->setTimezone(new DateTimeZone('UTC'))再格式化,避免依赖服务器本地时区
JSON 输出时的常见坑
PHP json_encode() 默认不会把 DateTime 转成 RFC3339 字符串,它要么报错(对象不可序列化),要么输出空对象。你得手动转:
$data = [
'created_at' => (new DateTime())->format('Y-m-d\TH:i:sP')
];
echo json_encode($data); // ✅ 输出 "created_at": "2024-05-22T14:30:45+08:00"
容易忽略的是:如果时间来自 MySQL DATETIME 字段且没显式设时区,PHP 默认按系统时区解释,可能导致 P 输出错误偏移。建议统一在 PDO 连接时加 ?timezone=UTC,或入库/查询时明确转换。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











