I'm iterating through an array of objects and each object has a time attribution. As I iterate through the array I want to calculate the total time. Not sure how to add minutes in the time. Please refer to this screenshot Only hours are getting added. Code to add the time is written below
$total_human_readable_time += humanReadableTime($total_workhours);
Function humanReadableTime is defined below
function humanReadableTime($time) {
$time = abs($time);
$hours = floor($time);
$minutes = ceil(($time - floor($time)) * 60);
if ($minutes < 10) {
$minutes = "0$minutes";
}
return $hours . ":" . $minutes;
}
If your humanReadableTime function is already doing what you want it to, it looks like all you should have to do is not call it as you iterate, but instead just add up the unformatted values and then call it once at the end.
foreach($objects as $object) {
// something that gives you $total_workhours
$total_time += $total_workhours;
}
$total_human_readable_time = humanReadableTime($total_time);
Related
For example, I have multiple times like:
$a = "9:00:00";
$b = "8:00:00";
$c = "9:00:00";
and so on...
It must return in 26:00:00 but how to subtract it from 45:00:00?
I have to find out total working hours and overtime for my attendance.
You can figure out the different using Carbon. Need some little trick to add these times. You can do it this way:
$a = '09:00:00';
$b = '08:00:00';
$c = '09:00:00';
//convert the $a in carbon instance.
//convert $b and $c in integer, you can add only integer with carbon.
$d = Carbon::createFromFormat('H:i:s',$a)->addHours(intval($b))->addHours((intval($c)));
//convert the time "45:00:00" to carbon
$e = Carbon::createFromFormat('H:i:s','45:00:00');
//return the difference
$e->diffInHours($d)
You can do the following:
$sumSeconds = 0;
foreach($times as $time) {
$explodedTime = explode(':', $time);
$seconds = $explodedTime[0]*3600+$explodedTime[1]*60+$explodedTime[2];
$sumSeconds += $explodedTime;
}
$hours = floor($sumSeconds/3600);
$minutes = floor(($sumSeconds % 3600)/60);
$seconds = (($sumSeconds%3600)%60);
$sumTime = $hours.':'.$minutes.':'.$seconds;
This is the code for suming the three times (supposed that they are in array) and the code for subtracting will be almost the same but for the subtraction you will subtract $sumSeconds of both times and then convert the result.
Carbon is what you need, it's integrate with laravel by default.
http://carbon.nesbot.com/docs/
using its addHours() and subHours() function to achieve your requirements.
$times = [
"9:00:00",
"8:00:00",
"9:00:00",
];
// Converting the time to seconds makes calculations
// more simple and easier to understand.
function timeToSeconds($time) {
list($hours, $minutes, $seconds) = explode(":", $time);
return ($hours * 60 * 60) + ($minutes * 60) + $seconds;
}
// Let's use this to convert say 300s into 00:05:00
function formatSecondsAsHMI($seconds) {
return sprintf(
'%02d:%02d:%02d',
floor($seconds / 3600),
floor($seconds / 60 % 60),
floor($seconds % 60)
);
}
// Add an array of times together and return the formatted string hh:mm:ss
function addTimes($times) {
$seconds = array_sum(array_map(function ($time) {
return timeToSeconds($time);
}, $times));
return formatSecondsAsHMI($seconds);
}
// Subtract an array of times. Order of array important.
// Subtracts 0 from 1 from 2 where 0,1,2 are array keys
// i.e. [03:00:00, 10:00:00] would subtract 3 from 10 = 07:00:00
function subtractTimes($times) {
$times = array_map(function($time) {
return timeToSeconds($time);
}, $times);
return array_reduce($times, function($carry, $item) {
return ($item - $carry);
});
}
// Now just add the times together and subtract the result from 45
echo subtractTimes([addTimes($times), '45:00:00']);
php sum variable in while loop
I have to "sum" variable's values in while, here us my example :
while($row = mysql_fetch_array($result)){
$working_hour= $row[working_hour];
}
The code above will output if I put echo $working_hour; for example:
01:00:03, 01:03:04, 01:10:15
I want something like : sum($working_hour) or array_sum($working_hour) to count all the results of while loop. So, that i want to count: 01:00:03, 01:03:04, 01:10:15= 03:13:22
I try this way :
$total_working_hour=’00:00:00’;
while($row = mysql_fetch_array($result)){
$working_hour= $row[working_hour];
$total_working_hour+= $working_hour;
}
Echo $total_working_hour;
The code above provide output as:
03
How can I do it with php?
Thanks
$hours=0;$min=0;$sec=0;
while($row = mysql_fetch_array($result)){
$working_hour= $row[working_hour];
$arr=explode(':',$working_hour);
$hours=$hours+$arr[0];
$min=$min+$arr[1];
if($min>60){$hours++;$min=$min-60;}
$sec=$sec+$arr[2];
if($sec>60){$min++;$sec=$sec-60;}
}
echo 'Total working hours='.$hours.':'.$min.':'.$sec;
I used the answer here (how to sum the array time) and created the following function:
function addTime($a, $b) {
$array = [$a, $b];
$totalTimeSecs = 0;
foreach ($array as $time) { // Loop outer array
list($hours,$mins,$secs) = explode(':',$time); // Split into H:m:s
$totalTimeSecs += (int) ltrim($secs,'0'); // Add seconds to total
$totalTimeSecs += ((int) ltrim($mins,'0')) * 60; // Add minutes to total
$totalTimeSecs += ((int) ltrim($hours,'0')) * 3600; // Add hours to total
}
$hours = str_pad(floor($totalTimeSecs / 3600),2,'0',STR_PAD_LEFT);
$mins = str_pad(floor(($totalTimeSecs % 3600) / 60),2,'0',STR_PAD_LEFT);
$secs = str_pad($totalTimeSecs % 60,2,'0',STR_PAD_LEFT);
return "$hours:$mins:$secs";
}
So you can use this and replace
$total_working_hour+= $working_hour;
with
$total_working_hour = addTime($total_working_hour, $working_hour);
The value of $row["working_hour"] is clearly a string. So saying something like "01:00:03" + "01:03:04" clearly makes no sense. PHP assumes that what you meant to do was cast the strings to integers first and then add them together. The result of that is not what you're actually after.
Instead, you want to convert a string like "01:00:03" to an normalized integer value, like number of seconds, that can be added together and then converted back to a string value.
So to get the normalized value of the string as an integer in seconds you need a function like this...
function convertStringToNumSeconds($string) {
list($hours, $minutes, $seconds) = explode(":", $string, 3);
$totalSeconds = 0;
$totalSeconds += $hours * 3600; // There are 3600 seconds in an hour
$totalSeconds += $minutes * 60; // There are 60 seconds in a minute
$totalSeconds += $seconds; // There is 1 second in a second
return $totalSeconds;
}
Then to convert the seconds back to a formatted string you can do the opposite...
function secondsToString($seconds) {
$hours = (int) floor($seconds / 3600);
$seconds -= $hours * 3600;
$minutes = (int) floor($seconds / 60);
$seconds -= $minutes * 60;
return sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds);
}
Now in your loop you can actually do something like this...
$totalWork = 0;
while($row = mysql_fetch_array($result)){
$totalWork += convertStringToNumSeconds($row["working_hour"]);
}
echo secondsToString($totalWork); // You should get your expected result
If the format in your example is fix, you can work with DateTime-Object and Date-Interval as well like this... (for further information to DateInterval, have a look at the PHP-Docu)
$dt = new \DateTime('00:00:00');
foreach ($dbRows as $row) {
$time = $row['working_hour'];
$timeSplit = explode(':', $time);
$interval = new \DateInterval(
'P0Y0DT'.$timeSplit[0].'H'.
$timeSplit[1].'M'.$timeSplit[2].'S'
);
$dt->add($interval);
}
echo $dt->format('H:i:s'); // Output: 03:13:22
I have this code that draws the data from the db, that when run displays the time totals for each record in a hh:mm format, eg 00:35 for 35 minutes.
$query="SELECT * FROM data1 ORDER BY id DESC";
$result=mysql_query ($query);
$num=mysql_num_rows ($result);
mysql_close();
$i=0;
while ($i < $num) {
$time_ttl=mysql_result($result,$i,"time_ttl");
echo $time_ttl . "<br>";
++$i;
}
The result from the query looks like this:
00:35
00:25
00:10
Total time: 01:10 (1 hour 10 minutes)
Depending on the query, the number of totals will vary, and I want to calculate a grand total depending on the query.
I tried using this code to calculate the time, which works, but I am not sure how to connect the incoming data inside the 'while { }' part:
$times = array();
$times[] = "00:35";
$times[] = "00:25";
$times[] = "00:10";
function ttl_time($times) {
foreach ($times as $time) {
list($hour, $minute) = explode(':', $time);
$minutes += $hour * 60;
$minutes += $minute;
}
$hours = floor($minutes / 60);
$minutes -= $hours * 60;
$ttl_time = sprintf('%02d:%02d', $hours, $minutes);
}
The code calculates the total time correctly, but I am looking for guidance how to build an array based on the query to feed into the ttl_time function so I can connect the incoming query data to the function.
I did try this:
$result2 = mysql_query("SELECT sum(time_ttl) FROM data1");
while ($rows = mysql_fetch_array($result2)) {
echo $rows['sum(time_ttl)'];
}
But it returns the wrong result
If I understand your question correctly...
$i=0; $result_times = array();
while ($i < $num) {
$result_times[] = mysql_result($result,$i,"time_ttl");
++$i;
}
Then you can pass $result_times to your ttl_time function.
As for your other attempted solution (using sum) it depends on the data type. This may be helpful: calculate a sum of type time using sql
I have an array variable, I store all the time in this array.
I want to total all the stored value in my array.
I tried using a for loop but it can't read the time format.
I'm using CakePHP
In my usercontroller:
$this->set('project_time',$sele_lang['time']);
I used that code to get the estimated time for each project.
i don't have any problem with this.
then in my php to get set time
i created a variable and array to stor the time.
$target_time and $stored_time=array()
if(i have two projects) //i assume that i have two project
for($i = 0; $i < count($lang_val); $i++)
{
$target_time = $project_time; // this will get the estimated time
$stored_time[] = $target_time; //this will store the time in array.
$tempo = date("H:i:s", strtotime($stored_time[$i])); //this will get the first array value.
}
I'm stacked here.
I don't know if there's something a function that can sum all the time stored in my array.
or
I'm thinking that if i stored the first value to a temp file then add the temp value to a the second value of the array that would give me the result i want but it a time based i only tried that to a integer.
thanks for advance. sorry for the lack of information in my first post.
Something like this? Your code doesn't make sense, this is my best interpretation. (And it's a bad way of doing it. We can merge the second loop in the first one.
for($i=0;$i<count($lang_val);$i++){
$target_time = $project_time;
$stored_time[] = $target_time; //Assuming this is a timestamp
}
$intTotalTime = 0;
foreach($stored_time as $intTimeStamp) {
$intTotalTime += $intTimeStamp;
}
echo "Total Time: ". date("H:i:s", strtotime($intTotalTime));
Why would you like to get the sum of timestamps? The result would be a very odd number.
I assume the $lang_val is an array with timestamps.
$new = array();
foreach( $lang_val as $entry ) {
$new[] = strtotime( $entry );
}
// Debugging
var_dump( $new );
// Actual value
var_dump( array_sum($new) );
Or
$total = 0;
foreach( $lang_val as $entry ) {
$total += strtotime( $entry );
}
After your comment:
$data = array(
'00:15:00',
'01:05:05',
'10:00:15'
);
$total = 0;
foreach( $data as $timestamp ) {
// Get values or set default if not present.
list( $hours, $minutes, $seconds ) = explode( ':', $data ) + array(
0 => 0,
1 => 0,
2 => 0
);
// Convert to seconds
$hours = $hours * 3600;
$minutes = $minutes * 60;
$total += $hours + $minutes + $seconds;
}
var_dump( $total );
You can use array_reduce and strtotime:
<?php
$array = array('00:10:15', '02:00:00', '05:30:00');
// Get total amount of seconds
$seconds = array_reduce($array, function($carry, $timestamp) {
return $carry + strtotime('1970-01-01 ' . $timestamp);
}, 0);
// Get hours
$hours = floor($seconds/ 3600);
$seconds -= $hours * 3600;
// Get minutes
$minutes = floor($seconds/ 60);
$seconds -= $minutes * 60;
// Convert to timestamp
$timestamp = sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
var_dump($timestamp); //string(8) "07:40:15"
DEMO
I have an array of DateTime() objects in which I store some time duration (like "H:i")
How can I sum all elements in this array to get total time duration?
And it's also should be taken into account, that if total time duration is grater that 23:59, I have to be able to get nubmer of days.
is this possible?
I was trying to do like this:
$duration = new DateTime('00:00');
foreach($routes as $route) {
$arrival_time = new DateTime();
$arrival_time->setTimestamp($route->arrival_time);
$departure_time = new DateTime();
$departure_time->setTimestamp($route->departure_time);
$leg_duration = $arrival_time->diff($departure_time);
$duration->add($leg_duration);
}
but in $duration I got wrong time.
P.S.
Using $duration->add($leg_duration); I got subtracted from "24:00" time, why?
For example if $leg_duration = new DateTime('02:10'); the result will be "21:50".
$duration->sub($leg_duration); add time to "24:00"
Is this right?
Concerning part of the question: you're using the diff() method in the inverted way, the code should actually be:
$leg_duration = $departure_time->diff($arrival_time);
Because in your code you are calculating $departure_time - $arrival_time (which is negative, thus giving you this "inverted" result).
Concerning the addition of time intervals, as a DateTime object contains a date too, you might have to do something like this to get a meaningful result:
$start = new DateTime('00:00');
$duration = $start;
// ... your loop ...
$total = $start->diff($duration);
$total will be a DateInterval object, whose fields should contain your total time difference (although I didn't test this).
echo sum_the_time('01:45:22', '17:27:03');
this will give you a result:
19:12:2
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;
// return "{$hours}:{$minutes}:{$seconds}";
return sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds); // Thanks to Patrick
}
I found from here