73

此代码在 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

有任何想法吗?

4

18 回答 18

27

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

function getTimestamp()
{
        return date("Y-m-d\TH:i:s") . substr((string)microtime(), 1, 8);
}
于 2008-10-04T00:57:22.487 回答
19

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

不幸的是,如果您精确到一秒,这将失败,因为.微时间输出中将没有;所以在这种情况下使用sprintf强制它包含 a .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');
于 2011-07-07T01:19:09.703 回答
17

该函数取自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

非常麻烦,您必须实现此功能才能使“u”工作...:\

于 2008-10-04T01:31:09.000 回答
15

试试这个,它显示微秒:

$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");
于 2010-12-10T22:59:16.273 回答
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']));
于 2015-03-09T07:59:53.150 回答
5

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

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

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

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

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

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

PHP日期毫秒

工作当量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

带有微秒的 PHP日期

等效于date('Y-m-d H:i:s').".$microseconds";或如果日期函数在微秒//'u'date('Y-m-d H:i:s.u')中表现如预期microtime()

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

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

于 2016-07-12T16:19:13.567 回答
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

于 2013-06-04T16:22:05.757 回答
1

日期创建

time:strtotime() 接受的格式的字符串,默认为“now”。

时间

time:要解析的字符串,根据 GNU » Date Input Formats 语法。在 PHP 5.0.0 之前,微秒是不允许的,因为 PHP 5.0.0 允许但忽略它们。

于 2008-10-04T05:28:32.347 回答
1

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

输出:

2010-12-01 18:12:10.146625
于 2010-12-01T22:29:52.663 回答
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

于 2013-07-17T08:39:51.450 回答
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
*/
于 2015-02-14T13:12:55.040 回答
0

strtotime() 接受的格式的字符串它工作!

于 2008-12-14T20:34:06.483 回答
0

在我正在编写的应用程序内部,我需要在 DateTime 对象上设置/显示微时间。似乎让 DateTime 对象识别微秒的唯一方法是使用“YYYY-MM-DD HH:MM:SS.uuuuuu”格式的时间对其进行初始化。日期和时间部分之间的空格也可以是“T”,这在 ISO8601 格式中很常见。

以下函数返回一个初始化为本地时区的 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()));
}
于 2013-05-09T18:45:55.627 回答
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

于 2013-08-29T04:59:50.947 回答
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
于 2015-05-07T19:07:26.940 回答
0

一些答案使用了几个时间戳,这在概念上是错误的,并且可能会出现重叠问题:从给定中21:15:05.999组合的秒数到微秒。21:15:06.00021:15:05.000

显然最简单的是使用DateTime::createFromFormat()with U.u,但正如评论中所述,如果没有微秒,它会失败。

所以,我建议这段代码:

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);
}
于 2015-09-13T18:20:08.417 回答
-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

更新:不推荐(见评论)

于 2012-06-04T11:39:35.493 回答
-2

date('u') 仅从 PHP 5.2 开始受支持。您的 PHP 可能较旧!

于 2010-11-17T09:29:43.117 回答