我正在尝试获取格式化的日期,包括以毫秒为单位指定的 UNIX 时间戳中的微秒。
唯一的问题是我不断得到 000000,例如
$milliseconds = 1375010774123;
$d = date("m-d-Y H:i:s.u", $milliseconds/1000);
print $d;
2013 年 7 月 28 日 11:26:14.000000
我正在尝试获取格式化的日期,包括以毫秒为单位指定的 UNIX 时间戳中的微秒。
唯一的问题是我不断得到 000000,例如
$milliseconds = 1375010774123;
$d = date("m-d-Y H:i:s.u", $milliseconds/1000);
print $d;
2013 年 7 月 28 日 11:26:14.000000
您可以使用输入格式轻松做到这一点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/en/function.number-format.php
回应 DaVe 时区的注释。
通常,createFromFormat()
如果未指定,该方法将使用本地时区。
http://php.net/manual/en/datetime.createfromformat.php
然而,这里描述的技术是初始化 DateTime 对象,使用microtime()
它返回自 Unix 纪元(格林威治标准时间 1970 年 1 月 1 日 00:00:00)以来经过的秒数。
http://php.net/manual/en/function.microtime.php
这意味着 DateTime 对象被隐式初始化为 UTC,这对于只想跟踪经过时间的服务器内部任务来说很好。
如果您需要显示特定时区的时间,则需要相应地设置它。但是,由于上述原因,这应该在初始化之后作为一个单独的步骤进行(不使用 的第三个参数)。createFromFormat()
该setTimeZone()
方法可用于实现这一要求。
http://php.net/manual/en/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")
php.net说:
微秒(在 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");
php.netdateTime()
上的参考
我已经回答了对作者来说简短而简单的问题。请参阅作者的更多信息:从毫秒获取日期格式 mdY H:i:su
这是一个稍微短一些的方法。我没有创建高精度数字日期/时间,而是将微秒值转换为字符串,删除0
,并将其添加到日期/时间字符串的末尾。我可以通过调整字符串长度参数轻松修剪小数位数;这里我4
用来获取毫秒,但你可以7
用来获取微秒。
$t = explode(" ",microtime());
echo date("m-d-y H:i:s",$t[1]).substr((string)$t[0],1,4);
对于 的 microtime() 值0.98236000 1407400573
,这将返回08-07-14 01:08:13.982
。
我用
echo date("Y-m-d H:i:s.").gettimeofday()["usec"];
output: 2017-09-05 17:04:57.555036
# 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
如果您需要限制小数位数,那么下面的行 (credit 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
该错误最近已修复,现在您可以使用带有小数部分的 UNIX 时间戳。
$milliseconds = 1375010774123;
$d = new DateTime( '@'. $milliseconds/1000 );
print $d->format("m-d-Y H:i:s.u");
输出:
07-28-2013 11:26:14.123000
您需要先指定 UNIX 时间戳的格式,然后才能在 DateTime 对象中使用它。如其他答案所述,您可以通过使用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");
输出:
07-28-2013 11:26:14.123000
如果您仍在使用早于 7.3 的 PHP,您可以替换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");
输出:
07-28-2013 11:26:14.123000
如果您出于某种原因想要像 JavaScript 那样格式化日期(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确实对小数位进行了四舍五入,但在两种情况下都以相同的方式四舍五入。
这是基于 ArchCodeMonkey 的回答。
但只是简化了,如果你只是想要一些快速有效的东西。
function 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");
从 PHP 7.1 开始,您可以简单地执行以下操作:
$date = new DateTime( "NOW" );
echo $date->format( "m-d-Y H:i:s.u" );
它将显示为:
04-11-2018 10:54:01.321688
这是另一种我觉得更优雅/更简单的方法:
echo date('Y-m-d-H:i:s.').preg_replace("/^.*\./i","", microtime(true));
// Procedural
$fineStamp = date('Y-m-d\TH:i:s') . substr(microtime(), 1, 9);
echo $fineStamp . PHP_EOL;
// Object-oriented (if you must). Still relies on $fineStamp though :-\
$d = new DateTime($fineStamp);
echo $d->format('Y-m-d\TH:i:s.u') . PHP_EOL;
该文档说明了以下内容:
微秒(在 PHP 5.2.2 中添加)。请注意, date() 将始终生成 000000,因为它需要一个整数参数,而 DateTime::format() 确实支持微秒。
即,改用 DateTime。
如果您使用的是 Carbon,则可以使用定义的规范“RFC3339_EXTENDED”。或自定义它。
Carbon::RFC3339_EXTENDED = 'Y-m-d\TH:i:s.vP';
php >= 7.3 的单行版本(用作函数参数):
printf("%s",
(DateTime::createFromFormat('U.u', microtime(true)))
->setTimezone(new \DateTimeZone('UTC'))
->format("Y-m-d.H:i:s.v")
);
见v
和格式u
_
现在使用 PHP 7.0+,您可以执行以下操作:
$dateString = substr($millseconds_go_here,0,10);
$drawDate = new \DateTime(Date('Y-m-d H:i',$dateString));
$drawDate->setTimezone(new \DateTimeZone('UTC'));
这按顺序执行以下操作:
Date()
处理日期。DateTime()
然后可以允许您修改您所在的时区,但请确保date_default_timezone_set("Timezone");
在使用DateTime()
函数和类之前进行设置。DateTime()
类或函数时处于正确的时区是一种很好的做法。此功能从 php5.2 一直工作到 php7.4。这里包括测试代码:
#!/usr/bin/php
<?php
function dtfn ($t=null) // for filenames, date + time, year first, ms always 3 digits
{
if (!$t) $t = microtime(true);
$dtx = date('Y-m-d_H.i.s', $t);
$ms = sprintf("%03u", 1000 * fmod($t,1));
return "$dtx.$ms";
}
function xxx($t)
{
echo sprintf("%12s: %s\n", $t, dtfn($t));
}
xxx(1);
xxx(1.0);
xxx(1.01);
xxx(1.0101);
xxx(1.23456789);
结果:
1: 1970-01-01_01.00.01.000
1: 1970-01-01_01.00.01.000
1.01: 1970-01-01_01.00.01.010
1.0101: 1970-01-01_01.00.01.010
1.23456789: 1970-01-01_01.00.01.234