Build array from query for a total time calculation - php

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

Related

Calculate Total time from array in php if total time greater than 24 hours

I want to get the sum of the time in array. There are a lot of questions asked before related this question. Only problem this solution work the only sum is less than 24 hours. After 24 hours it will start at 00:00:00. How do I get more than 24 hours as total?
<?php
$total = [
'00:02:55',
'00:07:56',
'01:03:32',
'15:13:34',
'02:13:44',
'03:08:53',
'13:13:54'
];
$sum = strtotime('00:00:00');
$sum2=0;
foreach ($total as $v){
$sum1=strtotime($v)-$sum;
$sum2 = $sum2+$sum1;
}
$sum3=$sum+$sum2;
echo date("H:i:s",$sum3);
?>
RESULT
11:04:28
Expected result
35:04:28
DEMO LINK
Try the following code
<?php
function explode_time($time) { //explode time and convert into seconds
$time = explode(':', $time);
$time = $time[0] * 3600 + $time[1] * 60;
return $time;
}
function second_to_hhmm($time) { //convert seconds to hh:mm
$hour = floor($time / 3600);
$minute = strval(floor(($time % 3600) / 60));
if ($minute == 0) {
$minute = "00";
} else {
$minute = $minute;
}
$time = $hour . ":" . $minute;
return $time;
}
$time = 0;
$time_arr = [
'00:02:55',
'00:07:56',
'01:03:32',
'15:13:34',
'02:13:44',
'03:08:53',
'13:13:54'
];
foreach ($time_arr as $time_val) {
$time +=explode_time($time_val); // this fucntion will convert all hh:mm to seconds
}
echo second_to_hhmm($time);
?>
With the external DateTime Extension dt you can add all times to a date.
With DateTime::diff you get the result:
$dt = dt::create("2000-1-1"); //fix Date
$dtsum = clone $dt;
foreach($total as $time){
$dtsum->addTime($time);
}
$diff = $dt->diff($dtsum);
printf('%d:%02d:%02d',$diff->days * 24 + $diff->h,$diff->i,$diff->s);
Output:
35:04:28
Update
Without a DateTime-Extension:
$dt = date_create("2000-1-1"); //fix Date
$dtsum = clone $dt;
foreach($total as $time){
$timeArr = explode(":",$time);
$secondsAdd = $timeArr[0] * 3600 + $timeArr[1] * 60 +$timeArr[2];
$dtsum->modify($secondsAdd." Seconds");
}
$diff = $dt->diff($dtsum);
printf('%d:%02d:%02d',$diff->days * 24 + $diff->h,$diff->i,$diff->s);
Look at what you are doing: using time to make computations ignoring date part.
Maybe considering things in another way : 1 hour = 60 seconds * 60 minutes. So convert all you iterations as seconds, do the sum at the end and write time you need yourself.
Or, or you will use some greater things from php documentation
<?php
$january = new DateTime('2010-01-01');
$february = new DateTime('2010-02-01');
$interval = $february->diff($january);
// %a will output the total number of days.
echo $interval->format('%a total days')."\n";
// While %d will only output the number of days not already covered by the
// month.
echo $interval->format('%m month, %d days');
Adapt to your needs, and I am sure it will work well.
Personally I would completely avoid touching any date functions because you're not working with dates. You could do something like:
// Input data
$data = [
'00:02:55',
'00:07:56',
'01:03:32',
'15:13:34',
'02:13:44',
'03:08:53',
'13:13:54'
];
// Total to hold the amount of seconds
$total = 0;
// Loop the data items
foreach($data as $item):
$temp = explode(":", $item); // Explode by the seperator :
$total+= (int) $temp[0] * 3600; // Convert the hours to seconds and add to our total
$total+= (int) $temp[1] * 60; // Convert the minutes to seconds and add to our total
$total+= (int) $temp[2]; // Add the seconds to our total
endforeach;
// Format the seconds back into HH:MM:SS
$formatted = sprintf('%02d:%02d:%02d', ($total / 3600),($total / 60 % 60), $total % 60);
echo $formatted; // Outputs 35:04:28
So we loop the items in the input array and explode the string by the : to get an array containing hours, minutes and seconds in indexes 0, 1, and 2.
We then convert each of those values to seconds and add to our total. Once we're done, we format back into HH:MM:SS format

how to get sum of the total time in php

Currently i working with the attendance management system.i calculate how many hours work done in employees.i already calculate the how much hours working in day and it store in the mysql database.
$totaltime = (strtotime($time_out) - strtotime($time_in));
$hours = sprintf('%02d', intval($totaltime / 3600));
$seconds_remain = ($totaltime - ($hours * 3600));
$minutes = sprintf('%02d', intval($seconds_remain / 60));
$seconds = sprintf('%02d' ,($seconds_remain - ($minutes * 60)));
$final = '';
if ($time_in == '' || $time_out == '')
{
$final = '';
}
else
{
$final .= $hours.':'.$minutes.':'.$seconds;
}
for example
$time_in = 08:09:57
$time_out = 16:04:50
$final = 07:54:53 (total working hours)
now i want to get the current month total working time for each employee.how do get sum of the $final using php?
sample data of the month_data
Emp_no Date Time_in Time_out Total_hours TranID
23 2019-08-01 07:54:40 16:01:40 08:07:00 1
23 2019-08-02 07:42:35 16:02:53 08:20:18 2
i want get the sum of the Total_hours for related one employee
If you ask me this can be easily done using plain MySQL, no meed for PHP to calculate this.
You could take a look at a query somewhat like this
SELECT SEC_TO_TIME(SUM(`Total_hours`) ) FROM `month_data` GROUP BY `Emp_no`;
there is a simple SUM function which can do this for you, it returns the total time in seconds though.
In order to turn that into readable time you can use the MySQL function SEC_TO_TIME.
edit
If the said column is not a TIME column you can CAST it to be handled as this type of column using CAST() the needed SQL would look something like
SELECT SEC_TO_TIME(SUM(CAST(`Total_hours` AS TIME)) ) FROM `month_data` GROUP BY `Emp_no`;
My suggestion would be to change the column type to TIME though.
edit 2
I was under the assumption that SUM() would be smart enough to convert the time to seconds and come up with the correct sum of the given times.
Not sure why yet but this is not the case, therefore you need to convert the given times to seconds first.
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(`Total_hours`)) ) FROM `month_data` GROUP BY `Emp_no`;
Now I have not tested this but TIME_TO_SEC() seems to accept VARCHAR just fine so need to CAST() the column anymore.
take a look at this:
echo OverallTime($allTimes);
$allTimes = array();
function OverallTime($allTimes) {
$minutes = 0;
foreach ($allTimes as $time) {
list($hour, $minute) = explode(':', $time);
$minutes += $hour * 60;
$minutes += $minute;
}
$hours = floor($minutes / 60);
$minutes -= $hours * 60;
return sprintf('%02d:%02d', $hours, $minutes);
<?php
$total = [
'00:02:55',
'00:07:56',
'01:03:32',
'01:13:34',
'02:13:44',
'03:08:53',
'03:13:54'
];
$sum = strtotime('00:00:00');
$sum2=0;
foreach ($total as $v){
$sum1=strtotime($v)-$sum;
$sum2 = $sum2+$sum1;
}
$sum3=$sum+$sum2;
echo date("H:i:s",$sum3);
?>
In case this is useful to someone looking for this, this is what I use on my music website. This code gets the duration in seconds of all the songs in an album, adds them up, and returns the total album length in hh mm ss.
$record_id = $this->record->id; <!--variable for record-->
.$query = 'SELECT SUM(duration) FROM #__songs WHERE `record_id` = '. $db->quote( (int) $record_id ); <!--selects the duration of all the songs in the album-->
$db->setQuery($query);
$results = $db->loadResult();
echo gmdate("H:i:s", $results); <!--echo total time in hh mm ss.-->
Not an expert here. If you see something, say something XD

how to add time in php 5.3.19

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);

php sum time with variable in while loop

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

Total all time stored in an array PHP

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

Categories