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.
Related
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 am quite new to PHP I need help in implementing the total Hours and minutes in PHP.
I have an array of time in PHP in hours, minutes and seconds
(array) Array
(
[0] => 01:10:00
[1] => 01:20:30
[2] => 00:00:10
)
My Expected output should be the total time in Hours, minutes and seconds (ex. 2:30:40)
$hours;
$minutes;
$seconds;
foreach( $thatArray as $v )
{
$subArray = explode(':', $v);
$hours += $subArray[0];
$minutes += $subArray[1];
$seconds += $subArray[2];
}
// output $hours / $minutes / $seconds, correctly formatting, etc
Not going to give you the codez. here's how you can do it:
Get the individual components of the time using explode()
Start by adding the seconds. If the result is greater than 60, increment minutes and so on.
The easiest way would probably be to convert all of them to a seconds representation, sum them, and convert them back. For example:
function timeToSeconds($time) {
$parts = explode(':', $time);
return $parts[0] * 3600 + $parts[1] * 60 + $parts[2];
}
function secondsToTime($seconds) {
$hours = floor($seconds / 3600);
$minutes = floor($seconds / 60) % 60;
$seconds %= 60;
return str_pad($hours, 2, '0', STR_PAD_LEFT) . ':' . str_pad($minutes, 2, '0', STR_PAD_LEFT) . ':' . str_pad($seconds, 2, '0', STR_PAD_LEFT);
}
$times = array('01:10:00', '01:20:30', '00:00:10');
$total = secondsToTime(array_sum(array_map('timeToSeconds', $times)));
Here's a demo.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Converting Seconds to HH:MM:SS
I have an integer as a number of seconds. I want to convert that integer into into hours/minutes/seconds like this:
1:45:32
If the number of seconds equates to less than one hour then it should return the string:
45:32
If the number of minutes is less than 10 it should return the string formatted like this:
3:25
And finally if the number of seconds equate to less than 1 minute, it should return the following:
0:04
What is the best way to do this in PHP?
The simpelst approch would be
if($seconds < 3600){
$format = 'i:s';
}else{
$format = 'G:i:s';
}
echo date($format, $seconds);
EDIT: this wouldnt fix your minutes < 10 problem.
you could handle the minutes by itself. like
$time = ($seconds >= 3600) ? date('G', $seconds).':' : '';
$time .= intval(date('i',$seconds)).':'.date('s', $seconds);
<?php
$seconds = (1*60 + 45)*60 + 32; // 1:45:32
define("SECONDS_IN_HOUR", 3600);
define("SECONDS_IN_MINUTE", 60);
// hours
if ($seconds >= SECONDS_IN_HOUR)
{
print floor($seconds/SECONDS_IN_HOUR) . ":";
$seconds = $seconds % SECONDS_IN_HOUR;
}
// minutes
if ($seconds >= SECONDS_IN_MINUTE)
{
print floor($seconds/SECONDS_IN_MINUTE) . ":";
$seconds = $seconds % SECONDS_IN_MINUTE;
}
// seconds
print $seconds;
?>
I think Rufinus is pretty close:
foreach(array(60 => ' 0:s', 3600 => 'i:s', 'G:i:s') as $val => $format)
{
if ($seconds < $val) break;
}
echo ltrim(ltrim(gmdate($format, $seconds), '0'), ' ');
This variant uses a configuration stored inside an array which associates a format string based on a time value in seconds (as key). The last element is the default format that will fall through.
Edit: Unfortunately there is no formatting code in date that allows to specify minutes w/o a leading there. Therefore the date string needs to be re-formatted to remove leading 0's occasionally. It's done with ltrim here.
function formatHMS($time) {
$s = $time % 60;
$time= floor($time/60);
$m = $time % 60;
$time= floor($time/60);
$h = floor($time);
$str = $s;
if ($m>0)
$str = "$m:$str";
if ($h>0)
$str = "$h:$str";
return $str;
}
Consider using explode() & implode() and then apply your logic of less-than & greater-than!
The function below outputs hours:0 whether the time is <1 hour or mins:0 when mins<1.
How can I show only the variables that are not zero?
Thank you.
function time_difference($endtime){
$hours =date("G",$endtime);
$mins =date("i",$endtime);
$secs =date("s",$endtime);
$diff="'hours': ".$hours.",'mins': ".$mins.",'sec': ".$secs;
return $diff;
}
$end_time =strtotime("+7 hours") - strtotime($entry->pubDate);
$difference = time_difference($end_time);
echo $difference;
Another possible approach:
function time_difference($endtime){
$times=array(
'hours' => date("G",$endtime),
'mins' => date("i",$endtime),
'secs' => date("s",$endtime),
);
//added a "just a moment ago" feature for you
if (intval($times['hours'], 10) == 0
&& intval($times['mins'], 10) == 0) {
return "just a moment ago";
}
$diff='';
foreach ($times as $k=>$v) {
$diff.=empty($diff) ? '' : ',';
$diff.=intval($v, 10) == 0 ? '' : "'$k':$v";
}
return $diff;
}
Use the ? operator.
$diff=($hours > 0) ? "'hours': ".$hours : "";
$diff=$diff.($minutes > 0) ? etc...
For larger time ranges, you'd better use maths instead of using date():
function time_difference($endtime){
// hours can get over 23 now, $endtime is in seconds
$hours = floor($endtime / 3600);
// modulo (%) already rounds down, not need to use floor()
$mins = $endtime / 60 % 60;
// the remainder of $endtime / 60 are seconds in a minute
$secs = $endtime % 60;
// this array holds the hour, minute and seconds if greater than 0
$diff = array();
if ($hours) $diff[] = "'hours': $hours";
if ($mins) $diff[] = "'mins': $mins";
if ($secs) $diff[] = "'sec': $secs";
// join the values with a comma
$diff = implode(',', $diff);
if (!$diff) { // hours, mins and secs are zero
$diff = "just a moment ago";
}
return $diff;
}
The below function would only return hours in the range 0 - 23. If the time exceeds a day, hours become zero:
function time_difference($endtime){
$hours = (int)date("G",$endtime);
$mins = (int)date("i",$endtime);
$secs = (int)date("s",$endtime);
// this array holds the hour, minute and seconds if greater than 0
$diff = array();
if ($hours) $diff[] = "'hours': $hours";
if ($mins) $diff[] = "'mins': $mins";
if ($secs) $diff[] = "'sec': $secs";
// join the values with a comma
$diff = implode(',', $diff);
if (!$diff) { // hours, mins and secs are zero
$diff = "just a moment ago";
}
return $diff;
}
(int) is needed to turn the string returned by date() into a string. "01" becomes 1 and "00" becomes "0" using this.
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).