PHP time string format to number of hours as integer - php

I'm getting aggregate values of time passed from DB in formats such as
"84:00:00"
"14:30:00"
"20:00:00"
"02:00:00"
"120:00:00"
and I need to convert that to integer values as follows:
84
14.5
20
2
120
is there any way to achieve this (rather simply); to my understanding strtotime() returns false if the value is greater than 24:00:00

Solution (thanks to #deceze):
if($time != '0') {
list($hours, $minutes) = explode(':', $time);
return $hours + ($minutes / 60);
}
return 0;

You could use the function TimeToSec() and then just devide seconds with 3600, and you will receive number of hours.
function TimeToSec($time) {
$sec = 0;
foreach (array_reverse(explode(':', $time)) as $k => $v) $sec += pow(60, $k) * $v;
return $sec;
}
echo TimeToSec('14:30:00') / 3600;
demo

PHP's time functions won't help you much, since you're dealing with durations, not timestamps
#deceze, you are wrong:
foreach (['84:00:00', '14:30:00', '20:00:00', '02:00:00', '120:00:00'] as $time)
{
list($h, $m, $s) = explode(':', $time);
$diff = mktime($h, $m, $s) - mktime(0, 0, 0);
print_r($diff / 60 / 60);
}

Related

How to calculate negative / positive times and greater than 24:00?

I have to make a calculation with times like these that come from an array:
+04:43
03:33
-10:33
I tried using Datetime and stuff but the class just broke when it surpassed 24:00 time (10:00 + 20:00 for example). So I tried something like this:
I transformed all my hh:mm to seconds with explode:
foreach($stringSaldo as $saldo) {
$horaM[] = explode(':',$saldo);
}
$totalHora = 0;
$totalMin = 0;
foreach($horaM as $hora) {
$totalHora = ($totalHora + $hora[0]);
$totalMin =( $totalMin + $hora[1]);
}
$totalHora = $totalHora * 3600;
$totalMin = $totalMin * 60;
$totalSeconds = $totalHora + $totalMin;
Then I tried to make that seconds in time:
$hours = floor($totalSeconds / 3600);
$minutes = floor(($totalSeconds / 60) % 60);
$seconds = $totalSeconds % 60;
echo $hours. ":" . $minutes;
For some reason when I have times like: -03:34 and +01:00 the calculation fails, it gives -02:-26 but it should be -02:34.
What am I doing wrong?
I think I have this ironed out. It is important that you do the arithmetic with the absolute values and separately handle the sign. I have included some zero padding to ensure that you are getting a consistent string result. My regular expression makes the + or - optional.
Code: (Demo of your 3 test cases)
function timeToSeconds($time) {
if (!preg_match('~([+-]?)(\d{2}):(\d{2})~', $time, $out)) {
echo "failed to parse $time\n";
return 0;
} else {
return (($out[2] * 3600) + $out[3] * 60) * ($out[1] == '-' ? -1 : 1);
}
}
function secondsToTime($seconds) {
$sign = $seconds < 0 ? '-' : '';
$abs = abs($seconds);
return $sign . str_pad(floor($abs / 3600), 2, '0', STR_PAD_LEFT) . ':' . str_pad(floor($abs / 60 % 60), 2, '0', STR_PAD_LEFT);
}
$times = ['-03:34', '+01:00'];
$seconds = 0;
foreach ($times as $time) {
$seconds += timeToSeconds($time);
}
echo $seconds; // -9240
echo "\n---\n";
echo secondsToTime($seconds); // -02:34
Relevant resource: https://stackoverflow.com/a/3856312/2943403
p.s. When you split time on :, the hours may be positive or negative, but the minutes will always be positive. This is a fundamental issue with your posted snippet.

PHP Calling just part of string item

So I have not yet learned PHP but our guy that would normally write the functions for our site is busy. So I'm attempting to solve this problem with very limited knowledge. I need to convert 4 digit army time (0800, 0815, 0830, 0845, 0900...) into standard time (8:00AM, 8:15AM,...). I wrote an equation but its returning all the hours as 12 and always PM. Here's my equation...
function convert_army_to_regular($time) {
$hours = substr($time, 0, 1);
$minutes = substr($time, 2, 3);
if ($hours > 12) {
$hours = $hours - 12;
$ampm = 'PM';
} else if ($hours = 12) {
$ampm = 'PM';
} else {
if ($hours < 11){
$ampm = 'AM';
}
}
return $hours . ':' . $minutes . $ampm;
}
What am I doing wrong?
You have two issues with your code, = is an assignment. You need to use == for a comparison (or === would also work, that checks the type as well).
The second issue is the substr. That function takes the position to start as parameter 1 and the number of characters to advance as 2. So your second parameter should be 2, in both examples.
$hours = substr($time, 0, 2);
$minutes = substr($time, 2, 2);
You also can cast it to an int and that will remove the leading 0 if it is less than 10.
$hours = (int)substr($time, 0, 2);
You also could do this with a regex:
echo preg_replace_callback('/(\d{2})(\d{2})/', function($match) {
$hours = (int)$match[1];
$minutes = $match[2];
$median = 'AM';
if($hours > 12 ) {
$hours = $hours - 12;
$median = 'PM';
}
return $hours . ':' . $minutes . $median;
},'1800');
Just use date to convert from military to standard time:
$armyTime = "2300";
$time_in_12_hour_format = date("g:i a", strtotime($armyTime));
echo $time_in_12_hour_format;
Result: 11:00 pm
Much easier to leverage the strtotime function and date.
$stime = '0830';
echo date("g:ia", strtotime($stime));
which results in 8:30am

Convert time in HH:MM:SS format to seconds only?

How to turn time in format HH:MM:SS into a flat seconds number?
P.S. Time could be sometimes in format MM:SS only.
No need to explode anything:
$str_time = "23:12:95";
$str_time = preg_replace("/^([\d]{1,2})\:([\d]{2})$/", "00:$1:$2", $str_time);
sscanf($str_time, "%d:%d:%d", $hours, $minutes, $seconds);
$time_seconds = $hours * 3600 + $minutes * 60 + $seconds;
And if you don't want to use regular expressions:
$str_time = "2:50";
sscanf($str_time, "%d:%d:%d", $hours, $minutes, $seconds);
$time_seconds = isset($seconds) ? $hours * 3600 + $minutes * 60 + $seconds : $hours * 60 + $minutes;
I think the easiest method would be to use strtotime() function:
$time = '21:30:10';
$seconds = strtotime("1970-01-01 $time UTC");
echo $seconds;
// same with objects (for php5.3+)
$time = '21:30:10';
$dt = new DateTime("1970-01-01 $time", new DateTimeZone('UTC'));
$seconds = (int)$dt->getTimestamp();
echo $seconds;
demo
Function date_parse() can also be used for parsing date and time:
$time = '21:30:10';
$parsed = date_parse($time);
$seconds = $parsed['hour'] * 3600 + $parsed['minute'] * 60 + $parsed['second'];
demo
If you will parse format MM:SS with strtotime() or date_parse() it will fail (date_parse() is used in strtotime() and DateTime), because when you input format like xx:yy parser assumes it is HH:MM and not MM:SS. I would suggest checking format, and prepend 00: if you only have MM:SS.
demo strtotime()
demo date_parse()
If you have hours more than 24, then you can use next function (it will work for MM:SS and HH:MM:SS format):
function TimeToSec($time) {
$sec = 0;
foreach (array_reverse(explode(':', $time)) as $k => $v) $sec += pow(60, $k) * $v;
return $sec;
}
demo
$time = 00:06:00;
$timeInSeconds = strtotime($time) - strtotime('TODAY');
You can use the strtotime function to return the number of seconds from today 00:00:00.
$seconds= strtotime($time) - strtotime('00:00:00');
In pseudocode:
split it by colon
seconds = 3600 * HH + 60 * MM + SS
Try this:
$time = "21:30:10";
$timeArr = array_reverse(explode(":", $time));
$seconds = 0;
foreach ($timeArr as $key => $value)
{
if ($key > 2) break;
$seconds += pow(60, $key) * $value;
}
echo $seconds;
Simple
function timeToSeconds($time)
{
$timeExploded = explode(':', $time);
if (isset($timeExploded[2])) {
return $timeExploded[0] * 3600 + $timeExploded[1] * 60 + $timeExploded[2];
}
return $timeExploded[0] * 3600 + $timeExploded[1] * 60;
}
function time2sec($time) {
$durations = array_reverse(explode(':', $item->duration));
$second = array_shift($durations);
foreach ($durations as $duration) {
$second += (60 * $duration);
}
return $second;
}
echo time2sec('4:52'); // 292
echo time2sec('2:01:42'); // 7302
On Windows 32 bit PHP version: 7.2.31 i get some error on all versions posted here.
If the time was 00:00:00 or 00:00:00 the zeros 00 were returned and used as "" empty string, and calculation with empty string returns error "A Non WELLNUMERIC blabla.
This Works also with more then 24hours:
function TimeToSec(string $time) {
$timearray = explode(":",$time);
$hours = (int)$timearray[0];
$minutes = (int)$timearray[1];
$seconds = (int)$timearray[2];;
//echo "Hours: " . $hours ."<br>";
//echo "minutes: " . $minutes ."<br>";
//echo "seconds: " . $seconds ."<br>";
$value = ($hours * 3600) + ($minutes * 60) + $seconds;
return $value;
}
echo TimeToSec("25:00:30");
<?php
$time = '21:32:32';
$seconds = 0;
$parts = explode(':', $time);
if (count($parts) > 2) {
$seconds += $parts[0] * 3600;
}
$seconds += $parts[1] * 60;
$seconds += $parts[2];

Output is in seconds. convert to hh:mm:ss format in php

My output is in the format of 290.52262423327 seconds. How can i change this to 00:04:51?
The same output i want to show in seconds and in HH:MM:SS format, so if it is seconds, i want to show only 290.52 seconds.(only two integers after decimal point)? how can i do this?
I am working in php and the output is present in $time variable. want to change this $time into $newtime with HH:MM:SS and $newsec as 290.52.
Thanks :)
1)
function foo($seconds) {
$t = round($seconds);
return sprintf('%02d:%02d:%02d', ($t/3600),($t/60%60), $t%60);
}
echo foo('290.52262423327'), "\n";
echo foo('9290.52262423327'), "\n";
echo foo(86400+120+6), "\n";
prints
00:04:51
02:34:51
24:02:06
2)
echo round($time, 2);
Try this one
echo gmdate("H:i:s", 90);
For till 23:59:59 hours you can use PHP default function
echo gmdate("H:i:s", 86399);
Which will only return the result till 23:59:59
If your seconds is more then 86399 than
with the help of #VolkerK answer
$time = round($seconds);
echo sprintf('%02d:%02d:%02d', ($time/3600),($time/60%60), $time%60);
will be the best options to use ...
Edit: A comment pointed out that the previous answer fails if the number of seconds exceeds a day (86400 seconds). Here's an updated version. The OP did not specify this requirement so this may be implemented differently than the OP might expect, and there may be much better answers here already. I just couldn't stand having provided an answer with this bug.
$iSecondsIn = 290.52262423327;
// Account for days.
$iDaysOut = 0;
while ($iSecondsIn >= 86400) {
$iDaysOut += 1;
$iSecondsIn -= 86400;
}
// Display number of days if appropriate.
if ($iDaysOut > 0) {
print $iDaysOut.' days and ';
}
// Print the final product.
print date('H:i:s', mktime(0, 0, $iSecondsIn));
The old version, with the bug:
$iSeconds = 290.52262423327;
print date('H:i:s', mktime(0, 0, $iSeconds));
Try this:
$time = 290.52262423327;
echo date("h:i:s", mktime(0,0, round($time) % (24*3600)));
Based on https://stackoverflow.com/a/3534705/4342230, but adding days:
function durationToString($seconds) {
$time = round($seconds);
return sprintf(
'%02dD:%02dH:%02dM:%02dS',
$time / 86400,
($time / 3600) % 24,
($time / 60) % 60,
$time % 60
);
}
I dont know if this is the most efficient way, but if you also need to display days, this works:
function foo($seconds) {
$t = round($seconds);
return sprintf('%02d %02d:%02d:%02d', ($t/86400%24), ($t/3600) -(($t/86400%24)*24),($t/60%60), $t%60);
}
Try this :)
private function conversionTempsEnHms($tempsEnSecondes)
{
$h = floor($tempsEnSecondes / 3600);
$reste_secondes = $tempsEnSecondes - $h * 3600;
$m = floor($reste_secondes / 60);
$reste_secondes = $reste_secondes - $m * 60;
$s = round($reste_secondes, 3);
$s = number_format($s, 3, '.', '');
$h = str_pad($h, 2, '0', STR_PAD_LEFT);
$m = str_pad($m, 2, '0', STR_PAD_LEFT);
$s = str_pad($s, 6, '0', STR_PAD_LEFT);
$temps = $h . ":" . $m . ":" . $s;
return $temps;
}
Personally, going off other peoples answers I made my own parser.
Works with days, hours, minutes and seconds. And should be easy to expand to weeks/months etc.
It works with deserialisation to c# as well
function secondsToTimeInterval($seconds) {
$t = round($seconds);
$days = floor($t/86400);
$day_sec = $days*86400;
$hours = floor( ($t-$day_sec) / (60 * 60) );
$hour_sec = $hours*3600;
$minutes = floor((($t-$day_sec)-$hour_sec)/60);
$min_sec = $minutes*60;
$sec = (($t-$day_sec)-$hour_sec)-$min_sec;
return sprintf('%02d:%02d:%02d:%02d', $days, $hours, $minutes, $sec);
}
1)
$newtime = sprintf( "%02d:%02d:%02d", $time / 3600, $time / 60 % 60, $time % 60 );
2)
$newsec = sprintf( "%.2f", $time );
If you're using Carbon (such as in Laravel), you can do this:
$timeFormatted = \Carbon\Carbon::now()->startOfDay()->addSeconds($seconds)->toTimeString();
But $timeFormatted = date("H:i:s", $seconds); is probably good enough.
Just see caveats.
Here was my implementation with microseconds
/**
* #example 00 d 00 h 00 min 00 sec 005098 ms (0.005098 sec.ms)
*/
public function __toString()
{
// Add your code to get $seconds and $microseconds
$time = round(($seconds + $microseconds), 6, PHP_ROUND_HALF_UP);
return sprintf(
'%02d d %02d h %02d min %02d sec %06d ms (%s sec.ms)',
$time / 86400,
($time / 3600) % 24,
($time / 60) % 60,
$time % 60,
$time * 1000000 % 1000000,
$time
);
}
echo date('H:i:s', round($time)%86400);
Simple formatter with progressively added parts - sample:
formatTime(123) => 2m 3s
formatTime(7400) => 2h 3m 20s
formatTime(999999) => 11d 13h 46m 39s
function formatTime($secs)
{
$secs = max(0, intval($secs));
if($secs > 0){
$out = [];
$yrs = floor($secs / 31536e3);
if($yrs){
$out[] = $yrs."y";
}
$rem = $secs - $yrs * 31536e3;
$days = floor($rem / 86400);
if($days || $out){
$out[] = $days."d";
}
$rem -= $days * 86400;
$hrs = floor($rem / 3600);
if($hrs || $out){
$out[] = $hrs."h";
}
$rem -= $hrs * 3600;
$min = floor($rem / 60);
if($min || $out){
$out[] = $min."m";
}
$rem -= $min * 60;
$out[] = $rem."s";
return implode(" ", $out);
}
return 0;
}
echo date('H:i:s',$time);
echo number_format($time,2);
Numero uno... http://www.ckorp.net/sec2time.php (use this function)
Numero duo... echo round(290.52262423327,2);

function for converting time to number of seconds

On our site, we have a lot of swimming times that we would like to convert to seconds. i.e. 1:23:33.03 or 58:22.43. Is there a PHP function that can do this? A MySQL function?
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_time-to-sec
mysql> SELECT TIME_TO_SEC('22:23:00');
-> 80580
mysql> SELECT TIME_TO_SEC('00:39:38');
-> 2378
function time2seconds($time='00:00:00')
{
list($hours, $mins, $secs) = explode(':', $time);
return ($hours * 3600 ) + ($mins * 60 ) + $secs;
}
From here.
MySQL also has TIME_TO_SEC()
so if mysql without fractions not appropriate solution - here is another mine
$time = '1:23:33.03';
$parts = explode(':', $time);
$seconds = 0;
foreach ($parts as $i => $val) {
$seconds += $val * pow(60, 2 - $i);
}
echo $seconds;
Use the following program for converting time to seconds in php.
<?php
function time_to_sec($time) {
$hours = substr($time, 0, -6);
$minutes = substr($time, -5, 2);
$seconds = substr($time, -2);
return $hours * 3600 + $minutes * 60 + $seconds;
}
$result=time_to_sec('12:25:59');
echo $result;
?>
$current_time_in_seconds="01:21:44.24";
list($hours, $minutes, $seconds) = explode(":", $current_time_in_seconds);
$current_time_in_seconds=$hours*3600+$minutes*60+$seconds;
will get from
01:21:44.24
to
4904.24
Strtotime is what you need. You get a Unix timestamp which in this case would be the number of seconds.
I am a little confused but I think that you mean. 1 hour, 23 minuts and 23.03 seconds.
this is not difficult to do. I made this PHP function that does that. My php server doesn't want to start up, so I couldn't test it, but I think it should work.
function ConvertTimeToSeconds($T)
{
$exp = explode(":",$T);
$c = count($exp);
$r = 0;
if ($c == 2)
{
$r = (((int)$exp[0]) * 60) + ((int)$exp[1]);
}else{
$r = (((int)$exp[0]) * 3600) + (((int)$exp[1]) * 60) + ((int)$exp[2]);
}
return $r;
}
ConvertTimeToSeconds("1:23:33.03");

Categories