我正在尝试获取一个格式化的日期,包括以毫秒为单位指定的UNIX时间戳中的微秒。
唯一的问题是我一直得到000000,例如:
$milliseconds = 1375010774123;
$d = date("m-d-Y H:i:s.u", $milliseconds/1000);
print $d;
2013年07月28日 11点26分14秒
我正在尝试获取一个格式化的日期,包括以毫秒为单位指定的UNIX时间戳中的微秒。
唯一的问题是我一直得到000000,例如:
$milliseconds = 1375010774123;
$d = date("m-d-Y H:i:s.u", $milliseconds/1000);
print $d;
2013年07月28日 11点26分14秒
你可以使用输入格式U.u
轻松地完成这个任务。
$now = DateTime::createFromFormat('U.u', microtime(true));
echo $now->format("m-d-Y H:i:s.u");
这会产生以下输出:
04-13-2015 05:56:22.082300
来自PHP手册日期格式页面:
http://php.net/manual/en/function.date.php
感谢giggsey指出我原来回答中的一个缺陷,将number_format()
添加到代码行中可以解决确切秒数的问题。遗憾的是,它现在感觉不那么优雅了...
$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
http://php.net/manual/zh/function.number-format.php
关于时区的说明,回应 DaVe 的问题。
createFromFormat()
方法通常会使用本地时区(如果没有指定的话)。
http://php.net/manual/zh/datetime.createfromformat.php
然而,这里描述的技术使用 microtime()
初始化 DateTime 对象,它返回自 Unix 纪元(1970 年 1 月 1 日 00:00:00 GMT)以来经过的秒数。
http://php.net/manual/zh/function.microtime.php
这意味着 DateTime 对象被隐式地初始化为 UTC,这对于仅想跟踪经过时间的服务器内部任务是可以的。
如果您需要显示特定时区的时间,则需要相应地设置它。但是,由于上述原因,这应该作为初始步骤之后的单独步骤完成(不要使用 createFromFormat()
的第三个参数)。
可以使用 setTimeZone()
方法来实现此需求。
http://php.net/manual/zh/datetime.settimezone.php
例如:
$now = DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
echo $now->format("m-d-Y H:i:s.u") . '<br>';
$local = $now->setTimeZone(new DateTimeZone('Australia/Canberra'));
echo $local->format("m-d-Y H:i:s.u") . '<br>';
产生以下输出:
10-29-2015 00:40:09.433818
10-29-2015 11:40:09.433818
请注意,如果您想将时间输入到MySQL中,则时间格式需要如下:
format("Y-m-d H:i:s.u")
microtime(true)
正好在整秒时运行,DateTime::createFromFormat('U.u', microtime(true));
将返回 false。它会返回 '1438616239' 而不是 '1438616239.000000'。 - giggseynumber_format
始终是必需的,即使它不在确切的第二位。否则,您将受到 precision
PHP 配置选项(用于“显示”)的限制,默认情况下 PHP 7.0 的精度不足,导致精度损失(不准确到微秒)。 - Teoh Han HuiPHP官网上提到:
微秒(在 PHP 5.2.2 中添加)。请注意,由于
date()
接受整数参数,所以它始终会生成000000
,而DateTime::format()
支持微秒,如果DateTime
是使用微秒创建的。
因此,简单使用:
$micro_date = microtime();
$date_array = explode(" ",$micro_date);
$date = date("Y-m-d H:i:s",$date_array[1]);
echo "Date: $date:" . $date_array[0]."<br>";
建议使用引用中的dateTime()
类:
$t = microtime(true);
$micro = sprintf("%06d",($t - floor($t)) * 1000000);
$d = new DateTime( date('Y-m-d H:i:s.'.$micro, $t) );
print $d->format("Y-m-d H:i:s.u"); // note at point on "u"
注意:u
代表微秒(1秒 = 1000000 µs)。
另一个来自php.net的例子:
$d2=new DateTime("2012-07-08 11:14:15.889342");
dateTime()
的参考文档位于 php.net。
我已经简短地回答了作者的问题。更多信息请参见: 获取毫秒数的日期格式 m-d-Y H:i:s.u
microtime(false)
也无法使用。) - Sz.2012-07-08 11:14:15.0.889342
。 - Daniel MarschallDeprecated: Implicit conversion from float 1664568100.74341 to int loses precision
,因为 microtime(true)
返回了这个值。 - Parminder Singh我在使用
echo date("Y-m-d H:i:s.").gettimeofday()["usec"];
output: 2017-09-05 17:04:57.555036
这里有一个稍微简短的方法。不需要创建高精度的日期/时间,我将微秒值转换为字符串,去掉0
,然后将其添加到日期/时间字符串的末尾。通过调整字符串长度参数,可以轻松地裁剪小数位数;在这里,我使用4
来获取毫秒,但您也可以使用7
来获取微秒。
$t = explode(" ",microtime());
echo date("m-d-y H:i:s",$t[1]).substr((string)$t[0],1,4);
0.98236000 1407400573
,此代码将返回 08-07-14 01:08:13.982
。# PHP 8 type safe when using declare(strict_types=1);
echo date('m-d-Y H:i:s').substr((string) fmod(microtime(true), 1), 1, 4);
示例输出:
02-06-2019 16:45:03.53811192512512
如果您需要限制小数点位数,则下面这行代码(来自mgutt的贡献)是一个不错的选择。(在下面的代码中,数字6限制小数点位数为6。)
echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));
示例输出:
02-11-2019 15:33:03.624493
echo date('m-d-Y H:i:').sprintf('%09.6f', date('s')+fmod(microtime(true), 1));
。为什么我们需要 09
的解释:https://dev59.com/614b5IYBdhLWcg3wvT6w#28739819。 - mguttecho date('H:i:s').substr(fmod(microtime(true), 1), 1, 7);
- mguttsubstr()
不会四舍五入。而且与 round()
结合使用时,它会截断尾随的零:https://dev59.com/wWs05IYBdhLWcg3wB9ef 这就是我建议使用 sprintf()
的原因。 - mgutt该错误最近已修复,现在您可以使用带有小数部分的UNIX时间戳。
$milliseconds = 1375010774123;
$d = new DateTime( '@'. $milliseconds/1000 );
print $d->format("m-d-Y H:i:s.u");
输出:
2013年07月28日 11:26:14.123000
在使用 DateTime 对象之前,您需要指定 UNIX 时间戳的格式。正如其他答案中所指出的那样,您可以通过使用 createFromFormat()
和 number_format()
来解决这个问题。
$milliseconds = 1375010774123;
$d = DateTime::createFromFormat('U.v', number_format($milliseconds/1000, 3, '.', ''));
print $d->format("m-d-Y H:i:s.u");
输出:
2013年7月28日 11:26:14.123000
如果你仍在使用PHP早于7.3的版本,可以将U.v
替换为U.u
。这不会有任何影响,但是毫秒格式标识符只出现在PHP 7.3之后。
$milliseconds = 1375010774123;
// V - Use microseconds instead of milliseconds
$d = DateTime::createFromFormat('U.u', number_format($milliseconds/1000, 3, '.', ''));
print $d->format("m-d-Y H:i:s.u");
输出:
2013年7月28日11点26分14.123秒
$date = new DateTime( "NOW" );
echo $date->format( "m-d-Y H:i:s.u" );
04-11-2018 10:54:01.321688
(new Date()).toISOString()
的格式来格式化日期,这是您可以在PHP中执行的操作:$now = microtime(true);
gmdate('Y-m-d\TH:i:s', $now).sprintf('.%03dZ',round(($now-floor($now))*1000));
样例输出:
2016-04-27T18:25:56.696Z
仅为证明减去整数不会降低小数部分的精度:
>>> number_format(123.01234567890123456789,25)
=> "123.0123456789012408307826263"
>>> number_format(123.01234567890123456789-123,25)
=> "0.0123456789012408307826263"
PHP确实对小数位进行了四舍五入,但在这两种情况下它采用了相同的方式进行四舍五入。
date('Y-m-d\TH:i:s', $time / 1000) . sprintf('.%03dZ', substr($time, 10));
呢? - Artfaith$time
是毫秒,但 2286
又怎么样呢?我的意思是,你为什么这么认为,如何才能避免这种情况? - Artfaithsubstr(..., 10)
假设了一个特定的数字数量。在2286年,时间戳将会增加一位数字。 - mpenfunction DateTime_us_utc(){
return DateTime::createFromFormat('U.u', number_format(microtime(true), 6, '.', ''));
}
function DateTime_us(){
$now = DateTime_us_utc();
return $now->setTimeZone(new DateTimeZone(date_default_timezone_get()));
}
$now = DateTime_us();
$now->format("m-d-Y H:i:s.u");
echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));