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
Related
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
i have two different break time
default break time
extra break time
here i want to sum of two times and display 12 hrs format
EX :
$default_time = "00:30";
$extra_time = "00:25";
my expected output : 00:55
but now display 01:00
this is my code
$default_time = $work_data->break_time;
$break_time = $work_data->extra_time;
$total_break = strtotime($default_time)+strtotime($break_time);
echo date("h:i",strtotime($total_break));
Here is the function you can calculate total time by passing the arguments to functions.
$hours, $min are supposed variable which is zero
$default_time = "00:30";
$break_time = "00:25";
function calculate_total_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 calculate_total_time($default_time, $break_time); # 00:55
There is one function call to strtotime function too much.
You should leave out the strtotime() call in the last line, as $total_break already is a UNIX timestamp:
$total_break = strtotime($default_time)+strtotime($break_time);
echo date("h:i",$total_break);
The problem is that you're trying to add too specific timestamps, but what you're trying to achieve is adding two durations. So you need to convert those timestamps into durations. For that you need a base, which in your case is 00:00.
$base = strtotime("00:00");
$default_time = $work_data->break_time;
$default_timestamp = strtotime($default_time);
$default_duration = $default_timestamp - $base; // Duration in seconds
$break_time = $work_data->extra_time;
$break_timestamp = strtotime($break_time);
$break_duration = $break_timestamp - $base; // Duration in seconds
$total_break = $default_duration + $break_duration; // 55 min in seconds
// If you want to calculate the timestamp 00:55, just add the base back to it
echo date("H:i", $base + $total_break);
Consider using standard DateTime and DateInterval classes. All you will need is to convert your second variable value to interval_spec format (see http://php.net/manual/en/dateinterval.construct.php for details):
$defaultTime = "00:30";
$breakTime = "PT00H25M"; // Or just 'PT25M'
$totalBreak = (new DateTime($defaultTime))->add($breakTime);
echo $totalBreak->format('H:i');
You could try the following code fragment:
$time1 = explode(":", $default_time);
$time2 = explode(":", $break_time);
$fulltime = ($time1[0] + $time2[0]) * 60 + $time1[1] + $time2[1];
echo (int)($fulltime / 60) . ":" . ($fulltime % 60);
<?php
$time = "00:30";
$time2 = "00:25";
$secs = strtotime($time2)-strtotime("00:00:00");
$result = date("H:i:s",strtotime($time)+$secs);
print_r($result);
?>
Use below code you will definitely get your answers.
$default_time = "00:30:00";
$extra_time = "00:25:00";
$secs = strtotime($extra_time)-strtotime("00:00:00");
$result = date("H:i:s A",strtotime($default_time)+$secs);
echo $result;die;
You can modify above code as per your need.
You could try the following:
$default_time = $work_data->break_time;
$date_start = new DateTime($default_time);
$break_time = $work_data->extra_time;
$interval = new DateInterval("PT" . str_replace(":", "H", $break_time) . "M");
$date_end = $date_start->add($interval);
echo $date_end->format("H:i");
Note that this doesn't account for times which span a 24 hour period
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 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