How can I sum multiple time in laravel 5.2 - php

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

Related

How to convert h:m:s to float and float to h:m:s php

I want to convert time value with second to float and than do some calculation on it and convert it again to time value using php
I have used the function describe below but it has only hour and minute calculation it display wrong amount if second value is there.
i found this function from time conversion to float
I have used function for convert time to float is
function hours_tofloat($val){
if (empty($val)) {
return 0;
}
$parts = explode(':', $val);
return $parts[0] + floor(($parts[1]/60)*100) / 100;
}
hours_tofloat("00:02:37");
if i use above function for 00:02:37 time value it gives me wrong float no 0.03 because above function dose not have option for second. so help me and guide how to calculate it
Modify your code as follows. It will return the time in seconds.
$val = '00:02:37';
function hours_tofloat($val){
if (empty($val)) {
return 0;
}
$parts = explode(':', $val);
return (int) (($parts[0] * 60 *60) + $parts[1]*60 + $parts[2]);
}
echo hours_tofloat($val);
Output: 00:02:37 = 157
It returns
157
Why don't you use EPOCH time routines? Epoch time is an integer representing seconds based on 1 Jan 1970. You don't need the date part so you can have the following approach:
<?php
$time = '00:02:37';
$date = new DateTime("1970-01-01T$time+00:00");
echo 'Seconds = '.$date->format('U');
?>
Output
Seconds = 157
$val = "00:02:37";
/* function converts time value to float */
function time_to_float($val){
$parts = explode(':', $val);
$hour_val = 0;
$hour_val = $parts[0];
$min_val = $parts[1];
$second_val = $parts[2];
return ($hour_val +(($min_val* 1/60))+($second_val * 1/3600));
}
$value = time_to_float($val);// 0.043611111111111
/* function to convert float to time */
$res = float_to_time($value);//00:02:37
function float_to_time($value){
$value1 = explode('.',$value);
$hours = $value1[0];
$min_in_float = ($value - $hours) * 60/1;
$min_val = explode('.',$min_in_float);
$min_val = $min_val[0];
$min_in_float = $min_in_float - $min_val;
$second_val = $min_in_float * 60/1;
$second_val = round($second_val);
if($hours < 10){
$hours = "0".$hours;
}
if($min_val < 10){
$min_val = "0".$min_val;
}
if($second_val < 10){
$second_val = "0".$second_val;
}
return $hours.":".$min_val.":".$second_val;
}
I got reference about the calculation from
https://www.calculatorsoup.com/calculators/time/time-to-decimal-calculator.php
https://www.calculatorsoup.com/calculators/time/decimal-to-time-calculator.php
With strtotime I get the seconds immediately. UTC must be used as the time zone.
$time = '00:02:37';
$seconds = strtotime('1970-01-01 '.$time.' UTC'); //157
gmdate can be used to convert an integer into a time H:i:s.
$seconds = 157;
$timeHis = gmdate('H:i:s',strtotime('1970-01-01 UTC +'.$seconds.' Seconds'));
//'00:02:37'
The number of hours must not exceed 23 and the number of seconds $seconds must be less than 86400 (= 1 Day). Negative times are also not supported.

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

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

Summing time in DateTime() objects

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

Categories