PHP中如何解析带毫秒的ISO 8601日期为DateTimeImmutable对象?
解决PHP解析含毫秒无时区的ISO格式日期为DateTimeImmutable的问题
核心问题分析
你之前的写法失败主要是混淆了PHP和C#的日期格式规则:
- PHP中4位年份用
Y而非YYYY,分钟用i而非ii - 转义字面量
T时,需在格式字符串中使用\T(单引号格式串)或\\T(双引号格式串) - 通配符
*无法弥补格式符本身的错误
正确解法
PHP 7.0+ 版本(支持毫秒格式符v)
直接使用正确的格式字符串解析,同时建议显式指定时区(因为原字符串无时区信息):
$s = '2018-07-17T17:34:08.167'; $date = \DateTimeImmutable::createFromFormat('Y-m-d\TH:i:s.v', $s, new \DateTimeZone('UTC')); // 验证解析结果 var_dump($date);
格式串说明:
Y:4位年份m/d:双位月份/日期\T:转义字面量T(也可用'T'替代,即'Y-m-d\'T\'H:i:s.v')H:24小时制双位小时i:双位分钟s:双位秒v:3位毫秒(PHP 7.0+新增)
PHP 5.x 版本(不支持v)
由于PHP 5.x没有专门的毫秒格式符,可先将毫秒补为6位微秒,再用u格式符解析:
$s = '2018-07-17T17:34:08.167'; // 把3位毫秒补全为6位微秒 $s = preg_replace('/\.(\d{3})$/', '.${1}000', $s); $date = \DateTimeImmutable::createFromFormat('Y-m-d\TH:i:s.u', $s, new \DateTimeZone('UTC')); var_dump($date);
额外说明
如果不需要显式指定时区,PHP会使用date.timezone配置的默认时区,但显式指定能避免环境差异导致的问题。
内容的提问来源于stack exchange,提问作者NobleUplift
相关产品推荐
相关产品推荐

