Fractions of 15 minutes in the time record in PHP

I have an hourly billing system which I am trying to charge for fractions of 15 min. It takes the difference of the time of entry and exit and adds the remaining time, Example:

  • Input 09:00-Output 09: 11
  • real Time: 00: 11-charge time: 00:15.

And so on from 15 to 15.

I put together a code that works up to 60 minutes, however, my doubt lies in after this time passes. They it does not add the fractions, but the normal minutes.

Is there any way he recognizes that after 01: 00: 01 one should add the fraction of 15 successively? Below follows the Code:

<?php 
$horaInicial = $_POST['inicio'];
$horaFinal = $_POST['final'];
$fator15 = 900;
$fator30 = 1800;
$fator45 = 2700;
$fator60 = 3600;
$horaMais = 3600;


$horaInicial = strtotime($horaInicial);
$horaFinal = strtotime($horaFinal);

$totalSegundos = ($horaFinal - $horaInicial);



switch($totalSegundos){
    case ($totalSegundos < $fator15):
        while($totalSegundos < $fator15){
            $totalSegundos++;
        }
        break;

    case ($totalSegundos > $fator15 && $totalSegundos < $fator30):
        while($totalSegundos < $fator30){
            $totalSegundos++;
        }
        break;

    case ($totalSegundos > $fator30 && $totalSegundos < $fator45):
        while($totalSegundos < $fator45){
            $totalSegundos++;
        }
        break;

    case ($totalSegundos > $fator45 && $totalSegundos < $fator60):
        while($totalSegundos < $fator60){
            $totalSegundos++;
        }
        break;
    case($totalSegundos > $fator60):
        while($totalSegundos < $fator15){
            $totalSegundos++;
        }

}



$resultado = gmdate("H:i", $totalSegundos);

echo "Total: ".$resultado;

?>
Author: hkotsubo, 2019-04-02

1 answers

Since you are working with the difference in minutes, you can ignore the seconds, so the first thing is to divide the difference by 60:

$totalMinutos = ($horaFinal - $horaInicial) / 60;

Then just see how many 15-minute intervals there are in this total (and using ceil to round up):

$intervalosDe15 = ceil($totalMinutos / 15);

With this you get the amount of 15-minute intervals. For example, if the start time is 09: 00 and the end time is 10:11, the result is 5.

To get the total of minutes equivalent, just multiply by 15:

$intervaloMinutos = $intervalosDe15 * 15;

And now we get to the point where you print the result. You are using gmdate, which prints a date in a certain format. But the information you have (the interval in minutes) is not a date. There are two different concepts here:

  • a date / time represents a specific point in the timeline: a date is a point in the calendar (ex: Day 2 of April 2019) and a time represents a specific point of the day (ex: half past two in the afternoon)
  • a duration represents an amount of time, with no direct relationship to calendars. Ex: the duration of the film is two hours (I did not say what time it starts, nor if in fact it will start, it is only the amount of time , with no relation to dates or Times)

Both can use the same words (days, hours, minutes, etc.), but they are concepts different.

gmdate it works with dates, but what you have ($intervaloMinutos) is a duration. And to work with durations, you must use a DateInterval:

$intervaloMinutos = $intervalosDe15 * 15;
$horas = floor($intervaloMinutos / 60);
$minutos = $intervaloMinutos % 60;
$interval = new DateInterval("PT{$horas}H{$minutos}M");
echo $interval->format('%H:%I'); // hh:mm

First I turn the 15-minute intervals into total minutes. Then I take the amount of hours and minutes and create the DateInterval.

The constructor of DateInterval needs to receive the values in the format ISO 8601. In the case, PTxHyM represents a duration of x hours and Y minutes. Then I use the method format to format DateInterval.

Using the start time 09: 00 and the end time 10: 11, $intervalosDe15 will be equal to 5, then $intervaloMinutos will be 75 (that is, the total duration is 75 minutes).

Then $horas will be 1 and minutos will be 15, and when formatting DateInterval, the result will be 01:15.

 2
Author: hkotsubo, 2019-04-02 13:42:25