You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DateTime::createFromFormat随机失败的原因是什么?

为什么DateTime::createFromFormat有时成功有时失败?

问题场景

在Yii2项目中遇到DateTime解析不稳定的问题,为此编写了以下测试脚本:

<?php

$microtime = microtime(true);
echo $microtime . PHP_EOL;

$now = DateTime::createFromFormat('U.u', $microtime);
if (!$now):
    echo "DateTime::createFromFormat failed..." . PHP_EOL;
    exit(1);
endif;

echo $now->format("m-d-Y H:i:s.u") . PHP_EOL;

测试运行结果

连续多次运行脚本,结果时成功时失败:

[test@my-dev-1 ~]$ php test.php
1665274706.459722
10-09-2022 00:18:26.459722
[test@my-dev-1 ~]$ php test.php
1665274708.4653969
DateTime::createFromFormat failed...
[test@my-dev-1 ~]$ php test.php
\1665274721.9026799
DateTime::createFromFormat failed...
[test@my-dev-1 ~]$ php test.php
1665274723.7216589
DateTime::createFromFormat failed...
[test@my-dev-1 ~]$ php test.php
1665274724.6398611
DateTime::createFromFormat failed...
[test@my-dev-1 ~]$ php test.php
1665274725.429971
10-09-2022 00:18:45.429971
[test@my-dev-1 ~]$ php test.php
1665274726.474606
10-09-2022 00:18:46.474606
[test@my-dev-1 ~]$ php test.php
1665274727.37256
10-09-2022 00:18:47.372560
[test@my-dev-1 ~]$ php test.php
1665274728.3463521
DateTime::createFromFormat failed...
[test@my-dev-1 ~]$ php test.php
1665274729.4645841
DateTime::createFromFormat failed...
[test@my-dev-1 ~]$ php test.php
1665274730.809057
10-09-2022 00:18:50.809057  

服务器环境

  • 系统:CentOS Linux release 7.9.2009 (Core)
  • PHP版本:
PHP 7.4.32 (cli) (built: Sep 28 2022 09:09:55) ( NTS )

原因分析

问题出在microtime(true)的输出格式与DateTime::createFromFormat使用的U.u格式不匹配:

  • U.u格式中,U代表Unix时间戳(整数部分),u代表6位微秒数
  • microtime(true)返回的是浮点数,当系统提供的精度超过6位时,输出的字符串会包含7位小数(比如1665274708.4653969),此时u无法匹配7位小数,导致解析失败
  • 当输出的小数部分≤6位时(比如1665274706.459722或1665274727.37256),u可以正确匹配(不足6位时会自动补0),所以解析成功

解决方案

确保传入DateTime::createFromFormat的时间字符串小数部分固定为6位,修改测试脚本如下:

<?php

$microtime = microtime(true);
echo $microtime . PHP_EOL;

// 格式化时间戳为6位小数的字符串,保证与U.u格式匹配
$formattedTime = sprintf("%.6f", $microtime);
$now = DateTime::createFromFormat('U.u', $formattedTime);

if (!$now):
    echo "DateTime::createFromFormat failed..." . PHP_EOL;
    exit(1);
endif;

echo $now->format("m-d-Y H:i:s.u") . PHP_EOL;

或者也可以通过number_format处理:

$formattedTime = number_format($microtime, 6, '.', '');

修改后,无论microtime(true)返回多少位小数,都会被统一格式化为6位小数,确保U.u格式可以正确解析。

内容的提问来源于stack exchange,提问作者Andreas Hinderberger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 01:50:24