在我的代码中,我使用DateTime
个对象来操作日期,然后将它们转换为时间戳,以便将它们保存在一些JSON文件中。
由于某些原因,我希望与DateTime(或接近的东西)具有相同的功能,但是具有微秒精度(在JSON文件中插入时我将转换为float)。
我的问题是: PHP对象是否像DateTime
一样,但也可以处理微秒?
目标是能够用物体操纵微量滴点。
在date()文档中,有一些东西表明可以用微秒创建DateTime,但我无法找到。
u Microseconds(在PHP 5.2.2中添加)。请注意,date()将始终 生成000000,因为它采用整数参数,而 如果创建了DateTime,DateTime :: format()确实支持微秒 用微秒。
我曾尝试使用浮动值(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'));
正如您在此处看到的那样.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)
编辑:我看到了这段代码,它允许向DateTime添加微秒,但我需要在创建DateTime之前对microtime应用大量修改。因为我会经常使用它,所以我想在获得" microtime对象之前尽可能少地修改微量片段。
$d = new DateTime("15-07-2014 18:30:00.111111");
答案 0 :(得分:18)
这是创建包含microtime的DateTime对象的一种非常简单的方法。
我没有深入研究这个问题所以,如果我错过了一些我道歉但希望你觉得这有用的话。
$date = DateTime::createFromFormat('U.u', microtime(TRUE));
var_dump($date->format('Y-m-d H:i:s.u'));
我测试了它并尝试了各种其他方法来使这项工作看似合乎逻辑,但这是唯一有效的方法。 然而,有一个问题,它返回正确的时间部分,但没有正确的一天部分(因为最有可能的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
<强>更新强>
正如评论中所指出的,从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代替microtime,因此会丢失所有的微量时间数据。
这是一个更新的沙箱,显示两者: http://sandbox.onlinephpfunctions.com/code/a88522835fdad4ae928d023a44b721e392a3295e
注意:在测试上面的沙箱时,我没有看到Planplan提到他经历过的微时间(TRUE)故障。然而,更新的方法似乎记录了KristopherWindsor建议的更高精度。
答案 1 :(得分:5)
Looking at a response on the PHP DateTime manual:
DateTime不支持分秒(微秒或毫秒等) 我不知道为什么没有记录。 类构造函数会毫无怨言地接受它们,但它们会被丢弃。 似乎没有办法像#34; 2012-07-08 11:14:15.638276&#34;并以完整的方式将其存储在客观的形式中。
所以你不能对两个字符串进行日期数学运算,例如:
<?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收到回复:
$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上dateTime()
的参考:http://php.net/manual/en/datetime.construct.php#
答案 2 :(得分:4)
/!\ EDIT /!\
我现在使用https://github.com/briannesbitt/Carbon,其余的答案仅仅是出于历史原因。
结束编辑
我决定使用你们给我的提示扩展课程DateTime
。
构造函数采用float(来自microtime
)或什么都没有(在这种情况下,它将使用当前&#34;微时间戳&#34;来初始化)。
我还覆盖了两个重要的功能:setTimestamp
和getTimestamp
。
不幸的是,我无法解决性能问题,虽然它并不像我想象的那么慢。
全班同学:
<?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;
}
}
答案 3 :(得分:2)
有多种选择。但正如Ben已经提供的那样,我会尝试给你另一个解决方案。
如果您提供了有关您希望进行何种计算的详细信息,则可以进一步更改。
$time =microtime(true);
$micro_time=sprintf("%06d",($time - floor($time)) * 1000000);
$date=new DateTime( date('Y-m-d H:i:s.'.$micro_time,$time) );
print "Date with microseconds :<br> ".$date->format("Y-m-d H:i:s.u");
或
$time =microtime(true);
var_dump($time);
$micro_time=sprintf("%06d",($time - floor($time)) * 1000000);
$date=new DateTime( date('Y-m-d H:i:s.'.$micro_time,$time) );
print "Date with microseconds :<br> ".$date->format("Y-m-d H:i:s.u");
或
list($ts,$ms) = explode(".",microtime(true));
$dt = new DateTime(date("Y-m-d H:i:s.",$ts).$ms);
echo $dt->format("Y-m-d H:i:s.u");
或
list($usec, $sec) = explode(' ', microtime());
print date('Y-m-d H:i:s', $sec) . $usec;
答案 4 :(得分:1)
/*
* More or less standard complete example. Tested.
*/
private static function utime($format, $utime = null, $timezone = null) {
if(!$utime) {
// microtime(true) had too fiew digits of microsecconds
$time_arr = explode( " ", microtime( false ) );
$utime = $time_arr[1] . substr( $time_arr[0], 1, 7 );
}
if(!$timezone) {
$timezone = date_default_timezone_get();
}
$date_time_zone = timezone_open( $timezone );
//date_create_from_format( "U.u", $utime ) - had a bug with 3-rd parameter
$date_time = date_create_from_format( "U.u", $utime );
date_timezone_set( $date_time, $date_time_zone );
$timestr = date_format( $date_time, $format );
return $timestr;
}
答案 5 :(得分:1)
这在PHP 7.2中对我有用:
$dateTime = \DateTime::createFromFormat('U.u', sprintf('%f', $aFloat), $optionalTimezone);
我开始考虑,由于格式代码'u'
在转换为字符串时仅输出日期的微秒部分,因此进行相反的操作是相同的。并且它还期望使用句点字符'.'
,因此,如果$aFloat
恰好是整数,则默认转换为字符串将保留小数点。最初,我认为需要'%.6f'
到字符串的浮点转换,但是'u'
期望得到一个左对齐的字符串。尾随零是不必要的。
答案 6 :(得分:0)
自从我解决了问题以来,我想与您分享。 Php71 +具有微秒级精度,如果要将其转换为纳米精度,只需将其乘以1000(10 ^ 3)。
$nsTimestamp = (int) (new \DateTime())->getTimestamp() * 1000
答案 7 :(得分:0)
$micro_seconds = microtime(false) * 1000000;
echo date('Y-m-d H:i:s.'. floor($micro_seconds));
有关日期的更多信息: https://www.php.net/manual/en/function.date.php
有关微时间的更多信息:https://www.php.net/manual/en/function.microtime.php
答案 8 :(得分:0)
我有点迟了,但是我不得不开发一种适用于PHP 5,PHP 7.0和PHP 7.1+的解决方案。
list($msec, $now) = explode(' ', microtime(false));
$z = gmdate('Y-m-d\TH:i:s' . substr($msec, 1) . '\Z', $now);
这将为您提供有效的UTC时间字符串(以微秒为单位)。如果仍然需要将其作为DateTime
对象,则可以直接传递以下字符串:
$dt = new DateTime($z);
如果您需要DateTime
,则从PHP 5.2开始有效,但是如果您只需要微秒的字符串,那么从PHP 4开始一直是很好的。
答案 9 :(得分:0)
美好的日期和时间,一步一步地
请注意,microtime()会告知时间 AND 微时间(句点后的数字)
echo microtime(true) ."<br>"; //1601674357.9448
sleep(0.99);
echo microtime(true) ."<br>"; //1601674357.9449
sleep(0.99);
echo microtime(true) ."<br>"; //1601674357.945
因此,让我们在句点之后加上数字:
echo substr(microtime(true), 11,4) . "<br>"; //945
但是,如果您在句点之后只有一两位数字吗?我们用零完成...
好,现在我们总是有4位数字,即微秒
echo str_pad(substr(microtime(true), 11,4), 4, '0', STR_PAD_RIGHT) . "<br>"; //9450
因此,让我们添加日期... 最终结果:
$date = gmdate('Y-m-d h:i:s.');
$time = str_pad(substr(microtime(true), 11,4), 4, '0', STR_PAD_RIGHT);
echo $date . $time; //2020-10-02 09:43:57.9450