I am getting times in format of "hh:mm:ss".
I am doing sum of all those times. But here I am getting two hours more than required. so, where is the actual problem.
My code is like,
foreach($result as $key=>$value)
{
$total_markin_time[] = date('H:i:s', strtotime($value['clock_in']));
}
Getting result like,
00:33:41
16:15:22
11:06:59
11:03:59
11:13:38
15:43:34
11:29:35
foreach ( $total_markin_time as $time )
{
list( $g, $i, $s ) = explode( ':', $time );
//echo $g."-";
$total_markin_seconds += $g * 60 * 60;
$total_markin_seconds += $i * 60;
$total_markin_seconds += $s;
}
//echo $total_markin_seconds; exit;
$total_markin_hours = floor( $total_markin_seconds / 3600 );
$total_markin_seconds -= $total_markin_hours * 3600;
$total_markin_minutes = floor( $total_markin_seconds / 60 );
$total_markin_seconds -= $total_markin_minutes * 60;
When I am doing sum on this, I am gettin result 77:26:48.
Where is the problem?
Updated:
Is there any problem with floor that I have read like,
The floor() function rounds a number DOWN to the nearest integer, if necessary.
There is no error and it works right.
Calculation:
hours: 0+16+11+11+11+15+11 = 75 hours
minutes: 33+15+6+3+13+43+29 = 142 = 2 hours and 22 minutes
seconds: 41+22+59+59+38+34+35 = 288 = 4 minutes and 48 seconds
The result of sum is 77:26:48.
If you want to get just the sum of hours you should use something like this
foreach ( $total_markin_time as $time )
{
list( $g, $i, $s ) = explode( ':', $time );
$total_markin_hours += $g;
}
It's simple. All your times adds to:
288 s = 4m 48s
142 m = 2h 22m
75 h
Which in result (add hours + minutes + seconds) gives 77:26:48
You may think that You only add hours independent of minutes and seconds, but You have to add overflows of minutes and seconds.
Related
This is not a duplicate question, but involves a little understanding about time.
I need a solution to the following problem
I have a number of specifically produced times (based on a date), that need to be rounded to the nearest 15 secs:
60 secs is 1 minute
meaning a regular round, floor, ceiling is to the nearest decimal (10/5)
which doesn't help me with time.
also since I'm dealing with secs, it could be that 59:59 will be rounded up to the nearest hour: e.g. 17:59:59 should be 18:00.
example:
6:17:29 rounded to 6:17:30
6:29:55 rounded to 6:30:00
20:45:34 rounded to 20:45:30
The following code does some of the job:
$hr = date('H',($resultStr));
$mn = date('i',($resultStr));
$sc = date('s',($resultStr));
$tot = ($hr * 60 * 60) + ($mn * 60) + $sc;
$totd = $tot / (60);
$totc = ceil($totd);
$totc = $totc / 60;
$hr = floor($totc);
$mn = ($totc - $hr)*60;
$mnflr = floor($mn);
$mn2 = $mn - $mnflr;
echo "$hr:$mnflr";
This results in:
18:35:17 rounded to: 18:36 (which is wrong)
18:31:49 rounded to: 18:32 (which is wrong)
As an aside:
$secs = date('U',($resultStr));
$round = ceil ( (($secs / 60 ) * 60 ));
$newtime = date('H:i:s',($round));
produces: 18:42:58 rounded to: 18:42:58 which is also incorrect
Please and thank you in advance....
You're massively overcomplicating this, just do rounding on the Unix timestamp level:
function roundMyTime($time)
{
$time = strtotime($time);
$time = 15*round($time/15);
echo date('H:i:s', $time)."\n";
}
roundMyTime('18:35:17');
roundMyTime('18:35:27');
roundMyTime('18:35:37');
roundMyTime('18:35:47');
roundMyTime('18:35:57');
roundMyTime('18:36:07');
roundMyTime('18:36:17');
Outputs:
18:35:15
18:35:30
18:35:30
18:35:45
18:36:00
18:36:00
18:36:15
Demo here.
$seconds = ($hr * 60 + $mn) * 60 + $sc; // convert to seconds
$rounded = round($seconds/15)*15; // round
$sc = $rounded % 60; // get seconds
$mn = ($rounded - $sc) / 60 % 60; // get minutes
$hr = ($rounded - $sc - $mn * 60) / 60; // get hours
Convert the date to seconds using strtotime and then just work in seconds.
$seconds = strtotime($date);
$seconds /= 15;
$seconds = round($seconds);
$seconds *= 15;
$date = date("Y-m-d H:i:s", $seconds);
I have array of items like this:
Array
(
[0] => 0:16:0
[1] => 0:0:8
[2] => 0:5:0
...
[n] => 0:3:1
)
There could be more arrays, they are symbolize
hours, minutes, seconds.
How can I calculate 0 + 1 + 2 + ... + n and to get final number of hours, minutes and seconds?
Try this code out
$arr = array('0:16:0', '25:12:5', '0:0:10', '0:5:0');
// converting all the times to seconds
$t_seconds = 0;
foreach ($arr as $v) {
sscanf($v, "%d:%d:%d", $hours, $minutes, $seconds);
$t_seconds += $hours * 3600 + $minutes * 60 + $seconds;
}
// condition if seconds calculated are negative
$sign = ($t_seconds < 0 ? '-' : '');
$t_seconds = abs($t_seconds);
// converting seconds, taking care of wrong minutes/seconds formats like 02:63:65
$hours = floor($t_seconds / 3600);
$minutes = floor(($t_seconds / 60) % 60);
$seconds = $t_seconds % 60;
// final format
$sum = $sign . sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds);
Result ($sum variable)
25:33:15
I solved by seperating hours, minutes, secounds as array from my foreach element. Then i call array, using array_sum
( thanks Rizier123 for point me on that function )
// receive values and calculate with current hours
$finalHourPause = array_sum($pauseArrayHours) . "\n";
$finalMinutePause = array_sum($pauseArrayMinutes) . "\n";
$finalSecoundsPause = array_sum($pauseArraySecounds) . "\n";
This is not a duplicate question, but involves a little understanding about time.
I need a solution to the following problem
I have a number of specifically produced times (based on a date), that need to be rounded to the nearest 15 secs:
60 secs is 1 minute
meaning a regular round, floor, ceiling is to the nearest decimal (10/5)
which doesn't help me with time.
also since I'm dealing with secs, it could be that 59:59 will be rounded up to the nearest hour: e.g. 17:59:59 should be 18:00.
example:
6:17:29 rounded to 6:17:30
6:29:55 rounded to 6:30:00
20:45:34 rounded to 20:45:30
The following code does some of the job:
$hr = date('H',($resultStr));
$mn = date('i',($resultStr));
$sc = date('s',($resultStr));
$tot = ($hr * 60 * 60) + ($mn * 60) + $sc;
$totd = $tot / (60);
$totc = ceil($totd);
$totc = $totc / 60;
$hr = floor($totc);
$mn = ($totc - $hr)*60;
$mnflr = floor($mn);
$mn2 = $mn - $mnflr;
echo "$hr:$mnflr";
This results in:
18:35:17 rounded to: 18:36 (which is wrong)
18:31:49 rounded to: 18:32 (which is wrong)
As an aside:
$secs = date('U',($resultStr));
$round = ceil ( (($secs / 60 ) * 60 ));
$newtime = date('H:i:s',($round));
produces: 18:42:58 rounded to: 18:42:58 which is also incorrect
Please and thank you in advance....
You're massively overcomplicating this, just do rounding on the Unix timestamp level:
function roundMyTime($time)
{
$time = strtotime($time);
$time = 15*round($time/15);
echo date('H:i:s', $time)."\n";
}
roundMyTime('18:35:17');
roundMyTime('18:35:27');
roundMyTime('18:35:37');
roundMyTime('18:35:47');
roundMyTime('18:35:57');
roundMyTime('18:36:07');
roundMyTime('18:36:17');
Outputs:
18:35:15
18:35:30
18:35:30
18:35:45
18:36:00
18:36:00
18:36:15
Demo here.
$seconds = ($hr * 60 + $mn) * 60 + $sc; // convert to seconds
$rounded = round($seconds/15)*15; // round
$sc = $rounded % 60; // get seconds
$mn = ($rounded - $sc) / 60 % 60; // get minutes
$hr = ($rounded - $sc - $mn * 60) / 60; // get hours
Convert the date to seconds using strtotime and then just work in seconds.
$seconds = strtotime($date);
$seconds /= 15;
$seconds = round($seconds);
$seconds *= 15;
$date = date("Y-m-d H:i:s", $seconds);
I have a website where users enter data including hours, for example they enter '1:00' (Meaning = 1 hour) and '00:15' (Meaning = 15 minutes) and '2:30' (Meaning = 2 hour and 30 minutes).
Now I need to make show them how many hours they have entered in total, when I calculate it by just doing $count += $time in a loop I am getting the correct number but not what is standing after the ':'.
1:00 + 00:15 + 2:30 will become '3' while it should be 3:45.
How would I do this? Also now that I am thinking about it, I will also need if it goes over 60 it adds 1 to the first number (A new hour).
Thanks.
First, calculates minutes, then calculate how many hours are those minutes and add them to the hours:
<?php foreach ($data as $entry) {
list($hour, $minutes) = explode(':', $entry);
$total_hours += $hour;
$total_minutes += $minutes;
}
$hours_from_minutes = floor($total_minutes / 60);
$total_hours += $hours_from_minutes;
$total_minutes -= $hours_from_minutes * 60;
echo "$total_hours:$total_minutes"
A simple solution that supports everything varying from 00:00:00 to just 00:00 and 00
$times = ['00:15', '01:00:13', '24:43:12', '00:00:34'];
$total_seconds = 0;
$total_minutes = 0;
$total_hours = 0;
foreach ($times as $time) {
$array = explode(':', $time);
switch (sizeof($array)) {
case 3:
$total_seconds += (int) $array[2];
case 2:
$total_minutes += (int) $array[1];
case 1:
$total_hours += (int) $array[0];
break;
default:
throw new Exception('got more than expected!');
}
}
$total_minutes += floor($total_seconds / 60);
$total_seconds %= 60;
$total_hours += floor($total_minutes / 60);
$total_minutes %= 60;
printf('%dh %dm %ds', $total_hours, $total_minutes, $total_seconds);
// upd coz strtotime is not for this Q
Try to use DateIntervals, they may help you.
http://php.net/manual/ru/class.dateinterval.php
I'm using my iTunes library to get data from about 1,100 mp3s and I'm running into a small issue in getting the duration of the library into minutes and seconds.
$duration = 1893642;
$minutes = bcmod(($duration / 60), 60);
$seconds = bcmod($duration, 60);
echo $minutes.":".$seconds; //returns 0:42
The problem is that this specific MP3 is actually 31:42. Any thoughts on why this isn't working?
$minutes = bcmod(($duration / 60), 60);
is taking the minutes modulo 60. Unless your track is over an hour it will always say 0.
You want it to be
$minutes = floor($duration / 60);
Try this function
function formatTime($secs) {
$times = array(3600, 60, 1);
$time = '';
$tmp = '';
for($i = 0; $i < 3; $i++) {
$tmp = floor($secs / $times[$i]);
if($tmp < 1) {
$tmp = '00';
}
elseif($tmp < 10) {
$tmp = '0' . $tmp;
}
$time .= $tmp;
if($i < 2) {
$time .= ':';
}
$secs = $secs % $times[$i];
}
return $time;
}
Not sure if the following function was available when this question was written, but as it's a question I've been asking myself so here goes.
I used the answer above:
$seconds = bcmod($row{'playtime_seconds'}, 60);
$minutes = floor($row{'playtime_seconds'} / 60);
$hours = floor($minutes / 60);
Which works for the majority of times, but there is no padding - so you can end up with 20:1 when it should be 20:01 - and it's not to good over an hour - one length comes in at length="1:70:9" - so an alternative is to use the "date" function.
<?=date("H:i:s", $duration); ?>
which returns 00:31:42 from that number of seconds
$duration_str = sprintf('%s:%02s:%02s',
floor($duration_int / 3600), // hours
floor($duration_int / 60) - floor($duration_int / 3600) * 60, // minutes
$duration_int % 60); // seconds
The *printf functions provide formatting. In this case the leading zero.
The minutes line is the most complex part, since you have to calculate the hours (duration [s] / 3600 [s/h]), then round down to integer (floor()), then multiply with 60 to transform to minutes, then subtract that from the total number of minutes (duration [s] / 60 [s/m]).
If your durations are shorter than an hour, the code is much simpler:
$duration_str = sprintf('%s:%02s', floor($duration_int / 60), $duration_int % 60);
The result is still correct for a duration greater than 59 minutes, but just not as readable (31560 minutes in the example).