<?php
function convertToHoursMins($total, $format = '%02d:%02d') {
$hours = intval($total / 60);
$minutes = ($total % 60);
return sprintf($format, $hours, $minutes);
}
echo convertToHoursMins($total, $format = '%02d:%02d');
?>
This solution works perfect (like many other solutions) when $total is positive.
When $total on the other hand is negative both $hours and $minutes gets negative like -hours:-minutes.
Every solution I have tried echoes the same output, and I am getting frustrated.
I really wood appreciate some help!
One of solutions is to work with absolute value of $total and prepend - if required:
function convertToHoursMins($total, $format = '%02d:%02d')
{
$absTotal = abs($total);
$hours = intval($absTotal / 60);
$minutes = ($absTotal % 60);
return sprintf((0 <= $total ? '' : '-') . $format, $hours, $minutes);
}
function convertToHoursMins($total, $format = '%02d:%02d') {
$total = abs($total);
$hours = intval($total / 60);
$minutes = ($total % 60);
return sprintf($format, $hours, $minutes);
}
Related
Here is my code:
$time = "20:58:05";
$time2 = "10:40:00";
$secs = strtotime($time2)-strtotime("00:00:00");
$result = date("H:i:s",strtotime($time)+$secs);
echo $result;
The output of the above code is - 07:38:05
i want it to display like this - 31:38:05. How can i achieve this?
Convert both times to seconds, add them, and then calculate the hours, minutes, and seconds yourself.
$time = "20:58:05";
$time2 = "10:40:00";
$secs = strtotime($time)-strtotime("00:00:00");
$secs2 = strtotime($time2)-strtotime("00:00:00");
$total = $secs + $secs2;
$hours = floor($total/3600);
$mins = floor(($total % 3600) / 60);
$secs = $total % 60;
echo sprintf("%d:%02d:%02d", $hours, $mins, $secs);
The solution of Barmar works when adding hours that are below 24:00:00, but when you add 2 variable with each variable exceeds 24:00:00 it gives a wrong output. For example:
$time = "20:58:05";
$time2 = "30:40:00";
$secs = strtotime($time)-strtotime("00:00:00");
$secs2 = strtotime($time2)-strtotime("00:00:00");
$total = $secs + $secs2;
$hours = floor($total/3600);
$mins = floor(($total % 3600) / 60);
$secs = $total % 60;
echo sprintf("%d:%02d:%02d", $hours, $mins, $secs);
output of the above code: -431348:-2:-55
Here is a code that works even if the data of the variables exceeds 24:00:00:
function sum_the_time($time1, $time2) {
$times = array($time1, $time2);
$seconds = 0;
foreach ($times as $time)
{
list($hour,$minute,$second) = explode(':', $time);
$seconds += $hour*3600;
$seconds += $minute*60;
$seconds += $second;
}
$hours = floor($seconds/3600);
$seconds -= $hours*3600;
$minutes = floor($seconds/60);
$seconds -= $minutes*60;
if($seconds < 9)
{
$seconds = "0".$seconds;
}
if($minutes < 9)
{
$minutes = "0".$minutes;
}
if($hours < 9)
{
$hours = "0".$hours;
}
return "{$hours}:{$minutes}:{$seconds}";
}
i found this code here
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>';
Is there any way to sum two times with milliseconds like this:
00:01:02.73
00:03:03.01
to one?
the result should be like this:
00:04:05.74
format is simple "hours:minutes:seconds.milliseconds"
If yes, how?
well I wrote few functions which is helping me to do that
$time1 = "00:15:45.89";
$time2 = "00:18:30.22";
$milli1 = timeToMilliseconds($time1);
$milli2 = timeToMilliseconds($time2);
$new = $milli1 + $milli2;
$time = formatMilliseconds($new);
echo $time;
function timeToMilliseconds($time){
$time_start = substr($time, -11, -3);
$time_end = substr($time, -3);
$time_arr = explode(':', $time_start);
$seconds = 0;
foreach($time_arr as $key => $val){
if($key == 0){
$seconds += $val * 60 * 60;
}elseif($key == 1){
$seconds += $val * 60;
}elseif($key == 2){
$seconds += $val;
}
}
$seconds = $seconds.$time_end;
$milliseconds = $seconds * 1000;
return $milliseconds;
}
function formatMilliseconds($milliseconds) {
$seconds = floor($milliseconds / 1000);
$minutes = floor($seconds / 60);
$hours = floor($minutes / 60);
$milliseconds = $milliseconds % 1000;
$seconds = $seconds % 60;
$minutes = $minutes % 60;
$format = '%u:%02u:%02u.%03u';
$time = sprintf($format, $hours, $minutes, $seconds, $milliseconds);
return rtrim($time, '0');
}
Has a problem with your solution #Scorpioniz, when the time is "1:34:55.831" for example, the return from formatMilliseconds is "1582:10:31.704".
I made some changes in the timeToMilliseconds function and I think that is more consistent:
function timeToMilliseconds($time){
$dateTime = new DateTime($time);
$seconds = 0;
$seconds += $dateTime->format('H') * 3600;
$seconds += $dateTime->format('i') * 60;
$seconds += $dateTime->format('s');
$seconds = floatval($seconds . '.' . $dateTime->format('u'));
return $seconds * 1000;
}
Or if your version of PHP is minor than 5.2.2 then you can do:
function timeToMilliseconds($time){
sscanf($time, "%d:%d:%d.%d", $hours, $minutes, $seconds, $microseconds);
$seconds += $hours * 3600;
$seconds += $minutes * 60;
$seconds = floatval($seconds . '.' . $microseconds);
return $seconds * 1000;
}
I hope someone enjoy.
(Sorry for my English if I said something strange :P)
I've found this, it has less code than yours and it does the job. I've added function for milliseconds.
I'm wondering if php has something built-in for this.
/**
* #author Masino Sinaga, http://www.openscriptsolution.com
* #copyright October 13, 2009
*/
function sum_the_time($time1, $time2) {
$times = array($time1, $time2);
$seconds = 0;
$Imiliseconds = 0.0;
foreach ($times as $time){
list($rest, $miliseconds) = explode('.', $time);
$Imiliseconds += '0.'.$miliseconds;
list($hour, $minute, $second) = explode(':', $rest);
$seconds += $hour*3600;
$seconds += $minute*60;
$seconds += $second;
}
$seconds += floor($Imiliseconds);
$hours = floor($seconds/3600);
$seconds -= $hours*3600;
$minutes = floor($seconds/60);
$seconds -= $minutes*60;
$miliseconds = $Imiliseconds-floor($Imiliseconds);
// return "{$hours}:{$minutes}:{$seconds}:{$miliseconds}";
return sprintf('%02d:%02d:%02d:%02d', $hours, $minutes, $seconds, $miliseconds); // Thanks to Patrick
}
echo sum_the_time($time, $time2); // this will give you a result: 19:12:25
i have two time values as give below
$time = 06:58:00;
$time2 = 00:40:00;
I am doing this for calculating the appointments and available time for a particular user
so i tried in this way
$max_date=abs(strtotime($time) + strtotime($time2));
but it is returning $max_date =2673452280
any suggestions pls
this code sample would take hour in $time and add the hour in $time2 to it
for example: time=06:58:00, time2=00:40:00, result = 07:38:00
$time = "06:58:00";
$time2 = "00:40:00";
$secs = strtotime($time2)-strtotime("00:00:00");
$result = date("H:i:s",strtotime($time)+$secs);
Use this function...
function sum_the_time($time1, $time2) {
$times = array($time1, $time2);
$seconds = 0;
foreach ($times as $time)
{
list($hour,$minute,$second) = explode(':', $time);
$seconds += $hour*3600;
$seconds += $minute*60;
$seconds += $second;
}
$hours = floor($seconds/3600);
$seconds -= $hours*3600;
$minutes = floor($seconds/60);
$seconds -= $minutes*60;
if($seconds < 9)
{
$seconds = "0".$seconds;
}
if($minutes < 9)
{
$minutes = "0".$minutes;
}
if($hours < 9)
{
$hours = "0".$hours;
}
return "{$hours}:{$minutes}:{$seconds}";
}
strtotime function takes full-date as an argument and valid format are as following:
http://www.php.net/manual/en/datetime.formats.php
You can see that in online PHP manual for the function at http://php.net/manual/en/function.strtotime.php
If you're build those time strings from a database before, you'd probably want to rebuild them to something like this:
$time = "00:06:58";
$time2 = "40 minutes";
$timestamp = strtotime($time." +".$time2);
$endTime = date("d.m.Y H:i:s", $timestamp);
Easiest way to add two times using php is :
1) Convert time from H:i:s (e.g. 08:15:40) format to seconds.
2) do the same for second time value ref:step 1
3) add converted values and store it php variable
4) Now convert total (which is in seconds) to H:i:s
and it works for me.
PHP Script:
$str_time ="08:04:40";
$str_time = preg_replace("/^([\d]{1,2})\:([\d]{2})$/", "00:$1:$2", $str_time);
sscanf($str_time, "%d:%d:%d", $hours, $minutes, $seconds);
$hrs_old_seconds = $hours * 3600 + $minutes * 60 + $seconds;
$str_time ="02:10:22";
$str_time = preg_replace("/^([\d]{1,2})\:([\d]{2})$/", "00:$1:$2", $str_time);
sscanf($str_time, "%d:%d:%d", $hours, $minutes, $seconds);
$hrs_toadd_seconds = $hours * 3600 + $minutes * 60 + $seconds;
$hrs_old_int1 = $hrs_old_seconds + $hrs_toadd_seconds;
echo $Total=gmdate("H:i:s", $hrs_old_int1);
Result= :10:15:02
Anudeep's solution was great for my use case, but I needed to be able to add negative times as well. Here's a slightly edited version of his code to take and return negative time strings ("-01:01:01" for example):
public static function sum_the_times($time1, $time2)
{
$times = array($time1, $time2);
$seconds = 0;
$negative = false;
foreach ($times as $time) {
list($hour,$minute,$second) = explode(':', $time);
if(substr($hour,0,1) == '-'){
$seconds -= substr($hour,1)*3600;
$seconds -= $minute*60;
$seconds -= $second;
} else {
$seconds += $hour*3600;
$seconds += $minute*60;
$seconds += $second;
}
}
if (substr($seconds, 0, 1) == '-') {
$negative = true;
$seconds = ($seconds * -1);
}
$hours = floor($seconds/3600);
$seconds -= $hours*3600;
$minutes = floor($seconds/60);
$seconds -= $minutes*60;
if ($seconds < 9) {
$seconds = "0".$seconds;
}
if ($minutes < 9) {
$minutes = "0".$minutes;
}
if ($hours < 9) {
$hours = "0".$hours;
}
return ($negative ? "-" : "")."{$hours}:{$minutes}:{$seconds}";
}
You can try this
$time = "04:00:00";
$time2 = "03:30:00";
$result = date("H:i:s",strtotime($time)+strtotime($time2));
echo $result;
It gives output 07:30:00 but it does not work sometime in different version of operating system. If you want to get sum of time then you can use this code
<?php
function CalculateTime($time1, $time2) {
$time1 = date('H:i:s',strtotime($time1));
$time2 = date('H:i:s',strtotime($time2));
$times = array($time1, $time2);
$seconds = 0;
foreach ($times as $time)
{
list($hour,$minute,$second) = explode(':', $time);
$seconds += $hour*3600;
$seconds += $minute*60;
$seconds += $second;
}
$hours = floor($seconds/3600);
$seconds -= $hours*3600;
$minutes = floor($seconds/60);
$seconds -= $minutes*60;
if($seconds < 9)
{
$seconds = "0".$seconds;
}
if($minutes < 9)
{
$minutes = "0".$minutes;
}
if($hours < 9)
{
$hours = "0".$hours;
}
return "{$hours}:{$minutes}:{$seconds}";
}
$time1= '23:32:05';
$time2 = '01:29';
echo CalculateTime($time1,$time2);
?>
In the second code, you can send time in hour:minutes or hours:minutes:seconds. This code accept both format because it convert time automatically
Here's a version that will cater for over 24 hours and doesn't use strtotime:
$time0 = "24:01:02";
$time1 = "01:02:03";
$matches0 = explode(':',$time0); // split up the string
$matches1 = explode(':',$time1);
$sec0 = $matches0[0]*60*60+$matches0[1]*60+$matches0[2];
$sec1 = $sec0+ $matches1[0]*3600+$matches1[1]*60+$matches1[2]; // get total seconds
$h = intval(($sec1)/3600);
$m = intval(($sec1-$h*3600)/60);
$s = $sec1-$h*3600-$m*60;
echo $str = str_pad($h, 2, '0', STR_PAD_LEFT).':'.str_pad($m, 2, '0', STR_PAD_LEFT).':'.str_pad($s, 2, '0', STR_PAD_LEFT);
I've got a script that takes in a value in seconds (to 2 decimal points of fractional seconds):
$seconds_input = 23.75
I then convert it to milliseconds:
$milliseconds = $seconds_input * 1000; // --> 23750
And then I want to format it like so:
H:M:S.x // --> 0:0:23.75
Where 'x' is the fraction of the second (however many places after the decimal there are).
Any help? I can't seem to wrap my mind around this. I tried using gmdate() but it kept lopping off the fractional seconds.
Thanks.
Edit: Well, I was a bit hasty. Here's one way to do what you're asking:
function formatMilliseconds($milliseconds) {
$seconds = floor($milliseconds / 1000);
$minutes = floor($seconds / 60);
$hours = floor($minutes / 60);
$milliseconds = $milliseconds % 1000;
$seconds = $seconds % 60;
$minutes = $minutes % 60;
$format = '%u:%02u:%02u.%03u';
$time = sprintf($format, $hours, $minutes, $seconds, $milliseconds);
return rtrim($time, '0');
}
My take
function formatSeconds( $seconds )
{
$hours = 0;
$milliseconds = str_replace( "0.", '', $seconds - floor( $seconds ) );
if ( $seconds > 3600 )
{
$hours = floor( $seconds / 3600 );
}
$seconds = $seconds % 3600;
return str_pad( $hours, 2, '0', STR_PAD_LEFT )
. gmdate( ':i:s', $seconds )
. ($milliseconds ? ".$milliseconds" : '')
;
}
And then the test
$testData = array(
23, // Seconds, w/o millis
23.75, // Seconds, w/millis
23.75123456789, // Lots of millis
123456789.75 // Lots of seconds
);
foreach ( $testData as $seconds )
{
echo formatSeconds( $seconds ), PHP_EOL;
}
which yields
00:00:23
00:00:23.75
00:00:23.75123456789
34293:33:09.75
Mine is much less readable, so it must be better. :p
Basically the same idea as #ircmaxell's version. It does trim the trailing '0's and even will skip the last '.' separator if milliseconds are 0.
<?
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(23.75);
if you really want to do it using date function you are right, you have to deal with milliseconds externally, is only based on second-timestamps.
you could do something like this:
<?
$input = "23.75";
$seconds = floor($input);
$date = DateTime::createFromFormat('s', floor($seconds));
$ms = ($input-$seconds);
if($ms == 0) {
$ms = "";
} else {
$ms = ltrim($ms,"0,");
}
echo $date->format('H:i:s').$ms;
but be aware of the hour-overflow, if your hours exceed 24 you will probably end up discarding the days.
in your case i would say your approach with floor to get the seconds is correct, and then you should probably just use modulo arithmetics like this:
<?
$totalsecs = 86400*10;
$secs = $totalsecs%60;
echo "secs: $secs \n";
$minutes = ($totalsecs - $secs) % (60*60);
?>
and so on..