I have statistics that require a 'Last Updated' section on a dynamic image, and is expressed in hours. This is done with the following:
$lastDate = $StatData->date;
$now = date("Y-m-d G:i:s");
$hours = (strtotime($now) - strtotime($lastDate)) / 3600;
Displaying $hours on the image with an imagettftext works just fine. It's just that it's up to 16 characters in length. So to fix that, I attempted the following:
if($hours < 10) {
substr($hours,0,4);
} else {
substr($hours,0,5);
}
The intention was to display no more than two decimals. The result was no change. As if the code wasn't even there.
So my question is one of two: 1: How do i get this to work? 2: I know there is a way to limit the decimal places, without using substr, but what is it? Might be a better solution.
use round():
$hours = round((strtotime($now) - strtotime($lastDate)) / 3600, 2); // 2 decimals
You can also use number_format
$hours = number_format($hours, 2);
Related
I am having issue in SUM of Time or Duration from my Database field.
Suppose. I have 5 Records
1. 00:25:32
2. 00:08:52
3. 00:33:22
4. 00:25:30
5. 00:15:12
how to sum all the times with php.
I spent a lot time on it but failed.
I have tried this.
$time = "00:58:30";
$time2 = "00:12:35";
$secs = strtotime($time2)-strtotime("00:00:00");
$result = date("H:i:s",strtotime($time)+$secs);
echo $result;
But it not works good for multiple records
Thanks to all of you. I have fixed it. I checked some other question on Stackoverflow and i got answer what i wanted.
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(`SongDuration`))) AS `TimeSum` FROM `mu_forms_competition_entries`
Durations are not dates. What would tomorrow at 35:00:00 mean?
The closest builtin feature is DateInterval, but in order to use it as-is your input data needs some rewriting ('00:25:32' into 'PT00H25M32S') and I don't think it supports addition anyway.
It isn't difficult to make the calculations yourself (error checking omitted and negative times not considered for brevity):
function timeToSeconds(string $time): int
{
[$h, $m, $s] = explode(':', $time);
return $s + 60 * $m + 3600 * $h;
}
function secondsToTime(int $seconds): string
{
return sprintf(
"%02d:%02d:%02d",
floor($seconds / 3600),
floor(($seconds / 60) % 60),
$seconds % 60
);
}
$times = [
'00:25:32',
'00:08:52',
'00:33:22',
'00:25:30',
'00:15:12',
];
$total = 0;
foreach ($times as $time) {
$total += timeToSeconds($time);
}
echo secondsToTime($total);
If you're allowed to change the database query there's probably a builtin function to convert to seconds right from SQL. For instance, MySQL has TIME_TO_SEC().
Last but not least, if your database actually has a Time column type, perhaps it allows to SUM() it.
Sorry , I can't find good title for it.
I want to convert minutes and hours to a number.
Ex. :-
$hours = "3";
$minutes = "30";
It should show 3.5.
If I write 4 hours and 15 minutes then it shows 4.25.
I want to convert like this.
You need to just divide the minutes by there maximum value (60) and then add that to your hours to get the full value.
$hours = "3";
$minutes = "30";
echo $hours + ($minutes / 60);
Demo: https://eval.in/819401
Also note the + here is adding, not concatenating. If you concatenate you get an extra decimal place appended to the hours value because the decimal is 0.fractionvalue.
$convertedTime = (($hours * 60) + $minutes) / 60;
You will need to add some rounding or cutting off decimal digits
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);
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;
I have 13 digit number and want to create date and time with include milisecond
Example code is like this this is my php script
$mil = 1328910295939;
$seconds = $mil / 1000;
$showdate = date('Y:m:d H:i:s', $seconds) ;
echo "$showdate";
the result is like this 2012:02:10 15:44:55.xxx ===> xxx is 3 digit miliseconds that i want to show up.
and how to include with 3 digit milisecond after H:i:s
Please help me.....
How about something like this?
$mil = 1328910295939;
function toTimestamp($milliseconds)
{
$seconds = $milliseconds / 1000;
$remainder = round($seconds - ($seconds >> 0), 3) * 1000;
return date('Y:m:d H:i:s.', $seconds).$remainder;
}
echo toTimestamp($mil);
Tadaa!
It should be pretty quick too.
Also, this is the output: 2012:02:10 15:44:55.939 - why you're not using - for delimiting the date portion beats me.
Just trim off the last two characters:
substr(date('Y-m-d H:i:s.u',1328910295939), 0, -2)
Here's a function that will do it for you accurately (by rounding, not cutting off):
function getTimestamp()
{
$microtime = floatval(substr((string)microtime(), 1, 8));
$rounded = round($microtime, 3);
return date("Y-m-d H:i:s") . substr((string)$rounded, 1, strlen($rounded));
}
Explanation:
microtime() returns 2 numbers as 1 string, delimited by a space. the 2nd number is the amount of seconds since the unix epoch, and the 1st number is the amount of microseconds since the 2nd number. Basically, the first number is the amount of microseconds expressed in a 8 precision format (0.00000000) and trailing 0s are never cut off.
We round this to a precision of 3 (0.00), and cut off the leading 0, and append that to the actual timestamp.
For some reason the php doc for u, microseconds, doesn't seem to be actually supported. I get 0.000 everytime when using that method. So I resorted to microtime() as a backup solution.
$t = 1328910295939;
echo date('Y-m-d H:i:s.', substr($t, 0, -3)) . substr($t, -3);
Output: 2012-02-10 16:44:55.939 (it depends on the timezone)
Because these answers were all quite amusing in their complexity, here's yet another answer for future posterity that uses the asker's original code and doesn't treat numbers as strings.
$mil = 1328910295939;
$seconds = floor($mil / 1000);
$fraction = $mil % 1000;
$showdate = date('Y:m:d H:i:s',$seconds) . ".$fraction";
echo "$mil<br>
$seconds<br>
$fraction<br>
$showdate";
Outputs the following on a server set to the EST time zone:
1328910295939
1328910295
939
2012:02:10 16:44:55.939
Since I can't add a comment to the of #westie, and if anyone need this, I allow myself to add the missing line to his function for decimals < 100 :
$seconds = $milliseconds / 1000;
$remainder = round($seconds - ($seconds >> 0), 3) * 1000;
$remainder = sprintf("%03d", $remainder);
return gmdate('H:i:s.', $seconds).$remainder;
Note that I also use gmdate to prevent time zone issues (i suppose you would work on milliseconds for duration calculation and not date calculation)