日期时间与微秒

2022-08-30 12:56:38

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

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

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

目标是能够用物体操纵微时间。

date()文档中,有一些东西表明DateTime可以用微秒为单位创建,但我无法找到方法。

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

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

这是我如何尝试的

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

正如您在此处看到的,没有考虑(即使我们可以使用对应于微秒的格式)。.4u

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之前,我需要对微时间应用很多修改。由于我将经常使用它,因此我想在获得“微时间对象”之前对微时间进行尽可能少的修改。

$d = new DateTime("15-07-2014 18:30:00.111111");

答案 1

下面是创建包含微时间的 DateTime 对象的非常简单的方法。

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

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

我测试了它,并尝试了各种其他方法来使这项工作看起来合乎逻辑,但这是适用于7.1之前的PHP版本的唯一方法。

但是有一个问题,它返回了正确的时间部分,但不是正确的日期部分(因为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'));

下面是一个工作示例:http://sandbox.onlinephpfunctions.com/code/66f20107d4adf87c90b5c8c914393d4edef180a2

UPDATE
正如注释中指出的那样,从 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'));

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

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

注意:在测试上面的沙箱时,我从未见过Planplan提到的他所经历的microtime(TRUE)故障。然而,更新后的方法似乎确实记录了KristopherWindsor所建议的更高水平的精度。

注意2:请注意,在极少数情况下,由于对 PHP DateTime 代码中微秒的处理做出了基础决策,因此任何一种方法都会失败。也:

  • 避免将其用于科学目的或任何需要非常高的准确性。
  • 或者准备好没有微秒数据在精确的第二个标记上返回...(其中一微秒...这是100万分之一秒,将没有数据返回,因为它是完全零...从我所读到的内容来看,从返回的内容中不清楚,可以以更好的方式完成,但值得创建代码来处理...再次,用于高精度用途)

感谢您的提醒Sz.(见评论)。


答案 2

查看 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
)

*/
?>

当你真正想要得到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>";

推荐并使用引用的类: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).

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


推荐