I try calculate time of an act in second with 2 decimals.
protected function microtimeFormat($data)
{
$duration = microtime(true) - $data;
$hours = (int)($duration/60/60);
$minutes = (int)($duration/60)-$hours*60;
return $seconds = $duration-$hours*60*60-$minutes*60;
}
this method get start time as $data...and get back it an int second
for example it return 2second.
I try get second with 2 decimals ...
protected function microtimeFormat($data,$format=null,$lng=null)
{
$duration = microtime(true) - $data;
$hours = (float)($duration/60/60);
$minutes = (float)($duration/60)-$hours*60;
$seconds = $duration-$hours*60*60-$minutes*60;
return number_format((float)$seconds, 2, '.', '');
}
but it return me 0.00 for short time
I think your issue comes from the (float) conversion to $hours and $minutes. When you do so you don't save the decimal part of each so your calculation of $seconds always give 0. Convert to int so you actually save in $hours and $minutes the actual number of seconds they each represent. And the remainder goes to $seconds.
protected function microtimeFormat($data,$format=null,$lng=null)
{
$duration = microtime(true) - $data;
$hours = (int)($duration/60/60);
$minutes = (int)($duration/60)-$hours*60;
$seconds = $duration-$hours*60*60-$minutes*60;
return number_format((float)$seconds, 2, '.', '');
}
$start = microtime(TRUE);
sleep(1);
$delay = $this->microtimeFormat($start);
var_dump($delay);
This gives me:
string(4) "1.01"
I use this form to generate a time in seconds, eg 1.20
$start = microtime(true);
for ($i=0; $i < 10000000; $i++) {
# code...
}
$end = microtime(true);
echo "<br>" . $time = number_format(($end - $start), 2);
// We get this: 1.20
An example comparing the performance of 2 functions of PHP:
define( 'NUM_TESTS', 1000000);
$start = microtime(true);
for( $i = 0; $i < NUM_TESTS; $i++)
{
mt_rand();
}
$end = microtime(true) - $start;
echo 'mt_rand: ' . number_format(($end), 2) . "\n";
$start = microtime(true);
for( $i = 0; $i < NUM_TESTS; $i++)
{
uniqid();
}
$end = microtime(true) - $start;
echo 'uniqid: ' . number_format(($end), 2) . "\n";
// We get this: mt_rand: 0.12 uniqid: 2.06
Related
Still a beginner so bear with me...
So I found this function for system uptime and have been fooling around with it as I learn about php and web development in general.
My goal is to have the output look like days:hours:mins:secs but there was no $seconds variable so I have added that line based on what else I had.
Everything works great except the seconds just shows up as 0. I'm not quite sure what I am doing wrong or if this is even the best way to do this.
function Uptime() {
$uptime = #file_get_contents( "/proc/uptime");
$uptime = explode(" ",$uptime);
$uptime = $uptime[0];
$days = explode(".",(($uptime % 31556926) / 86400));
$hours = explode(".",((($uptime % 31556926) % 86400) / 3600));
$minutes = explode(".",(((($uptime % 31556926) % 86400) % 3600) / 60));
$seconds = explode(".",((((($uptime % 31556926) % 86400) % 3600) / 60) / 60));
$time = $days[0].":".$hours[0].":".$minutes[0].":".$seconds[0];
return $time;
}
EDIT: I was able to get it working in a different way new function is below .
I am also still curious if anyone can answer why the above method did not work as expected, and if the new method below is the best way to accomplish this.
function Uptime() {
$ut = strtok( exec( "cat /proc/uptime" ), "." );
$days = sprintf( "%2d", ($ut/(3600*24)) );
$hours = sprintf( "%2d", ( ($ut % (3600*24)) / 3600) );
$min = sprintf( "%2d", ($ut % (3600*24) % 3600)/60 );
$sec = sprintf( "%2d", ($ut % (3600*24) % 3600)%60 );
return array( $days, $hours, $min, $sec );
}
$ut = Uptime();
echo "Uptime: $ut[0]:$ut[1]:$ut[2]:$ut[3]";
EDIT 2: I believe this last method is the best based on the answer given by nwellnhof. I had to tweak a bit to get the output exactly as I wanted. Thanks guys.
function Uptime() {
$str = #file_get_contents('/proc/uptime');
$num = floatval($str);
$secs = $num % 60;
$num = (int)($num / 60);
$mins = $num % 60;
$num = (int)($num / 60);
$hours = $num % 24;
$num = (int)($num / 24);
$days = $num;
return array(
"days" => $days,
"hours" => $hours,
"mins" => $mins,
"secs" => $secs
);
}
Reading directly from /proc/uptime is the most efficient solution on Linux. There are multiple ways to convert the output to days/hours/minutes/seconds. Try something like:
$str = #file_get_contents('/proc/uptime');
$num = floatval($str);
$secs = fmod($num, 60); $num = (int)($num / 60);
$mins = $num % 60; $num = (int)($num / 60);
$hours = $num % 24; $num = (int)($num / 24);
$days = $num;
Or, with intdiv (PHP7):
$str = #file_get_contents('/proc/uptime');
$num = floatval($str);
$secs = fmod($num, 60); $num = intdiv($num, 60);
$mins = $num % 60; $num = intdiv($num, 60);
$hours = $num % 24; $num = intdiv($num, 24);
$days = $num;
uptime supports the -p command line option. You can use this simple piece of code:
echo shell_exec('uptime -p');
variation of your initial example as a class:
class Uptime {
private $uptime;
private $modVals = array(31556926, 86400, 3600, 60, 60);
public function __construct() {
$this->read_uptime();
}
/**
* actually trigger a read of the system clock and cache the value
* #return string
*/
private function read_uptime() {
$uptime_raw = #file_get_contents("/proc/uptime");
$this->uptime = floatval($uptime_raw);
return $this->uptime;
}
private function get_uptime_cached() {
if(is_null($this->uptime)) $this->read_uptime(); // only read if not yet stored or empty
return $this->uptime;
}
/**
* recursively run mods on time value up to given depth
* #param int $d
* #return int
**/
private function doModDep($d) {
$start = $this->get_uptime_cached();
for($i=0;$i<$d;$i++) {
$start = $start % $this->modVals[$i];
}
return intval($start / $this->modVals[$d]);
}
public function getDays()
{
return $this->doModDep(1);
}
public function getHours() {
return $this->doModDep(2);
}
public function getMinutes()
{
return $this->doModDep(3);
}
public function getSeconds()
{
return $this->doModDep(4);
}
public function getTime($cached=false) {
if($cached != false) $this->read_uptime(); // resample cached system clock value
return sprintf("%03d:%02d:%02d:%02d", $this->getDays(), $this->getHours(), $this->getMinutes(), $this->getSeconds());
}
}
If you just look at the pattern in your statements, you can see that the one for seconds is different. It has two divisions. Additionally, the numbers you are using represent the number of seconds per time unit. The number of seconds per second should be 1, not 60. In short:
$seconds = explode(".",((((($uptime % 31556926) % 86400) % 3600) / 60) / 60));
Should be:
$seconds = explode(".",((((($uptime % 31556926) % 86400) % 3600) % 60) / 1));
Now this whole way of doing things is a bit weird. For example, (x % (n*m)) % m is just x % m.
A nicer way would be to do:
$uptime = (int) $uptime;
$seconds = $uptime % 60;
$minutes = ($uptime / 60 ) % 60;
$hours = ($uptime / (60*60) ) % 24;
$days = $uptime / (60*60*24); # % 365, if you want
On Unix/BSD, using /proc is not reliable since it is not mounted by default, on some Linux distributions it can be unmounted also, so it's better to parse using either uptime or sysctl command, e.g.
sysctl
<?php
preg_match('/sec = (\d+)/', shell_exec('sysctl -n kern.boottime'), $secs)
echo $secs[1];
or:
$s = explode( " ", exec("/sbin/sysctl -n kern.boottime") );
$a = str_replace( ",", "", $s[3]);
$uptime = time() - $a;
or as per example taken from m0n0wall:
<?php
exec("/sbin/sysctl -n kern.boottime", $boottime);
preg_match("/sec = (\d+)/", $boottime[0], $matches);
$boottime = $matches[1];
$uptime = time() - $boottime;
if ($uptime > 60)
$uptime += 30;
$updays = (int)($uptime / 86400);
$uptime %= 86400;
$uphours = (int)($uptime / 3600);
$uptime %= 3600;
$upmins = (int)($uptime / 60);
$uptimestr = "";
if ($updays > 1)
$uptimestr .= "$updays days, ";
else if ($updays > 0)
$uptimestr .= "1 day, ";
$uptimestr .= sprintf("%02d:%02d", $uphours, $upmins);
echo htmlspecialchars($uptimestr);
uptime
Example taken from 4webhelp:
<?php
$data = shell_exec('uptime');
$uptime = explode(' up ', $data);
$uptime = explode(',', $uptime[1]);
$uptime = $uptime[0].', '.$uptime[1];
echo ('Current server uptime: '.$uptime.'
or (tested on FreeBSD):
$uptime = exec("uptime");
$uptime = split(" ",$uptime);
$days = $uptime[3]; # NetBSD: $days = $uptime[4];
$time = split(",",$uptime[5]); # NetBSD: $time = split(",",$uptime[7]);
if (sizeof($hourmin = split(":",$time[0])) < 2){ ;
$hours = "0";
$mins = $hourmin[0];
} else {
$hourmin=split(":",$time[0]);
$hours = $hourmin[0];
$mins = $hourmin[1];
}
$calcuptime = "Uptime: ".$days." days ".$hours." hours ".$mins." mins" ;
echo $calcuptime;
Here is version which works for Windows:
<?php
$uptime = `c:\windows\system32\uptime2.bat $server`;
$uptime = explode(": ", $uptime);
$uptime = explode(", ", $uptime[1]);
$uptime_days = preg_replace($pattern, '', $uptime[0]);
$uptime_hours = preg_replace($pattern, '', $uptime[1]);
$uptime_minutes = preg_replace($pattern, '', $uptime[2]);
$uptime_seconds = preg_replace($pattern, '', $uptime[3]);
echo '<b>Uptime:</b><br><br>';
echo 'Days: '.$uptime_days.'<br>';
echo 'Hours: '.$uptime_hours.'<br>';
echo 'Minutes: '.$uptime_minutes.'<br>';
echo 'Seconds: '.$uptime_seconds.'<br>';
I need to add multiple time values as in Hours:mins, so I use
strtotime($value1) + strtotime($value2)
to add all of them, how do I put them back as hours:mins ?
cant use
date("h:i")
it only works if hours < 24.
I appreciate your help. Thanks
Here is an function that will sum all your time values in format HH:MM:
function sum_time() {
$i = 0;
foreach (func_get_args() as $time) {
sscanf($time, '%d:%d', $hour, $min);
$i += $hour * 60 + $min;
}
if ($h = floor($i / 60)) {
$i %= 60;
}
return sprintf('%02d:%02d', $h, $i);
}
// use example
echo sum_time('01:05', '00:02', '05:59'); # 07:06
demo
Try this :
function time_convert($s) {
$m = 0; $hr = 0; $td = "now";
if ($s > 59) {
$m = (int)($s/60);
$s = $s-($m*60); // sec left over
$td = "$m min";
}
if ($m > 59) {
$hr = (int)($m / 60);
$m = $m - ($hr*60); // min left over
$td = "$hr hr";
if ($hr > 1) {
$td .= "s";
}
if ($m > 0) {
$td .= ", $m min";
}
}
return $td;
}
And use it:
$time = (int) strtotime($v1) + strtotime($v2);
echo time_convert($time);
May it helps
The function strtotime() returns the time in seconds since January 1 1970 00:00:00 UTC. So adding the return value of this function might not do what you would expect.
Instead of using the date functions we can manipulate the string and perform some basic arithmetic operations:
<?php
$value1 = "12:44";
$value2 = "13:47";
$arr1 = explode(':', $value1);
$arr2 = explode(':', $value2);
$totalMinutes = (int)$arr1[0] * 60 + (int)$arr1[1] + (int)$arr2[0] * 60 + (int)$arr2[1];
$hours = (int) ($totalMinutes / 60);
$minutes = $totalMinutes % 60; // Modulus: remainder when dividing with 60
echo $hours . ':' . $minutes;
?>
Another way with DateTime
$dt1 = new DateTime($value1);
$dt2 = new DateTime($value2);
$interval = $dt1->diff($dt2);
echo $interval->format('%a day(s) %h hour(s) %i minute(s)') . '<br />';
echo ($interval->format('%a') * 24 + $interval->format('%h')) . ' hour(s) ';
echo $interval->format('%i minute(s)');
I want a PHP for loop that goes to certain number say "23" and again starts from "0".
Actually I want for the listing of time in 24 hours format and suppose a case is: I have to show time from 9 AM to 2 AM (i.e 9,10,11,12,13,14,...........23,0,1,2)
$i= range(0,23);//it doest work as it creates an array containing a range of elements
$start_time = 9;
$end_time = 2;
for ($i = $start_time ; $i<= $end_time ; $i++)
{
echo $i;
}
Please suggest a way.
Since your use-case mentions time-sensitive information you might be best off learning to use the date and strtotime functions (or the DateTime classes):
$time = strtotime('2013-09-14 02:00');
$endTime = strtotime('2013-09-15 09:00');
while ($time <= $endTime) {
echo date('Y-m-d H:i:s', $time)."\n";
$time = strtotime('+1 hour', $time);
}
// 2013-09-14 02:00:00
// 2013-09-14 03:00:00
// 2013-09-14 04:00:00
// 2013-09-14 05:00:00
// etc.
$start_time = 9;
$end_time = 2;
$end_time += ($end_time < $start_time) ? 24 : 0;
for ($i = $start_time; $i<= $end_time; $i++) {
echo ($i % 24);
}
Reason, the line $end_time += ($end_time < $start_time) ? 24 : 0; checks to see if the end time is less than the start time (which we assume means the next day), and if it is, it adds 24 hours to it. The line $i %24 is the modulus operator which will divide the number and give the remainder, so if it's 25, it will give you 1 back. Note that all hours being worked with will need to be in 24 hour format to use this method.
You can use the modulo to deduct 24 from numbers when they're greater than 23.
$start_time = 9;
$end_time = 2;
for( $i = $start_time; $i % 24 != $end_time; $i++ )
{
echo $i % 24;
}
Note that you need to be careful with this; if $end_time is greater than 23 it will be stuck in an infinite loop.
Try this its working
<?php
$i= range(0,23);//it doest work as it creates an array containing a range of elements
$start_time = 9;
$end_time = 2;
$max_value=23;
if($start_time>=$end_time)
{
for ($i = $start_time ; $i<= $max_value; $i++)
{
echo $i;
}
for($i=0; $i<=$end_time; $i++)
{
echo $i;
}
}
else
{
for ($i = $start_time ; $i<= $max_value; $i++)
{
echo $i;
}
}
?>
Again late to Answer , Try this
<?php
$start_time = 20;
$end_time = 10;
$maxTime=23;
$minTime=0;
for ($i = $minTime ; $i<=$maxTime - abs($start_time-$end_time) ; $i++)
{
$validTime= $start_time + ($i % $maxTime);
$validTime= $validTime>$maxTime?$validTime-$maxTime:$validTime;
echo $validTime;
}
?>
Check this out. Hope this helps
$start_time = 9;
$end_time = 2;
$flag = 1;
while($flag) [
echo $start_time . "<br>";
$start_time++;
if ($start_time == 23) { $start_time = 0; }
if ($start_time == $end_time) {
$flag = 0;
}
}
Does it have to be a for loop?
You can try this
function hours($range, $recurse = true, $end = array())
{
foreach($range as $time)
{
echo $time . "\n";
}
if($recurse && sizeof($end) > 0)
{
$range = range($end['start'], $end['end']);
hours($range, false);
}
}
$range = range(9,23);
$end = array('start' => 0, 'end' => 2);
hours($range, true, $end);
Maybe better to use date:
$hours = 8;
for ($i=1; $i<=8; $i++){
echo 'TIME1 = '.date("Y-m-d H:i:s",mktime (20+$i,15,18,06,05,2013)).'<br>';
}
or better DateTime class:
$date = DateTime::createFromFormat('Y-m-d H:i:s', '2013-06-05 20:15:18');
$hours = 8;
for ($i=0; $i<8; $i++){
$date->add(new DateInterval('PT1H'));
echo 'TIME2 = '.$date->format('Y-m-d H:i:s').'<br>';
}
Thanks everybody for your help, using your ideas I got my work done.
Here is the code that actually worked.
$start_time = some_dynamic_value;
$end_time = some_dynamic_value;
$i= $start_time;
$flag = false;
if($start_time > $end_time)
$flag = true;
while ($i <= $end_time || $flag)
{
echo $i;
if($i == 24)
{
$i= 0;
$flag = false;
}
$i++;
}
How can I calculate the total travel time in PHP:
Per mile Duration: 00:11:40
Total miles: 177
Total duration: 34:25:00
I've tried different ways, but can not get it done.
$distance = "177";
$parsetime = strtotime("00:11:40");
$otfrom_string = time();
$needed = $parstime*$distance;
$otto_string = $otfrom_string+$needed;
echo date("H:i:s",$otfrom_string)."<br />";
echo date("H:i:s",$otto_string)."<br />";
$start = $otfrom_string;
$end = $otto_string;
$elapsed = $end - $start;
echo date("H:i:s", $elapsed);
$time = '00:11:40';
$distance = 177;
list($h,$m,$s) = explode(':',$time);
$nbSec = $h * 3600 + $m * 60 + $s;
$totalDuration = $nbSec * $distance;
echo nbSecToString($totalDuration);//print 34:00:25
function nbSecToString($nbSec) {
$tmp = $nbSec % 3600;
$h = ($nbSec - $tmp ) / 3600;
$s = $tmp % 60;
$m = ( $tmp - $s ) / 60;
$h = str_pad($h, 2, "0", STR_PAD_LEFT);
$m = str_pad($m, 2, "0", STR_PAD_LEFT);
$s = str_pad($s, 2, "0", STR_PAD_LEFT);
return "$h:$m:$s";
}
Demo
strtotime Returns a timestamp on success, false otherwise. i THINK you are multipling a timestamp for 177 which is not the way to calculate the duration.
I suggest you to convert your string in seconds, then multiply for 177 then ADD result of below code to the current time and you get the "arrival" time.
To convert your string to seconds use
$timestr = '00:30:00';
$parts = explode(':', $timestr);
$seconds = ($parts[0] * 60 * 60) + ($parts[1] * 60) + $parts[2];
I need to get an array of time slots in a day, i.e. 24 hours. Something like:
array (
00:00=>00:00,
00:05=>00:05,
00:10=>00:10,
.................
21:05=>21:05,
.....
23:55=>23:55,
24:00=>24:00
)
I want to get this as a function return value with 5 minute intervals. Sorry for my bad English.
No need for a date function:
$result = array();
for ($n = 0; $n < 24 * 60; $n+=5)
{
$date = sprintf('%02d:%02d', $n / 60, $n % 60);
$result[$date] = $date;
}
BTW: There's no such thing as 24:00 hours.
$result = array();
for ($i = 0; $i < 24; $i++) {
for ($j = 0; $j < 60; $j+=5) {
$time = sprintf('%02d', $i) . ':' . sprintf('%02d', $j);
$result[$time] = $time;
}
}