DateTime以微秒为单位

Her*_*uin 28 php datetime

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

出于某些原因,我希望与DateTime(或接近的东西)具有相同的功能,但具有微秒精度(我在插入JSON文件时将转换为float).

我的问题是:是否有一个PHP对象就是喜欢DateTime,但能处理微秒吗?

目标是能够使用对象操纵microtimes.

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

u微秒(在PHP 5.2.2中添加).请注意,date()将始终生成000000,因为它采用整数参数,而DateTime :: format()确实支持微秒,如果使用微秒创建DateTime.

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

这是我试过的方式

$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'));
Run Code Online (Sandbox Code Playgroud)

这里.4没有考虑到这一点(即使我们可以使用u与微秒相对应的格式).

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)
Run Code Online (Sandbox Code Playgroud)

编辑:我看到这个代码,它允许在DateTime中添加微秒,但我需要在创建DateTime之前对microtime应用大量修改.由于我将使用它很多,我想在获得"microtime对象"之前尽可能少地修改microtime.

$d = new DateTime("15-07-2014 18:30:00.111111");
Run Code Online (Sandbox Code Playgroud)

MER*_*MER 28

这是一个创建包含microtime的DateTime对象的非常简单的方法.

我没有深入研究这个问题,所以如果我错过了一些我道歉但希望你觉得这很有帮助.

$date = DateTime::createFromFormat('U.u', microtime(TRUE));
var_dump($date->format('Y-m-d H:i:s.u')); 
Run Code Online (Sandbox Code Playgroud)

我测试了它并尝试了各种其他方法来使这项工作看似合乎逻辑,但这是唯一有效的方法.然而,有一个问题,它返回正确的时间部分,但没有正确的一天部分(因为最有可能的UTC时间)这是我做的(仍然看起来更简单恕我直言):

$dateObj = DateTime::createFromFormat('U.u', microtime(TRUE));
$dateObj->setTimeZone(new DateTimeZone('America/Denver'));
var_dump($dateObj->format('Y-m-d H:i:s:u'));
Run Code Online (Sandbox Code Playgroud)

这是一个有效的例子:http://sandbox.onlinephpfunctions.com/code/66f20107d4adf87c90b5c8c914393d4edef180a2

更新
正如评论中所指出的,从PHP 7.1开始,Planplan推荐的方法似乎优于上面显示的方法.

因此,对于PHP 7.1及更高版本,最好使用以下代码而不是上述代码:

$dateObj = DateTime::createFromFormat('0.u00 U', microtime());
$dateObj->setTimeZone(new DateTimeZone('America/Denver'));
var_dump($dateObj->format('Y-m-d H:i:s:u'));
Run Code Online (Sandbox Code Playgroud)

请注意,上述内容仅适用于PHP 7.1及更高版本.以前版本的PHP将返回0代替microtime,因此丢失所有microtime数据.

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

注意:在测试上面的沙箱时,我没有看到Planplan提到他经历过的微时间(TRUE)故障.然而,更新的方法似乎记录了KristopherWindsor建议的更高精度.

  • 在极少数情况下,microtime(true)可以返回仅包含整数部分的浮点数,从而使"Uu"格式失败.这有点难看,但这总是适用于DateTime :: createFromFormat('0.u00 U',microtime()); (4认同)

Ben*_*Ben 6

查看PHP DateTime手册的响应:

DateTime不支持分秒(微秒或毫秒等). 我不知道为什么没有记录.类构造函数会毫无怨言地接受它们,但它们会被丢弃.似乎没有办法像"2012-07-08 11:14:15.638276"那样使用字符串,并以完整的方式将其存储在客观形式中.

所以你不能对两个字符串进行日期数学运算,例如:

<?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
)

*/
?>
Run Code Online (Sandbox Code Playgroud)

当你真的想要获得0.251066秒时,你会回到0.


但是,从这里得到回应:

$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>";
Run Code Online (Sandbox Code Playgroud)

推荐和使用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 "u" is microseconds (1 seconds = 1000000 µs).
Run Code Online (Sandbox Code Playgroud)

dateTime()在php.net上的参考:http://php.net/manual/en/datetime.construct.php#


Her*_*uin 4

/!\ 编辑 /!\

我现在使用https://github.com/briannesbitt/Carbon,由于历史原因,这个答案的其余部分就在这里。

结束编辑

DateTime我决定利用你们给我的建议来扩展课程。

构造函数接受一个浮点数(来自microtime)或什么都不接受(在这种情况下它将使用当前的“微时间戳”进行初始化)。我还重写了两个重要的函数:setTimestampgetTimestamp

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

这是全班同学的情况:

<?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;
    }
}
Run Code Online (Sandbox Code Playgroud)