How to subtract microtime and display date with milliseconds in php? - php

How to subtract microtime and display date with milliseconds in php ?
For example: I have set end date and time
$endtime = 2012-02-21 10:29:59;
then I have current date or start date with converted from microtime
$starttime = 2012-02-21 10:27:59.452;
function getTimestamp()
{
$microtime = floatval(substr((string)microtime(), 1, 8));
$rounded = round($microtime, 3);
return date("Y-m-d H:i:s") . substr((string)$rounded, 1, strlen($rounded));
}
echo getTimestamp(); //sample output 2012-02-21 10:27:59.452
Now I want to subtract:
$finaldate = $endtime - $starttime;
I want my output to be like this: 00:00:02.452

You need to use microtime for the start/end values, and only format it for display at the end.
// Get the start time in microseconds, as a float value
$starttime = microtime(true);
/************/
/* Do stuff */
/************/
// Get the difference between start and end in microseconds, as a float value
$diff = microtime(true) - $starttime;
// Break the difference into seconds and microseconds
$sec = intval($diff);
$micro = $diff - $sec;
// Format the result as you want it
// $final will contain something like "00:00:02.452"
$final = strftime('%T', mktime(0, 0, $sec)) . str_replace('0.', '.', sprintf('%.3f', $micro));
Note: this is returning float values from microtime and using float arithmetic to simplify the math, so your numbers may be extremely slightly off due to the float rounding problem, but you are rounding the result to 3 digits in the end anyway, and minor fluctuations in processor timing are greater than floating point errors anyway, so this is not problem for you on multiple levels.

Well phpmyadmin uses this a code like this to calculate the time that a query took. It's similar to your requirements:
//time before
list($usec, $sec) = explode(' ',microtime($starttime));
$querytime_before = ((float)$usec + (float)$sec);
/* your code */
//time after
list($usec, $sec) = explode(' ',microtime($endtime));
$querytime_after = ((float)$usec + (float)$sec);
$querytime = $querytime_after - $querytime_before;
I think this should work for you. You just have to figure your output format

Related

PHP converting strtotime into a microtime

I'm trying to find a way to make an strtotime with a provided datetime match up somewhat with a time generated from microtime(true).
I can't quite figure it out, I've tried dividing my strtotime by 1000 but this doesn't quite give me the right result, how can I match them up to be identical.
$time = strtotime('2022-04-06 09:00:00') / 1000;
$micro = microtime(true);
echo "$time - $micro";
output
1649260.8 - 1649233311.5081
You can do this just by adding a dot and zeros to your string :
$time = strtotime('2022-04-06 09:00:00');
$micro = microtime(true);
echo $time.".0000 - ".$micro;
Otherwise you can use the number_format function :
$time = strtotime('2022-04-06 09:00:00');
$timemicro = number_format($time, 4, '.', '');
$micro = microtime(true);
echo $timemicro." - ".$micro;
These are the simplest solutions I have found :)

Difference with microseconds precision between two DateTime in PHP

I can get a datetime with microseconds in PHP with a workaround as:
list($usec, $sec) = explode(" ", microtime());
echo date("Y-m-d\TH:i:s", $sec) . "." . floatval($usec)*pow(10,6);
I need the difference with microseconds between two datetimes, can't get a workaround for:
$datetime1 = new DateTime('2013-08-14 18:49:58.606');
$datetime2 = new DateTime('2013-08-14 22:27:19.272');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%h hours %i minutes %s seconds %u microseconds');
DateInterval::format doesn't has the format character %u or equivalent for microseconds.
Anyone knows a workaround for this?
/**
* returns the difference in seconds.microseconds(6 digits) format between 2 DateTime objects
* #param DateTime $date1
* #param DateTime $date2
*/
function mdiff($date1, $date2){
return number_format(abs((float)$date1->format("U.u") - (float)$date2->format("U.u")), 6);
}
Manually creating a DateTime object with micro seconds:
$d = new DateTime("15-07-2014 18:30:00.111111");
Getting a DateTime object of the current time with microseconds:
$d = date_format(new DateTime(),'d-m-Y H:i:s').substr((string)microtime(), 1, 8);
Difference between two DateTime objects in microseconds (e.g. returns: 2.218939)
//Returns the difference, in seconds, between two datetime objects including
//the microseconds:
function mdiff($date1, $date2){
//Absolute val of Date 1 in seconds from (EPOCH Time) - Date 2 in seconds from (EPOCH Time)
$diff = abs(strtotime($date1->format('d-m-Y H:i:s.u'))-strtotime($date2->format('d-m-Y H:i:s.u')));
//Creates variables for the microseconds of date1 and date2
$micro1 = $date1->format("u");
$micro2 = $date2->format("u");
//Absolute difference between these micro seconds:
$micro = abs($micro1 - $micro2);
//Creates the variable that will hold the seconds (?):
$difference = $diff.".".$micro;
return $difference;
}
Essentially it finds the difference for the DateTime Objects using strtotime and then adding the extra microseconds on.
Since PHP 7.1 (2016-12-01) there is %f and %F for microseconds precision, but just from 7.2 (2017-11-30) it is safe to use due to the critical date bugs in 7.1 (Tested)
The working example:
<?php
$datetime1 = new DateTime('2013-08-14 18:49:58.800');
$datetime2 = new DateTime('2013-08-14 22:27:19.900');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%h hours %i minutes %s seconds %f microseconds');
PD: Answering my own question posted 4 years before the existence of %f
I had to replace this
$micro = abs($micro1 - $micro2);
with this
str_pad(abs($micro1 - $micro2), 6, '0', STR_PAD_LEFT);
to get the correct microtime for some reason.
function mdiff($date1, $date2){
//Absolute val of Date 1 in seconds from (EPOCH Time) - Date 2 in seconds from (EPOCH Time)
$diff = abs(strtotime($date1->format('d-m-Y H:i:s.u'))-strtotime($date2->format('d-m-Y H:i:s.u')));
//Creates variables for the microseconds of date1 and date2
$micro1 = $date1->format("u");
$micro2 = $date2->format("u");
//Difference between these micro seconds:
$diffmicro = $micro1 - $micro2;
list($sec,$micro) = explode('.',((($diff) * 1000000) + $diffmicro )/1000000);
//Creates the variable that will hold the seconds (?):
$difference = $sec . "." . str_pad($micro,6,'0');
return $difference;
}
This function returns the correct difference
Example:
Start:"2016-10-27 17:17:52.576801"
End:"2016-10-27 17:18:00.385801"
Difference:"7.809000"
Old Function:
Difference:"8.191000"
Shorter version with float returned
function diff(\DateTimeInterface $a, \DateTimeInterface $b): float
{
return ($a->getTimestamp() - $b->getTimestamp()) + ($a->format("u") - $b->format("u")) / 1000000;
}

How to convert microtime() to HH:MM:SS:UU

I was measuring some curl requests and I used microtime(true). The example output would be 3.1745569706
This is 3.1745569706 seconds. I want to convert that to a somewhat more readable format, let's say 00:00:03:17455 (HOURS:MINUTES:SECONDS:MILLISECONDS)
$maxWaitTime = '3.1745569706';
echo gmdate("H:i:s.u", $maxWaitTime);
// which returns
00:00:01.000000
echo date("H:i:s.u" , $maxWaitTime)
// which returns
18:00:01.000000
That looks wrong. I'm not quite sure what I'm missing here.
How do I convert microtime() to HH:MM:SS:UU ?
From the PHP.net article on date() which is similar to gmdate(), except that the time is returned in GMT:
Since this function only accepts integer timestamps the u format
character is only useful when using the date_format() function with
user based timestamps created with date_create().
Use something like this instead:
list($usec, $sec) = explode(' ', microtime()); //split the microtime on space
//with two tokens $usec and $sec
$usec = str_replace("0.", ".", $usec); //remove the leading '0.' from usec
print date('H:i:s', $sec) . $usec; //appends the decimal portion of seconds
Which prints: 00:00:03.1745569706
If you want you can use round() to round the $usec var even more.
If you use microtime(true) use this instead:
list($sec, $usec) = explode('.', microtime(true)); //split the microtime on .
<?php
function format_period($seconds_input)
{
$hours = (int)($minutes = (int)($seconds = (int)($milliseconds = (int)($seconds_input * 1000)) / 1000) / 60) / 60;
return $hours.':'.($minutes%60).':'.($seconds%60).(($milliseconds===0)?'':'.'.rtrim($milliseconds%1000, '0'));
}
echo format_period(3.1745569706);
OUTPUT
0:0:3.174
Assuming one really cares about microseconds, which is admittedly rare, then one should not use any representation that involves floats.
Instead use gettimeofday() which will return an associative array that contains the seconds and microseconds as integers.
$g1 = gettimeofday();
# execute your process here
$g2 = gettimeofday();
$borrow = $g2['usec'] < $g1['usec'] ;
$seconds = $g2['sec'] - $g1['sec'] - $borrow ;
$micros = $borrow*1000000 + $g2['usec'] - $g1['usec'] ;
$delta = gmdate( 'H:i:s.', $seconds ).sprintf( '%06d', $micros );

Calculate elapsed time in php

Hi All I'm trying to calculate elapsed time in php. The problem is not in php, it's with my mathematical skills. For instance:
Time In: 11:35:20 (hh:mm:ss), now say the current time is: 12:00:45 (hh:mm:ss) then the time difference in my formula gives the output: 1:-34:25. It should actually be: 25:25
$d1=getdate();
$hournew=$d1['hours'];
$minnew=$d1['minutes'];
$secnew=$d1['seconds'];
$hourin = $_SESSION['h'];
$secin = $_SESSION['s'];
$minin = $_SESSION['m'];
$h1=$hournew-$hourin;
$s1=$secnew-$secin;
$m1=$minnew-$minin;
if($s1<0) {
$s1+=60; }
if($s1>=(60-$secin)) {
$m1--; }
if($m1<0) {
$m1++; }
echo $h1 . ":" . $m1 . ":" . $s1;
Any help please?
EDIT
Sorry I probably had to add that the page refreshes every second to display the new elapsed time so I have to use my method above. My apologies for not explaining correctly.
This will give you the number of seconds between start and end.
<?php
// microtime(true) returns the unix timestamp plus milliseconds as a float
$starttime = microtime(true);
/* do stuff here */
$endtime = microtime(true);
$timediff = $endtime - $starttime;
?>
To display it clock-style afterwards, you'd do something like this:
<?php
// pass in the number of seconds elapsed to get hours:minutes:seconds returned
function secondsToTime($s)
{
$h = floor($s / 3600);
$s -= $h * 3600;
$m = floor($s / 60);
$s -= $m * 60;
return $h.':'.sprintf('%02d', $m).':'.sprintf('%02d', $s);
}
?>
If you don't want to display the numbers after the decimal, just add round($s); to the beginning of the secondsToTime() function.
Using PHP >= 5.3 you could use DateTime and its method DateTime::diff(), which returns a DateInterval object:
$first = new DateTime( '11:35:20' );
$second = new DateTime( '12:00:45' );
$diff = $first->diff( $second );
echo $diff->format( '%H:%I:%S' ); // -> 00:25:25
Keep track of your time using the 'time()' function.
You can later convert 'time()' to other formats.
$_SESSION['start_time'] = time();
$end_time = time();
$end_time - $_SESSION['start_time'] = 65 seconds (divide by 60 to get minutes)
And then you can compare that to another value later on.
Use microtime if you need millisecond detail.
You can implement the solutions shown, but I'm fond of using the phptimer class (or others, this wheel has been invented a few times). The advantage is that you can usually define the timer to be active or not, thereby permitting you to leave the timer calls in your code for later reference without re-keying all the time points.
For high resolution time, try using monotonic clock: hrtime
<?php
$time = -hrtime(true);
sleep(5);
$end = sprintf('%f', $time += hrtime(true));
?>
Difference between CLOCK_REALTIME and CLOCK_MONOTONIC?

16-digit timestamp with PHPs date() function

How can I use the following 16-digit timestamp (from an XML file) with PHP's date() function?
1295076698126000 // 15-01-2011 08:31:38.126
1286697695521000 // 10-10-2010 10:01:35.521
Those timestamps are in microseconds. However, since PHP uses integers for timestamps in seconds with date(), you won't be able to obtain the microsecond value. You're still able to print the rest of the date by dividing the timestamp by a million (1 million microseconds = 1 second), and passing the quotient to date():
// "u" will always be printed as 000000 regardless of actual microseconds
echo date('d-m-Y H:i:s.u', 1295076698126000 / 1000000);
EDIT: Hacky, but you can perform manual arithmetic to get the milliseconds and output it separately as a workaround, like this:
$xml_timestamp = 1295076698126000;
$seconds = $xml_timestamp / 1000000;
$microseconds = $seconds - floor($seconds);
$seconds = floor($seconds);
// 1 millisecond = 1000 microseconds
// Milliseconds, because your desired output is 3 decimal places long, not 6
$milliseconds = round($microseconds * 1000);
$format = 'd-m-Y H:i:s.' . sprintf('%03d', $milliseconds);
echo date($format, $seconds);
For reusability the DateTime class is a good option. Or, a custom function:
function date_milliseconds($format, $timestamp = NULL) {
$seconds = ($timestamp === NULL) ? microtime(true) : $timestamp / 1000000;
$microseconds = $seconds - floor($seconds);
$seconds = floor($seconds);
$milliseconds = round($microseconds * 1000);
$format = preg_replace('/(?<!\\\\)u/', sprintf('%03d', $milliseconds), $format);
return date($format, $seconds);
}
echo date_milliseconds('d-m-T H:i:s.u', floatval($xml_timestamp));

Categories