I have to implement some functionality using time calculation and my app has following type of code.
date_default_timezone_set(auth()->user()->timezone);
$t_now = \Carbon\Carbon::parse(date('Y-m-d H:i:s'));
$t_allowed = \Carbon\Carbon::parse($shift_details->start_time) ;
#endphp
#php
$check = $t_allowed->diffForHumans($t_now);
$search = 'after';
$dff_min = $t_allowed->diffInSeconds($t_now, true);
$init = $dff_min;
$day = floor($init / 86400);
$hours = floor(($init - $day * 86400) / 3600);
$minutes = floor(($init / 60) % 60);
$seconds = $init % 60;
$late_not_late = $hours . ' hours ' . $minutes . ' minutes ' . $seconds . ' seconds ';
first i want to confirm that $dff_min = $t_allowed->diffInSeconds($t_now, true); is returning minutes or seconds? Acording to my knowledge $dff_min contain seconds
i know that hours could be calculate using (init /3600) but what is the meaning of following statement
$hours = floor(($init - $day * 86400) / 3600);
why developer subtracting $day * 86400 from $init?
similary we also can calculate seconds by $init/60 since in one minute there are 60 seconds but
what is meaning of following line
$minutes = floor(($init / 60) % 60);
and also why he is using Modulo here
$seconds = $init % 60;
\Carbon\Carbon::parse(date('Y-m-d H:i:s')) will call twice the timelib and will loose the microseconds, just do \Carbon\Carbon::now() and you don't need to reinvent the wheel, you can get this exact string with:
$t_now = \Carbon\Carbon::now();
$t_allowed = \Carbon\Carbon::parse($shift_details->start_time);
$late_not_late = $t_allowed->diffForHumans($t_now, ['parts' => 3, 'syntax' => CarbonInterface::DIFF_ABSOLUTE]);
$late_not_late will contain 2 days 9 hours 20 minutes
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";
I'm taking a total number of minutes and am trying to calculate total hrs & minutes.
If you do:
$elapsed = "6476"; // Trying to get 107:56 (107 hours, 56 min)
if ($elapsed > 60) { $format = "i:s"; }
if ($elapsed > 3600) { $format = "H:i:s"; }
$showdiff = gmdate($format, $elapsed);
The problem with this is it doesn't work for calculations above 23hrs 59min.
So, you can do simple division:
$elapsed = $elapsed / 60; // total hours
Only then you will get a fraction (in this case, 107.933333333). I need to keep this as hours and minutes. Any suggestions?
You should be able to use division (as you've stated) and modulus division to accomplish what you want.
$hours = floor($elapsed / 60);
$minutes = round(($elapsed / 60) % 60);
echo $hours . "hrs " . $minutes . "min";
you could try
$elapsed = $elapsed / 60; // total hours (107.933333333)
$parts = explode(".", $elapsed); // split 107.93333 into 2 parts using the . as a separator
$minutes = $parts[1] // $parts[0] is 107, this will be the .9333
$minutes = $minutes * 60 // = 55.99...
$minutes = round($minutes); // round 55.9999 up to 56
$hours = $parts[0];
echo "$hours hrs $minutes mins";
probably could be written a bit better but my excuse is I'm tired :)
That should give you an idea though and let you do what you need to.
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).
This question already has answers here:
Convert seconds to Hour:Minute:Second
(30 answers)
Closed 9 years ago.
For some reason I convert a time format like: 03:30 to seconds 3*3600 + 30*60, now. I wanna convert it back to its first (same) format up there. How could that be?
My attempt:
3*3600 + 30*60 = 12600
12600 / 60 = 210 / 60 = 3.5, floor(3.5) = 3 = hour
Now, what about the minutes?
Considering the value can be like 19:00 or 02:51.
I think you got the picture.
And by the way, how to convert 2:0 for example to 02:00 using RegEx?
This might be simpler
gmdate("H:i:s", $seconds)
PHP gmdate
$hours = floor($seconds / 3600);
$mins = floor($seconds / 60 % 60);
$secs = floor($seconds % 60);
If you want to get time format:
$timeFormat = sprintf('%02d:%02d:%02d', $hours, $mins, $secs);
If the you know the times will be less than an hour, you could just use the date() or $date->format() functions.
$minsandsecs = date('i:s',$numberofsecs);
This works because the system epoch time begins at midnight (on 1 Jan 1970, but that's not important for you).
If it's an hour or more but less than a day, you could output it in hours:mins:secs format with `
$hoursminsandsecs = date('H:i:s',$numberofsecs);
For more than a day, you'll need to use modulus to calculate the number of days, as this is where the start date of the epoch would become relevant.
Hope that helps.
Maybe the simplest way is:
gmdate('H:i:s', $your_time_in_seconds);
Let $time be the time as number of seconds.
$seconds = $time % 60;
$time = ($time - $seconds) / 60;
$minutes = $time % 60;
$hours = ($time - $minutes) / 60;
Now the hours, minutes and seconds are in $hours, $minutes and $seconds respectively.
Another solution that will give you the days, hours, minutes, and seconds for a passed-in seconds value:
function seconds_to_time($secs)
{
$dt = new DateTime('#' . $secs, new DateTimeZone('UTC'));
return array('days' => $dt->format('z'),
'hours' => $dt->format('G'),
'minutes' => $dt->format('i'),
'seconds' => $dt->format('s'));
}
print_r(seconds_to_time($seconds_value);
Extra logic will be needed for 'days' if the time is expected to be more than one year. Use str_pad() or ltrim() to add/remove leading zeros.
ITroubs answer doesn't deal with the left over seconds when you want to use this code to convert an amount of seconds to a time format like hours : minutes : seconds
Here is what I did to deal with this:
(This also adds a leading zero to one-digit minutes and seconds)
$seconds = 3921; //example
$hours = floor($seconds / 3600);
$mins = floor(($seconds - $hours*3600) / 60);
$s = $seconds - ($hours*3600 + $mins*60);
$mins = ($mins<10?"0".$mins:"".$mins);
$s = ($s<10?"0".$s:"".$s);
$time = ($hours>0?$hours.":":"").$mins.":".$s;
$time will contain "1:05:21" in this example.
If you were to hardcode it you would use modulus to extract the time as others suggested.
If you are returning the seconds from MySQL database, assuming you don't need the data in seconds format in your app, there is a much cleaner way to do it, you can use MySQL's SEC_TO_TIME and it will return time in hh:mm:ss format.
Eg.
SELECT SEC_TO_TIME(my_seconds_field) AS my_timestring;
Sorry this is too late but maybe useful
function mediaTimeDeFormater($seconds)
{
if (!is_numeric($seconds))
throw new Exception("Invalid Parameter Type!");
$ret = "";
$hours = (string )floor($seconds / 3600);
$secs = (string )$seconds % 60;
$mins = (string )floor(($seconds - ($hours * 3600)) / 60);
if (strlen($hours) == 1)
$hours = "0" . $hours;
if (strlen($secs) == 1)
$secs = "0" . $secs;
if (strlen($mins) == 1)
$mins = "0" . $mins;
if ($hours == 0)
$ret = "$mins:$secs";
else
$ret = "$hours:$mins:$secs";
return $ret;
}
echo mediaTimeDeFormater(216.064000);//3:36
something like this?
if(is_numeric($time)){
$value = array(
"years" => 0, "days" => 0, "hours" => 0,
"minutes" => 0, "seconds" => 0,
);
if($time >= 31556926){
$value["years"] = floor($time/31556926);
$time = ($time%31556926);
}
if($time >= 86400){
$value["days"] = floor($time/86400);
$time = ($time%86400);
}
if($time >= 3600){
$value["hours"] = floor($time/3600);
$time = ($time%3600);
}
if($time >= 60){
$value["minutes"] = floor($time/60);
$time = ($time%60);
}
$value["seconds"] = floor($time);
return (array) $value;
} else{
return (bool) FALSE;
}
grabbed from: http://www.ckorp.net/sec2time.php
Use modulo:
$hours = $time_in_seconds / 3600;
$minutes = ($time_in_seconds / 60) % 60;
just one small additional example
requested time in miliseconds
// ms2time( (microtime(true) - ( time() - rand(0,1000000) ) ) );
// return array
function ms2time($ms){
$return = array();
// ms
$return['ms'] = (int) number_format( ($ms - (int) $ms), 2, '', '');
$seconds = (int) $ms;
unset($ms);
if ($seconds%60 > 0){
$return['s'] = $seconds%60;
} else {
$return['s'] = 0;
}
if ( ($minutes = intval($seconds/60))){
$return['m'] = $minutes;
}
if (isset($return['m'])){
$return['h'] = intval($return['m'] / 60);
$return['m'] = $return['m'] % 60;
}
if (isset($return['h'])){
$return['d'] = intval($return['h'] / 24);
$return['h'] = $return['h'] % 24;
}
if (isset($return['d']))
$return['mo'] = intval($return['d'] / 30);
foreach($return as $k=>$v){
if ($v == 0)
unset($return[$k]);
}
return $return;
}
// ms2time2string( (microtime(true) - ( time() - rand(0,1000000) ) ) );
// return array
function ms2time2string($ms){
$array = array(
'ms' => 'ms',
's' => 'seconds',
'm' => 'minutes',
'h' => 'hours',
'd' => 'days',
'mo' => 'month',
);
if ( ( $return = ms2time($ms) ) && count($ms) > 0){
foreach($return as $key=>$data){
$return[$key] = $data .' '.$array[$key];
}
}
return implode(" ", array_reverse($return));
}
Here is another way with leading '0' for all of them.
$secCount = 10000;
$hours = str_pad(floor($secCount / (60*60)), 2, '0', STR_PAD_LEFT);
$minutes = str_pad(floor(($secCount - $hours*60*60)/60), 2, '0', STR_PAD_LEFT);
$seconds = str_pad(floor($secCount - ($hours*60*60 + $minutes*60)), 2, '0', STR_PAD_LEFT);
It is an adaptation from the answer of Flaxious.
If You want nice format like: 0:00:00 use str_pad() as #Gardner.
1 day = 86400000 milliseconds.
DecodeTime(milliseconds/86400000,hr,min,sec,msec)
Ups! I was thinking in delphi, there must be something similar in all languages.