Calculation percentage of hours

Asked

Viewed 1,335 times

4

How to calculate percentage between two times?

I tried like this and it wasn’t:

$tempo_total= "00:10:00";
$tempo_realizado= "00:05:00";

$percent= round((strtotime($tempo_realizado)/strtotime($tempo_total))*100);

Doesn’t work.

  • See if that answer helping.

  • Try to format the question title as a question (ending in "?" and all). Ex.: "How to calculate the hour percentage in PHP?"

  • 1

    In fact the title dispenses PHP because it already contains the correct tag.

  • Still doesn’t sound like a question. Try again and.e

2 answers

8


In that case, I think you should convert the times to seconds and then do the calculation.

$tempo_total= "00:10:00";
$empo_realizado= "00:05:00";

$tt = time_to_sec($tempo_total);
$tr = time_to_sec($tempo_realizado);

$percent = round(($tr / $tt) * 100);

echo $percent;

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;
}

For the tests I did here worked, and in this case returned 50 that as I understood, would be 50% of the time performed.

3

So far I’ve never experienced a case where using the right tool would be more complicated than using the wrong one.

Here comes the story...

For this type of calculation you should use the famous cross multiplication that we learned in elementary school:

A --- B
C --- D

In your case, these variables would represent:

  • To the Total Time
  • B the percentage of Total Time (always 100)
  • C the Time Accomplished
  • D the value of the equation you need to discover

In those hours the elephant of PHP would be roaring that since you are working with notions of time you should use the class Datetime, but very calm at this time because it is not so easy, see:

$total      = "00:10:00";
$running    = "00:05:00";

$dt1 = DateTime::createFromFormat( 'H:i:s', $total   ) -> getTimestamp();
$dt2 = DateTime::createFromFormat( 'H:i:s', $running ) -> getTimestamp();

Common sense leads us to create the Datetime objects from the time format H:i:s. And since we cannot wisely operate the hours, minutes and seconds, we get the timestamp of each of them to work only with the seconds.

But by applying these values to the mathematical formula:

$x = ( ( 100 * $dt2 ) / $dt1 );

We get as a result 97.368421052632

What? o. The

The implementation is correct, you can check the calculator, but something is messing up the results and the culprit is not the butler, but the Timezone.

The vast majority of local PHP installations have the directive date.Timezone commented or without a valid value which causes any script to trigger the following Warning

It is not safe to rely on the system’s Timezone Settings. You are required to use the date.Timezone Setting or the date_default_timezone_set() Function. In case you used any of those methods and you are still Getting this Warning, you Most likely misspelled the Timezone Identifier. We Selected the Timezone 'UTC' for now, but Please set date.Timezone to select your Timezone.

And, to silence this error, as directed, 99% of the time we start the script by calling the function date_default_timezone_set() to define a Timezone. And it’s precisely the use of that function that makes the cake go away.

When we created our Datetime objects and obtained the timestamps, the returned integers take into account the Timezone defined by the above function.

To solve this problem we have two alternatives:

  1. Subtract the seconds obtained from the seconds from ground zero Unix age, that is, 1 January 1970 at 00:00:00
  2. Explicitly define a Timezone whose offset be zero

The first option is slightly more expensive for the Application because it requires the creation of a third Datetime object:

$start      = "00:00:00";
$total      = "00:10:00";
$running    = "00:05:00";

$dt0 = DateTime::createFromFormat( 'H:i:s', $start   ) -> getTimestamp();
$dt1 = DateTime::createFromFormat( 'H:i:s', $total   ) -> getTimestamp();
$dt2 = DateTime::createFromFormat( 'H:i:s', $running ) -> getTimestamp();

So we have to subtract from each of the two we already had:

$x = ( ( 100 * ( $dt2 - $dt0 ) ) / ( $dt1 - $dt0 ) ); // 50

The second option is more efficient, but not by far obvious, for a change.

Datetime::createFromFormat(), as well as the class builder Datetime, accepts a third argument, an object Datetimezone so that we can perform the operations with a offset different from that generated by date_default_timezone_set()

It seems simple, doesn’t it? What is the difficulty of instantiating another object?

$total      = "00:10:00";
$running    = "00:05:00";

$dt1 = DateTime::createFromFormat( 'H:i:s', $total,   new DateTimeZone( 'UTC' ) ) -> getTimestamp();
$dt2 = DateTime::createFromFormat( 'H:i:s', $running, new DateTimeZone( 'UTC' ) ) -> getTimestamp();

$x = ( ( 100 * $dt2 ) / $dt1 );

But the result obtained... 99.999978800777.

What? o. The

I’m still looking for concrete and more detailed information but what I have for the moment is that for it to work as expected we should create the objects Datetime using the full rating (or at least date and time), of the Unix age, that is, for your total time, 1970-01-01 00:10:00:

$dt1 = DateTime::createFromFormat( 'Y-m-d H:i:s', $total,   new DateTimeZone( 'UTC' ) ) -> getTimestamp();
$dt2 = DateTime::createFromFormat( 'Y-m-d H:i:s', $running, new DateTimeZone( 'UTC' ) ) -> getTimestamp();

$x = ( ( 100 * $dt2 ) / $dt1 ); // 50

Browser other questions tagged

You are not signed in. Login or sign up in order to post.