这段代码总是在PHP 5.2.5中返回0微秒:
<?php
$dt = new DateTime();
echo $dt->format("Y-m-d\TH:i:s.u") . "\n";
?>
输出:
[root@www1 ~]$ php date_test.php
2008-10-03T20:31:26.000000
[root@www1 ~]$ php date_test.php
2008-10-03T20:31:27.000000
[root@www1 ~]$ php date_test.php
2008-10-03T20:31:27.000000
[root@www1 ~]$ php date_test.php
2008-10-03T20:31:28.000000
有什么想法吗?
答案 0 :(得分:26)
这似乎有效,尽管http://us.php.net/date记录微秒说明符但却不真正支持它似乎不合逻辑:
function getTimestamp()
{
return date("Y-m-d\TH:i:s") . substr((string)microtime(), 1, 8);
}
答案 1 :(得分:19)
您可以在构造DateTime
对象时指定输入包含微秒,并直接使用microtime(true)
作为输入。
不幸的是,如果你达到精确的秒数,这将失败,因为微量时间输出中没有.
;所以在这种情况下使用sprintf
强制它包含.0
:
date_create_from_format(
'U.u', sprintf('%.f', microtime(true))
)->format('Y-m-d\TH:i:s.uO');
或等效(更多OO风格)
DateTime::createFromFormat(
'U.u', sprintf('%.f', microtime(true))
)->format('Y-m-d\TH:i:s.uO');
答案 2 :(得分:16)
function udate($format, $utimestamp = null)
{
if (is_null($utimestamp))
$utimestamp = microtime(true);
$timestamp = floor($utimestamp);
$milliseconds = round(($utimestamp - $timestamp) * 1000000);
return date(preg_replace('`(?<!\\\\)u`', $milliseconds, $format), $timestamp);
}
echo udate('H:i:s.u'); // 19:40:56.78128
非常麻烦你必须实现这个功能才能让“你”工作......:\
答案 3 :(得分:14)
试试这个并显示微秒:
$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");
答案 4 :(得分:8)
\DateTime::createFromFormat('U.u', microtime(true));
会给你(至少在大多数系统上):
object(DateTime)(
'date' => '2015-03-09 17:27:39.456200',
'timezone_type' => 3,
'timezone' => 'Australia/Darwin'
)
但是由于PHP浮动舍入而导致精度下降。它不是真正的微秒。
<强>更新强>
这可能是createFromFormat()
选项的最佳折衷方案,并提供完全精确度。
\DateTime::createFromFormat('0.u00 U', microtime());
<强>函数gettimeofday()强>
更明确,也许更强大。解决了Xavi发现的错误。
$time = gettimeofday();
\DateTime::createFromFormat('U.u', sprintf('%d.%06d', $time['sec'], $time['usec']));
答案 5 :(得分:5)
是的,我想一劳永逸地解决这个问题。
有关如何显示ISO 8601格式日期&amp;的说明PHP中的时间,毫秒秒,微秒......
milli 秒或'ms'在小数点后有4位数,例如0.1234。 微秒或'μs'在小数点后有7位数。秒数分数/名称说明here
PHP的date()
函数的行为与毫秒或微秒没有完全相同,因为只有整数,如格式字符'u'下的php date docs所述。
基于Lucky的评论想法(here),但更正了PHP语法并正确处理秒格式(Lucky的代码在秒后添加了错误的额外'0'
这些也消除了竞争条件并正确地格式化了秒数。
工作等同于date('Y-m-d H:i:s').".$milliseconds";
list($sec, $usec) = explode('.', microtime(true));
echo date('Y-m-d H:i:s.', $sec) . $usec;
输出= 2016-07-12 16:27:08.5675
date('Y-m-d H:i:s').".$microseconds";
或date('Y-m-d H:i:s.u')
的工作等效,如果日期函数的行为符合预期,并带有微秒/ microtime()
/'u'
list($usec, $sec) = explode(' ', microtime());
echo date('Y-m-d H:i:s', $sec) . substr($usec, 1);
输出= 2016-07-12 16:27:08.56752900
答案 6 :(得分:4)
这对我有用,并且是一个简单的三线:
function udate($format='Y-m-d H:i:s.', $microtime=NULL) {
if(NULL === $microtime) $microtime = microtime();
list($microseconds,$unix_time) = explode(' ', $microtime);
return date($format,$unix_time) . array_pop(explode('.',$microseconds));
}
默认情况下(没有提供参数)将返回此格式的字符串,用于调用它的当前微秒:
YYYY-MM-DD HH:MM:SS.UUUUUUUU
更简单/更快的(虽然精度只有一半)如下:
function udate($format='Y-m-d H:i:s.', $microtime=NULL) {
if(NULL === $microtime) $microtime = microtime(true);
list($unix_time,$microseconds) = explode('.', $microtime);
return date($format,$unix_time) . $microseconds;
}
这个会以下列格式打印出来:
YYYY-MM-DD HH:MM:SS.UUUU
答案 7 :(得分:1)
在Lucky的comment和feature request in the PHP bug database工作,我使用的是这样的:
class ExtendedDateTime extends DateTime {
/**
* Returns new DateTime object. Adds microtime for "now" dates
* @param string $sTime
* @param DateTimeZone $oTimeZone
*/
public function __construct($sTime = 'now', DateTimeZone $oTimeZone = NULL) {
// check that constructor is called as current date/time
if (strtotime($sTime) == time()) {
$aMicrotime = explode(' ', microtime());
$sTime = date('Y-m-d H:i:s.' . $aMicrotime[0] * 1000000, $aMicrotime[1]);
}
// DateTime throws an Exception with a null TimeZone
if ($oTimeZone instanceof DateTimeZone) {
parent::__construct($sTime, $oTimeZone);
} else {
parent::__construct($sTime);
}
}
}
$oDate = new ExtendedDateTime();
echo $oDate->format('Y-m-d G:i:s.u');
输出:
2010-12-01 18:12:10.146625
答案 8 :(得分:1)
这个怎么样?
$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>";
示例输出
2013-07-17 08:23:37:0.88862400
答案 9 :(得分:1)
这应该是最灵活和最精确的:
function udate($format, $timestamp=null) {
if (!isset($timestamp)) $timestamp = microtime();
// microtime(true)
if (count($t = explode(" ", $timestamp)) == 1) {
list($timestamp, $usec) = explode(".", $timestamp);
$usec = "." . $usec;
}
// microtime (much more precise)
else {
$usec = $t[0];
$timestamp = $t[1];
}
// 7 decimal places for "u" is maximum
$date = new DateTime(date('Y-m-d H:i:s' . substr(sprintf('%.7f', $usec), 1), $timestamp));
return $date->format($format);
}
echo udate("Y-m-d\TH:i:s.u") . "\n";
echo udate("Y-m-d\TH:i:s.u", microtime(true)) . "\n";
echo udate("Y-m-d\TH:i:s.u", microtime()) . "\n";
/* returns:
2015-02-14T14:10:30.472647
2015-02-14T14:10:30.472700
2015-02-14T14:10:30.472749
*/
答案 10 :(得分:1)
time:strtotime()接受格式的字符串,默认为“now”。
time:根据GNU»Date Input Formats语法解析的字符串。在PHP 5.0.0之前,当时不允许使用微秒,因为PHP 5.0.0允许但忽略它们。
答案 11 :(得分:0)
在我写的应用程序内部,我需要在DateTime对象上设置/显示microtime。似乎让DateTime对象识别微秒的唯一方法是使用格式为“YYYY-MM-DD HH:MM:SS.uuuuuu”的时间初始化它。日期和时间部分之间的空间也可以是ISO8601格式中的“T”。
以下函数返回初始化为本地时区的DateTime对象(当然需要修改代码以满足个人需求):
// Return DateTime object including microtime for "now"
function dto_now()
{
list($usec, $sec) = explode(' ', microtime());
$usec = substr($usec, 2, 6);
$datetime_now = date('Y-m-d H:i:s\.', $sec).$usec;
return new DateTime($datetime_now, new DateTimeZone(date_default_timezone_get()));
}
答案 12 :(得分:0)
PHP文档清楚地说“请注意,date()将始终生成000000,因为它需要一个整数参数... ”。如果您想快速替换date()
函数,请使用以下函数:
function date_with_micro($format, $timestamp = null) {
if (is_null($timestamp) || $timestamp === false) {
$timestamp = microtime(true);
}
$timestamp_int = (int) floor($timestamp);
$microseconds = (int) round(($timestamp - floor($timestamp)) * 1000000.0, 0);
$format_with_micro = str_replace("u", $microseconds, $format);
return date($format_with_micro, $timestamp_int);
}
(可在此处获取:date_with_micro.php)
答案 13 :(得分:0)
strtotime()接受的格式的字符串 它有效!
答案 14 :(得分:0)
在Lucky的评论的基础上,我写了一个简单的方法来在服务器上存储消息。在过去,我使用哈希值和增量来获取唯一的文件名,但微秒的日期适用于此应用程序。
// Create a unique message ID using the time and microseconds
list($usec, $sec) = explode(" ", microtime());
$messageID = date("Y-m-d H:i:s ", $sec) . substr($usec, 2, 8);
$fname = "./Messages/$messageID";
$fp = fopen($fname, 'w');
这是输出文件的名称:
2015-05-07 12:03:17 65468400
答案 15 :(得分:0)
有些答案会使用多个时间戳,这在概念上是错误的,并且可能会出现重叠问题:21:15:05.999
的秒数与21:15:06.000
的微秒相加21:15:05.000
。
显然,最简单的方法是将DateTime::createFromFormat()
与U.u
一起使用,但as stated in a comment,如果没有微秒则会失败。
所以,我建议这段代码:
function udate($format, $time = null) {
if (!$time) {
$time = microtime(true);
}
// Avoid missing dot on full seconds: (string)42 and (string)42.000000 give '42'
$time = number_format($time, 6, '.', '');
return DateTime::createFromFormat('U.u', $time)->format($format);
}
答案 16 :(得分:-1)
此方法比接受的答案更安全:
date('Y-m-d H:i:s.') . str_pad(substr((float)microtime(), 2), 6, '0', STR_PAD_LEFT)
输出:
2012-06-01 12:00:13.036613
更新:不推荐(见评论)
答案 17 :(得分:-2)
日期('u')仅支持PHP 5.2。你的PHP可能会更老!