get minutes of float - php

i have this code in php
$minutes = date("i", $time);
$seconds = date("s", $time);
$hours = date("H", $time);
$toMinutes = ($hours*60) + $minutes + ($seconds/60);
$KmPerHour = $distance / ($toMinutes/60);
$MperMin = ($distance*1000) / $toMinutes;
$KmPerMin = 1/($distance/$toMinutes);
$MperSec = 100/(($distance*1000)/($toMinutes*60));
all works except this line
$KmPerMin = 1/($distance/$toMinutes);
basicly calcule the time in minutes in running 1 kilometer (the distance is in kilometers)
but for example
10km in 00:39:00 > 39 mins results 3.9
but it should be 3:54 mins
how i can transform 3.9 to mins?

Try something like this:
$min = 3.9;
$min = floor($min) . ':' . ($min - floor($min)) * 60; //3:54
See demo

3.9 minutes is 3m54s, because nine tenths of a minute is fifty-four seconds.
Use the whole part 3 for minutes.
Multiply the fractional part 0.9 by 60 to get seconds.
The following PHP code:
$min = 3.9;
$intmin = floor($min);
$sec = ($min - $intmin) * 60;
if ($sec < 10) {
echo $intmin.':0'.$sec;
} else {
echo $intmin.':'.$sec;
}
will output:
3:54
You can even use fractional seconds, such as with 3.14159 minutes giving 3:08.4954.
I'd provide the code for handling hours as well but, if it's taking you that long to run a kilometre, you may want to find another exercise regime :-)
As an aside, KmPerMin is the wrong sense for what you're calculating, it should more rightly be called MinPerKm.

This code may help you
<?php
$KmPerMin = 3.9;
$KmPerMin = intval($KmPerMin) + (intval(( ($KmPerMin - intval($KmPerMin))*100 * 60)/100)+1)/100;
echo $KmPerMin; // shows 3.54
?>
to show the $KmPerMin in 3:54 format
echo explode(".",$KmPerMin)[0] . ":" . explode(".",$KmPerMin)[1]; // shows 3:54

Related

Difference between durations

I am creating a timesheet whereby it shows expected and actual hours.
The durations are saved like the below
23:15 - 23 hours and 15 mins
25:45 - 25 hours and 45 mins
I need to work out the difference in hours and mins between the two (extra hours worked)
I have tried the below
$acutal=='23:15';
$expected=='25:45';
$start_time = new DateTime("1970-01-01 $acutal:00");
$time = $start_date->diff(new DateTime("1970-01-01 $expected:00"));
This does work, however when the hours are over 24:00 it throws an error (obviously because it's reading it as time)
Uncaught exception 'Exception' with message 'DateTime::__construct():
Failed to parse time string (1970-01-01 25:45:00)
Is there another way to do this?
You could check if the number of hours are greater than 24, and if so, add a day, and remove 24 hours.
$actual='23:15';
$expected='25:45';
$day = 1;
list($hrs, $min) = explode(':', $expected);
if ($hrs > 24) { $day += 1; $hrs -= 24; }
$start_time = new DateTime("1970-01-01 $actual:00");
$time = $start_time->diff(new DateTime("1970-01-$day $hrs:$min:00"));
echo $time->format('%hh %Im');
Output:
2h 30m
Please also note that == is used to compare, not to assign.
You can also change the if ($hrs > 24) by while(), if there is 48 hours or more.
edit
As pointed out by #CollinD, if the time exceed the number of days of the month, it will fail. Here is another solution:
$actual='23:15';
$expected='25:45';
list($hrs, $min) = explode(':', $actual);
$total1 = $min + $hrs * 60;
list($hrs, $min) = explode(':', $expected);
$diff = $min + $hrs * 60 - $total1;
$start_time = new DateTime();
$expected_time = new DateTime();
$expected_time->modify("+ $diff minutes");
$time = $start_time->diff($expected_time);
echo $time->format('%hh %Im');
You can do it manually by keeping track of the number of minutes worked - this will be exact and will also allow you to show negative differences.
<?php
// get the difference in H:mm between two H:mm
function diff_time($actual, $expected) {
$diff_mins = mins($actual) - mins($expected);
return format_mins($diff_mins);
}
// convert a HH:mm to number of minutes
function mins($t) {
$parts = explode(':', $t);
return $parts[0] * 60 + $parts[1];
}
// convert number of minutes into HH:mm
function format_mins($m) {
$mins = $m % 60;
$hours = ($m - $mins) / 60;
// format HH:mm
return $hours . ':' . sprintf('%02d', abs($mins));
}
var_dump(diff_time('23:15', '25:45'));
var_dump(diff_time('25:15', '23:45'));
This outputs:
string(5) "-2:30"
string(4) "1:30"
.. first, 2:30 less than expected, for the second 1:30 more than expected.
You can try using datetime functions but it seems a lot more straightforward to me to treat the times as string, use split or explode to get hours and minutes, convert to integers, get the difference in minutes and convert it back to hours and minutes (integer divide by 60 and remainder).
$t1=explode(':',$expected);
$t2=explode(':',$actual);
$d=60*($t1[0]-$t2[0])+t1[1]-t2[1];
$result=str_pad(floor($d/60),2,'0',STR_PAD_LEFT).':'.str_pad($d%60,2,'0',STR_PAD_LEFT);

Multiply a Time String (HH:MM) by an Integer in PHP

I wish to multiply 2 variables so that one of them is in the hour format (hh:mm),
How can I do so? The answer I am getting is 0:
<?php
$num = 5;
$timeUnit = "00:01";
$waitingTime = $num * $timeUnit;
echo $waitingTime;
I need to get 00:05 (5 min) in the output, but I am getting 0.
Hope this will help you
$num=100;
$timeUnit="00:02";
$timeUnit;
$time=explode(":",$timeUnit);
$waitingTime=$num*$time[1];
$minute = sprintf("%02d", ($waitingTime%60));
$hour = sprintf("%02d", ($waitingTime/60));
$current_time = floor($hour).':'.($minute);
echo $current_time;
$num=20;
$timeUnit="00:03";
$time=explode(":",$timeUnit);
$waitingTime=$num*$time[1];
$sec=$time[0]+$waitingTime%60;
$hour=floor($waitingTime/60);
$timeUnit1="".$hour.":".$sec."";
$current=strtotime($timeUnit1); //seconds of current time
echo date("H:i",$current);
You can do like this
I ended up converting the time into seconds, did the multiply and converted it to "time format" again:
$num=200;
$timeUnit="00:01:00";
$time=explode(":",$timeUnit);
$sec=$time[1]*60;
$sec=$sec*$num;
$diff = $sec;
$format = sprintf('%02d:%02d:%02d', ($diff / 3600), ($diff / 60 % 60), $diff % 60);
echo $format;
Thanks for your help
You can't compute string and digits this way.
All you would have to do would be to create a function/method that would implement the behavior you want and use it

Formating integers in percentage in php

I have two integers that are $hours = 74 and $minutes = 20, the format I need to get them in is following: hours and minutes (without any spacing) in percentage of one hour. So in this case the final result should be 7433.
Just to make it more clear if the two numbers would be $hours = 74 and $minutes = 30, the final result should be 7450.
I have been trying to look for similar functions, but without any success.
Any help or guidance is much appreciated.
So really what you are looking for is $result = $hours . floor($minutes/60*100); ?
Or if you need the leading zeroes: $result = str_pad($hours,2,'0') . str_pad(floor($minutes/60*100),2,'0');
Save yourself the pain of coming up with code that handles cases where the value of $minutes >= 60 by using the DateTimeInterface objects. I admit, they may seem overkill in this situation, but they are very sturdy and reliable. Plus, if ever you'd want to add days, weeks, months, years or seconds to this code, the DateTimeInterface classes are already equipped for the job:
$now = new DateTime();
$comp = clone $now;
//2 identical datetime instances
//add hours + minutes to either one
$comp->add(
sprintf(
'PT%dH%dM',
$hours,
$minuts
)
);
//get difference in seconds
$diff = $comp->getTimeStamp() - $now->getTimeStamp();
//or echo, I used printf to limit the number of decimals to 2
printf(
'%.2f hours difference'
$diff/3600 //1 hour === 3600 seconds
);
Just browse the DateTime docs, and other classes/interfaces like DateInterval and others implementing the DateTimeInterface.
Just for completeness, here's how I'd set about doing this "manually"
$decimalT = $hours + floor($minutes/60) + ($minutes%60)/60
//add hours in case $minutes>= 60
//floor($minutes/60);
//get remainder minutes, converted to decimal hours
//($minutes%60)/60;
printf(
'%d hours + %d seconds == %.2f hours',
$hours,
$minutes,
$decimalT
);
Use this snippet of code:
$hours = 74;
$minutes = 20;
$totalMinutes = $hours * 60 + $minutes;
$percentage = floor(($totalMinutes * 100) / 60);
var_dump($percentage);

mysql convert decimal time to xx:xx format

I am trying to convert a decimal time into an actual time format with hours and minutes, ie: in xx:xx hours.
My query is:
select SUM(vt.vluchtdec) AS vluchttijddecimal
from tbl_vluchtgegevens vg
left join tbl_vluchttijd vt
on vg.vluchttijddec = vt.vluchttijdID
WHERE vg.vertrekdatum <=NOW();
And I am echoing
. $row['vluchttijddecimal'] .
I have also tried this, but this also still gives me my response in a decimal format:
$result = mysql_query("select SUM(vt.vluchtdec) AS vluchttijddecimal
from tbl_vluchtgegevens vg
left join tbl_vluchttijd vt
on vg.vluchttijddec = vt.vluchttijdID
WHERE vg.vertrekdatum <=NOW();");
while($row = mysql_fetch_array($result))
{
$dec = $row['vluchttijddecimal'];
function
convertTime($dec)
{
// start by converting to seconds
$seconds = $dec * 3600;
// we're given hours, so let's get those the easy way
$hours = floor($dec);
// since we've "calculated" hours, let's remove them from the seconds variable
$seconds -= $hours * 3600;
// calculate minutes left
$minutes = floor($seconds / 60);
// remove those from seconds as well
$seconds -= $minutes * 60;
// return the time formatted HH:MM:SS
return lz($hours).":".lz($minutes).":".lz($seconds);
}
// lz = leading zero
function lz($num)
{
return (strlen($num) < 2) ? "0{$num}" : $num;
}
echo "" .$dec."";
In MS Access I would do something like this:
CInt([vluchttijddecimal]) & ":" & Format([vluchttijddecimal]*60 Mod 60;"00")
But this does not work or I don't know how to do so in MySQL / php.
For anyone that is interested... This is how you would convert decimal time (Where 0.1 == 6 minutes) to hours and minutes (0.2333 == 14 minutes) in MYSQL alone. no PHP is needed. This also accounts for the need to round seconds to minutes.
SELECT CONCAT(FLOOR(timeInDec),':', LPAD(ROUND((timeInDec - FLOOR(timeInDec)) * 60) % 60,2,0)) AS TimeInHoursMinutes
FROM YourTable;
Replace timeInDec with the column name that contains the decimal time you would like to convert.
This will return 0:06 for 0.1000 decimal value so leading zeros are accounted for in single digit minutes.
You can do this in you SQL statement something like this:
SELECT CONCAT(CEIL(mydecimal),':', LPAD(Floor(mydecimal*60 % 60),2,'0')) as formated text
Where mydecimal is your unformatted field name
I think I have calculated your time values... although it was kinda pain.
It appears your "decimal time" is "hours.minutes"? Rather horrible and definitely not a good format: for dealing with time its best to stick to integers that specify either a total of minutes/seconds/hours or whatever granularity you need.
But assuming it is hours.minutes, you should be able to do it like this in PHP:
while($row = mysql_fetch_array($result))
{
$dec = $row['vluchttijddecimal'];
return sprintf("%2d:%2d", floor($dec), floor(($dec - floor($dec))*100));
}
Hopefully I am correct in assuming that you mean, for example that 2.5 hours = 2H 30mins. If so, then your 'time' is a time interval and is best represented by the DateInterval class.
This function will do what you want:-
/**
* Converts a 'decimal time' in the format 1.5hours to DateInterval object
*
* #param Int $decimalTime
* #return DateInterval
*/
function decTimeToInterval($decimalTime)
{
$hours = floor($decimalTime);
$decimalTime -= $hours;
$minutes = floor($decimalTime * 60);
$decimalTime -= ($minutes/60);
$seconds = floor($decimalTime * 3600);
$interval = new \DateInterval("PT{$hours}H{$minutes}M{$seconds}S");
return $interval;
}
echo decTimeToInterval(512.168)->format("%H:%I:%S");
See it working
If you want to add times in the format 'H:i' without converting them to and from decimals, you can do it like this:-
function sumTimes($time1, $time2)
{
list($hours1, $minutes1) = explode(':', $time1);
list($hours2, $minutes2) = explode(':', $time2);
$totalHours = $hours1 + $hours2;
$totalMinutes = $minutes1 + $minutes2;
if($totalMinutes >= 60){
$hoursInMins = floor($totalMinutes/60);
$totalHours += $hoursInMins;
$totalMinutes -= ($hoursInMins * 60);
}
return "$totalHours:$totalMinutes";
}
echo sumTimes('12:54', '100:06') . PHP_EOL;
echo sumTimes('12:54', '100:20') . PHP_EOL;
See it working
This is what I used for my Payroll System:
SELECT If(total_late>0, LPAD(CONCAT(REPLACE(FLOOR(total_late/60) + FORMAT(total_late%60*0.01,2), '.', ':'), ':00'), 8, 0), '00:00:00') FROM MyTable
I multiplied it by 0.01 because my variables are in Seconds. Eg. 60.00 = 1min
I would suggest this to include seconds. It is based on #Richard's solutions. Just notice I've changed CEIL by FLOOR in #Richard's solution.
SET #timeInDec=1.505;
SELECT CONCAT(FLOOR(#timeInDec),':', LPAD(FLOOR(#timeInDec*60 % 60),2,'0'),':', LPAD(FLOOR(MOD(#timeInDec*60 % 60,1)*100),2,0)) as timeInDec;

How to get total minutes to display as Xhrs, Xmin?

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.

Categories