[SOLVED] Calc Element : Time start 08:00 + 3 hours = 11:00 + Solution

marcq

Member
Hi,

I have created a form in which I'm calculating an arrival time based on a Start Time and a Duration Field.

I have created the two following fields

1. Start Time -> dropdown -> values 08:00 | 08:30 | 09:00 etc.
2. Arrival time -> calc -> calculation 1 + 2

Calculation Field in Calc Element :
PHP:
$start = {nep_booking___book_starttime};
$duration = 3; // 3 hours

$end = strtotime($start) + $duration * 60;
return date ('H:i', $end );

I'm missing something since no value is calculated.

I would appreciate some help.

Thanks in advance.

Cheers,

Marc
 
First thing, you need quotes around the placeholder, otherwise the generated PHP after we substitute is not syntacically correct, like ...

Code:
$start = 8:30;

So it needs to be ...

Code:
$start = '{nep_booking___book_starttime}';

... so the generated code we eval is then ...

Code:
$start = '8:30';

Then the issue is correctly calculating the time. You can use strtotime and doing math, but the best way (and a good habit to get in to) is to use PHP's DateTime class for any ind of date calculations ...

Code:
$start = '{nep_booking___book_starttime}';
if (!empty($start)) {
   $end = new DateTime($start);
   return $end->modify("+3 hours")->format("H:s");
}
else {
   return "";
}

... should do it. Note that this will correctly handle crossing midnight, so 23:30 + 3 would be 02:30.

the DateTime class has all kinds of useful functions for calculating differences, modifying, formatting etc.

-- hugh
 
Hi Hugh,

Thanks a lot, it is working like a charm and thank you also for your didactical way of explaining !

I would like now to use a dropdown instead a predefined static value ? I tried this which is not working :

Code:
$start = '{nep_booking___book_starttime}'; // start time of rental
$duration = '{nep_booking___book_termrental}'; // chosen duration
if (!empty($start)) {
   $end = new DateTime($start);
   return $end->modify(+$duration)->format("H:i");
}
else {
   return "";
}

Content of my databasejoin dropdown duration table :

id | duree
1 | 3 heures
2 | 5 heures
3 | 7 heures
 
Last edited:
If you want to have the id use {nep_booking___book_termrental_raw}.

For debugging you can add e.g.
var_dump($start,$duration);
to see what you get.
 
This is one of the few times where a simple dropdown might be more appropriate than a join. Simply set the value of the dropdown options to be the number of hours, and use the _raw placeholder, as suggested by Troester.

Using a join, you either have to then lookup the actual hour number from the table, or parse it out of the label with a regular expression ...

Code:
$matches = array();
if (preg_match('/^(\d+)\s+/', '{nep_booking___book_termrental}', $matches)) {
   $duration = $matches[1];
   // rest of the code ...
}

Whereas with a dropdown where the value is set to the duration, it's just ...

Code:
$duration = '{nep_booking___book_termrental_raw}';

-- hugh[/code]
 
Thank you troester and Hugh,

Sorry to bother you with this certainly trivial issue, I tried it with a join, but I get no result :

Code:
$start = '{fab_booking___book_starttime}';
$matches = array();
if (preg_match('/^(\d+)\s+/', '{fab_booking___book_termrental}', $matches)) {
   $duration = $matches[1];
if (!empty($start)) {
   $end = new DateTime($start);
   return $end->modify(+$duration)->format("H:i");
}
else {
   return "";
}
}
 
Last edited:
Hi Hugh,

Values returned for $duration with var_dump in the calc field are : "7" if i chose "7 heures", "5" if I chose "5 heures" etc. in the fab_booking___book_termrental dropdown.

Values returned for $matches with var_dump are : "array(2) { [0]=> string(2) "3 " [1]=> string(1) "3" }" if I chose "3 heures", "array(2) { [0]=> string(2) "5 " [1]=> string(1) "5" }" if I chose "5 heures" etc.
 
Last edited:
I think the modifier still has to be a string ...

Code:
return $end->modify("+" . $duration . " hours")->format("H:i");

-- hugh
 
Thank you Hugh, I understand now how it works !

Solution from Hugh is :

Code:
$start = '{fab_booking___book_starttime}';
$matches = array();
if  (preg_match('/^(\d+)\s+/', '{fab_booking___book_termrental}', $matches)) {
    $duration = $matches[1];
   
if  (!empty($start)) {
    $end = new DateTime($start);
    return $end->modify("+" . $duration . " hours")->format("H:i");
}
else {
   return "";
}
}
 
Back
Top