PHP DateTime 微秒总是返回 0

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/169428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 21:45:25  来源:igfitidea点击:

PHP DateTime microseconds always returns 0

phpdatetime

提问by eydelber

this code always returns 0 in PHP 5.2.5 for microseconds:

这段代码在 PHP 5.2.5 中总是返回 0 微秒:

<?php
$dt = new DateTime();
echo $dt->format("Y-m-d\TH:i:s.u") . "\n";
?>

Output:

输出:

[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

Any ideas?

有任何想法吗?

采纳答案by eydelber

This seems to work, although it seems illogical that http://us.php.net/datedocuments the microsecond specifier yet doesn't really support it:

这似乎有效,尽管http://us.php.net/date记录微秒说明符但并不真正支持它似乎不合逻辑:

function getTimestamp()
{
        return date("Y-m-d\TH:i:s") . substr((string)microtime(), 1, 8);
}

回答by tr0y

You can specify that your input contains microseconds when constructing a DateTimeobject, and use microtime(true)directly as the input.

您可以在构造DateTime对象时指定您的输入包含微秒,并microtime(true)直接用作输入。

Unfortunately, this will fail if you hit an exact second, because there will be no .in the microtime output; so use sprintfto force it to contain a .0in that case:

不幸的是,如果您精确到一秒,这将失败,因为微时间.输出中将没有;所以在这种情况下使用sprintf强制它包含 a .0

date_create_from_format(
    'U.u', sprintf('%.f', microtime(true))
)->format('Y-m-d\TH:i:s.uO');

Or equivalently (more OO-style)

或者等效地(更面向对象的风格)

DateTime::createFromFormat(
    'U.u', sprintf('%.f', microtime(true))
)->format('Y-m-d\TH:i:s.uO');

回答by jmccartie

This function pulled from http://us3.php.net/date

该函数从http://us3.php.net/date拉取

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

Very screwy you have to implement this function to get "u" to work... :\

非常棘手,你必须实现这个功能才能让“u”工作......:\

回答by dbwebtek

Try this and it shows micro seconds:

试试这个,它显示微秒:

$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");

回答by Ryan

\DateTime::createFromFormat('U.u', microtime(true));

Will give you (at least on most systems):

会给你(至少在大多数系统上):

object(DateTime)(
  'date' => '2015-03-09 17:27:39.456200',
  'timezone_type' => 3,
  'timezone' => 'Australia/Darwin'
)

But there is a loss of precision because of PHP float rounding. It's not truly microseconds.

但是由于 PHP 浮点舍入会导致精度损失。这不是真正的微秒。

Update

更新

This is probably the best compromise of the createFromFormat()options, and provides full precision.

这可能是createFromFormat()选项中最好的折衷方案,并提供了完全的精度。

\DateTime::createFromFormat('0.u00 U', microtime());

gettimeofday()

获取时间()

More explicit, and maybe more robust. Solves the bug found by Xavi.

更明确,也许更健壮。解决了哈维发现的bug。

$time = gettimeofday(); 
\DateTime::createFromFormat('U.u', sprintf('%d.%06d', $time['sec'], $time['usec']));

回答by hozza

Right, I'd like to clear this up once and for all.

是的,我想一劳永逸地解决这个问题。

An explanation of how to display the ISO 8601format date & time in PHP with milliseconds and microseconds...

解释如何在 PHP 中以毫秒微秒显示ISO 8601格式的日期和时间...

milliseconds or 'ms' have 4 digits after the decimal point e.g. 0.1234. microseconds or 'μs' have 7 digits after decimal. Seconds fractions/names explanation here

毫秒或“ms”在小数点后有 4 位数字,例如 0.1234。微秒或“μs”在小数点后有 7 位数字。秒分数/名称解释在这里

PHP's date()function does not behave entirely as expected with milliseconds or microseconds as it will only except an integer, as explained in the php date docsunder format character 'u'.

PHP 的date()函数在毫秒或微秒内的行为并不完全符合预期,因为它只会除整数外,如格式字符“u”下的php 日期文档中所述。

Based on Lucky's comment idea (here), but with corrected PHP syntax and properly handling seconds formatting (Lucky's code added an incorrect extra '0' after the seconds)

基于 Lucky 的评论想法(此处),但使用更正的 PHP 语法并正确处理秒格式(Lucky 的代码在秒后添加了一个不正确的额外“0”)

These also eliminate race conditions and correctly formats the seconds.

这些还消除了竞争条件并正确格式化秒。

PHP Date with milliseconds

毫秒为单位的PHP 日期

Working Equivalent of date('Y-m-d H:i:s').".$milliseconds";

工作当量 date('Y-m-d H:i:s').".$milliseconds";

list($sec, $usec) = explode('.', microtime(true));
echo date('Y-m-d H:i:s.', $sec) . $usec;

Output = 2016-07-12 16:27:08.5675

输出 = 2016-07-12 16:27:08.5675

PHP Date with microseconds

PHP日期与

Working Equivalent of date('Y-m-d H:i:s').".$microseconds";or date('Y-m-d H:i:s.u')if the date function behaved as expected with microseconds/microtime()/'u'

工作等价物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);

Output = 2016-07-12 16:27:08.56752900

输出 = 2016-07-12 16:27:08.56752900

回答by KyleFarris

This has worked for me and is a simple three-liner:

这对我有用,是一个简单的三行:

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));
}

This, by default (no params supplied) will return a string in this format for the current microsecond it was called:

这默认情况下(不提供参数)将返回一个这种格式的字符串,用于调用它的当前微秒:

YYYY-MM-DD HH:MM:SS.UUUUUUUU

YYYY-MM-DD HH:MM:SS.UUUUUUUU

An even simpler/faster one (albeit, with only half the precision) would be as follows:

一个更简单/更快的(尽管只有一半的精度)如下:

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;
}

This one would print out in the following format:

这将按以下格式打印出来:

YYYY-MM-DD HH:MM:SS.UUUU

YYYY-MM-DD HH:MM:SS.UUUU

回答by Nadeem

How about this?

这个怎么样?

$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>";

Sample Output

样本输出

2013-07-17 08:23:37:0.88862400

2013-07-17 08:23:37:0.88862400

回答by mgutt

This should be the most flexible and precise:

这应该是最灵活和精确的:

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
*/

回答by enobrev

Working from Lucky's commentand this feature request in the PHP bug database, I use something like this:

根据Lucky评论PHP 错误数据库中的功能请求,我使用了以下内容:

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');

Output:

输出:

2010-12-01 18:12:10.146625