首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >微秒级的DateTime

微秒级的DateTime
EN

Stack Overflow用户
提问于 2015-11-13 19:12:08
回答 9查看 50.5K关注 0票数 36

在我的代码中,我使用DateTime对象来操作日期,然后将它们转换为时间戳,以便将它们保存在一些JSON文件中。

出于某些原因,我希望拥有与DateTime相同的东西(或接近的东西),但要有微秒级的精度(当我在JSON文件中插入时,我会将其转换为float )。

我的问题是:有没有像DateTime一样的PHP对象,但也可以处理微秒级的

我们的目标是能够对对象进行微时间操作。

date()文档中,有一些东西表明DateTime可以在微秒内创建,但我无法找到如何创建。

u微秒(在PHP5.2.2中添加)。请注意,date()将始终生成000000,因为它接受一个整数参数,而如果DateTime是用微秒创建的,则DateTime::format()不支持微秒。

我曾尝试使用浮点值(microtime(true))设置DateTime对象的时间戳,但不起作用(我认为它会将时间戳转换为整数,从而导致丢失微秒)。

以下是我尝试的方法

代码语言:javascript
复制
$dt = new DateTime();
$dt->setTimestamp(3.4); // I replaced 3.4 by microtime(true), this is just to give an example
var_dump($dt);
var_dump($dt->format('u'));

正如您在这里看到的那样,.4没有被考虑在内(即使我们可以使用u格式,它对应于微秒)。

代码语言:javascript
复制
object(DateTime)[1]
  public 'date' => string '1970-01-01 01:00:03' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/Berlin' (length=13)

string '000000' (length=6)

编辑:我看到了这段代码,它允许将微秒添加到DateTime中,但在创建DateTime之前,我需要对microtime进行大量修改。由于我会经常使用它,所以在获得"microtime对象“之前,我想对microtime做尽可能少的修改。

代码语言:javascript
复制
$d = new DateTime("15-07-2014 18:30:00.111111");
EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2015-11-25 22:44:02

/!\编辑/!\

我现在使用的是https://github.com/briannesbitt/Carbon,出于历史原因,下面的答案就在这里了。

结束编辑

我决定使用你们给我的提示来扩展DateTime类。

构造函数接受一个浮点型(来自microtime)或空(在本例中,它将使用当前的“微时间戳”进行初始化)。我还覆盖了两个重要的函数:setTimestampgetTimestamp

不幸的是,我不能解决性能问题,尽管它并不像我想象的那样慢。

下面是整个类:

代码语言:javascript
复制
<?php
class MicroDateTime extends DateTime
{
    public $microseconds = 0;

    public function __construct($time = 'now')
    {
        if ($time == 'now')
            $time = microtime(true);

        if (is_float($time + 0)) // "+ 0" implicitly converts $time to a numeric value
        {
            list($ts, $ms) = explode('.', $time);
            parent::__construct(date('Y-m-d H:i:s.', $ts).$ms);
            $this->microseconds = $time - (int)$time;
        }
        else
            throw new Exception('Incorrect value for time "'.print_r($time, true).'"');
    }

    public function setTimestamp($timestamp)
    {
        parent::setTimestamp($timestamp);
        $this->microseconds = $timestamp - (int)$timestamp;
    }

    public function getTimestamp()
    {
        return parent::getTimestamp() + $this->microseconds;
    }
}
票数 4
EN

Stack Overflow用户

发布于 2016-05-20 08:42:13

下面是创建包含microtime的DateTime对象的一个非常简单的方法。

我没有深入研究这个问题,所以如果我遗漏了什么,我道歉,但希望这对你有帮助。

代码语言:javascript
复制
$date = DateTime::createFromFormat('U.u', microtime(TRUE));
var_dump($date->format('Y-m-d H:i:s.u')); 

我对它进行了测试,并尝试了其他各种方法,以使这项工作看起来合乎逻辑,但这是在7.1之前的PHP版本中唯一有效的方法。

但是有一个问题,它返回了正确的时间部分,而不是正确的日期部分(因为很可能是UTC时间)下面是我所做的(仍然看起来更简单,IMHO):

代码语言:javascript
复制
$dateObj = DateTime::createFromFormat('U.u', microtime(TRUE));
$dateObj->setTimeZone(new DateTimeZone('America/Denver'));
var_dump($dateObj->format('Y-m-d H:i:s:u'));

下面是一个有效的示例:http://sandbox.onlinephpfunctions.com/code/66f20107d4adf87c90b5c8c914393d4edef180a2

更新

正如评论中指出的,在PHP 7.1中,Planplan推荐的方法似乎优于上面显示的方法。

因此,对于PHP 7.1和更高版本,使用下面的代码可能比使用上面的代码更好:

代码语言:javascript
复制
$dateObj = DateTime::createFromFormat('0.u00 U', microtime());
$dateObj->setTimeZone(new DateTimeZone('America/Denver'));
var_dump($dateObj->format('Y-m-d H:i:s:u'));

请注意,以上功能仅适用于PHP 7.1及以上版本。PHP以前的版本将返回0而不是microtime,因此会丢失所有microtime数据。

这是一个更新的沙箱,显示了这两种情况:http://sandbox.onlinephpfunctions.com/code/a88522835fdad4ae928d023a44b721e392a3295e

注意:在测试上面的沙箱时,我从来没有看到过Planplan提到的微时间(真的)失败。然而,根据KristopherWindsor的建议,更新后的方法似乎记录了更高的精度水平。

NOTE2:请注意,在极少数情况下,任何一种方法都会因为在PHP DateTime代码中处理微秒的基本决策而失败。以下任一项:

  • 避免将其用于科学目的或任何需要非常高精度的地方。
  • 或者准备好在精确的第二个标记上没有微秒数据返回...(其中一微秒...这是百万分之一秒,将没有数据返回,因为它是完全零…据我所知,这并不清楚返回了什么,可以用更好的方式完成,但值得创建代码来处理……同样,对于高精度使用)

谢谢你的建议。(请参阅注释)。

票数 31
EN

Stack Overflow用户

发布于 2015-11-13 19:17:21

Looking at a response on the PHP DateTime manual

DateTime不支持分秒(微秒或毫秒等)我不知道为什么没有文档说明。类构造函数会毫无抱怨地接受它们,但它们会被丢弃。似乎没有一种方法可以将"2012-07-08 11:14:15.638276“这样的字符串完整地以客观形式存储。

因此,您不能对以下两个字符串执行日期数学运算:

代码语言:javascript
复制
<?php
$d1=new DateTime("2012-07-08 11:14:15.638276");
$d2=new DateTime("2012-07-08 11:14:15.889342");
$diff=$d2->diff($d1);
print_r( $diff ) ;

/* returns:

DateInterval Object
(
    [y] => 0
    [m] => 0
    [d] => 0
    [h] => 0
    [i] => 0
    [s] => 0
    [invert] => 0
    [days] => 0
)

*/
?>

当你想要得到0.251066秒的时候,你会得到0。,

但是,从here获取响应

代码语言:javascript
复制
$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()类:

代码语言:javascript
复制
$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 "u" is microseconds (1 seconds = 1000000 µs).

Php.net上的dateTime()引用:http://php.net/manual/en/datetime.construct.php#

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33691428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档