Jump to content

Subtracting Time from Total Hours


Go to solution Solved by requinix,

Recommended Posts

I am trying to subtract a submitted time from the total time.

For example, user puts in a start time of 09:00 and end time of 17:00

This gives me a total hours of 08:00, which is correct.

What I want to do is allow the user to put, for example, 02:30 into a third input and click calculate, which should give a total time of 05:30.

 

Here is the code I have for calculating the difference between both times:

<?php
if(isset($_POST['start_shift1']) && $_POST['end_shift1'] && $_POST['break1'] != "") 
{
$datetime1 = new DateTime($_POST['start_shift1']);
$datetime2 = new DateTime($_POST['end_shift1']);
$break = new DateTime($_POST['break1']);
$mondiff = $datetime1->diff($datetime2);

?>
<input type="text" readonly class="form-control" name="monday" value="<?php echo $mondiff->format('%H:%I'); ?>">
<?php
}
    ?>

Does anyone know how I can subtract $break from $mondiff?

Link to comment
https://forums.phpfreaks.com/topic/304578-subtracting-time-from-total-hours/
Share on other sites

Try using DateInterval for the break instead of DateTime.

$break = DateInterval::createFromDateString($_POST['break1']);
Then check the documentation for DateTime to see if there's a way to add (or subtract) a DateInterval.

Tried a couple of methods I found on Google but getting the same result:

Fatal error: Call to undefined method DateInterval::sub() 

What I have done is:

$datetime1 = new DateTime($_POST['start_shift1']);
$datetime2 = new DateTime($_POST['end_shift1']);
$break = DateInterval::createFromDateString($_POST['break1']);
$mondiff = $datetime1->diff($datetime2);
$total = $mondiff->sub($break1);

$total being the offending line.

The DateInterval class doesn't have a sub() method.

 

You need to either add the interval to $datetime1 or substract it from $datetime2. Then you can calculate the difference between the new limits.

Okay, this is what I have now, hoping it's within the scope that you described:

<?php
if(isset($_POST['start_shift2']) && $_POST['end_shift2'] && $_POST['break2'] != "") 
{
$datetime1 = new DateTime($_POST['start_shift2']);
$datetime2 = new DateTime($_POST['end_shift2']);
$break = DateInterval::createFromDateString($_POST['break1']);
$total = $break + $datetime1;
$mondiff = $total->diff($datetime2);

?>
<input type="text" readonly class="form-control" name="monday" value="<?php echo $mondiff->format('%H:%I'); ?>">
<?php
}
    ?>

Not getting any errors, but getting no results either.

You keep inventing methods and operators that just don't exist. And your error reporting is obviously misconfigured.

 

The DateTime class doesn't have a "+" operator. It would be nice if it had, but there is no such feature. Read the manual. This tells you exactly what the class does and doesn't have. Hint: DateTime::add() looks promising.

It's not the fault of PHP when you rather run in circles for hours than spend 5 minutes to RTFM.

 

The DateTime class has less than 20 methods and is fully documented. How hard can it be to go through those methods and pick one that makes sense? I even told you the method you need to use (and guess how I found it: I read the manual).

 

You're creating the problems yourself. The solution is right in front of you, but for some strange reason, you cannot see it until I put it into an extra-large font (which then pisses you off).

Edited by Jacques1

It's not the fault of PHP when you rather run in circles for hours than spend 5 minutes to RTFM.

 

The DateTime class has less than 20 methods and is fully documented. How hard can it be to go through those methods and pick one that makes sense? I even told you the method you need to use (and guess how I found it: I read the manual).

 

You're creating the problems yourself. The solution is right in front of you, but for some strange reason, you cannot see it until I put it into an extra-large font (which then pisses you off).

I tried what you suggested mate, and what others suggested and what PHP themselves even suggest. Nothing works for me. Only one getting pissed off here is you. ;)

The DateInterval class doesn't have a sub() method.

 

 

Example #1 DateTime::sub() example

Object oriented style

<?php
$date = new DateTime('2000-01-20');
$date->sub(new DateInterval('P10D'));
echo $date->format('Y-m-d') . "\n";
?>
 

Procedural style

<?php
$date = date_create('2000-01-20');
date_sub($date, date_interval_create_from_date_string('10 days'));
echo date_format($date, 'Y-m-d');
?>
From RTFM

DateInterval does not have a sub() method - as Jacques said. What you've managed to locate is the sub() method in the DateTime class. You can tell because

$date->sub(
and

$date = new DateTime(
I still have hope that you can figure out how to do this so here's one step away from posting actual code:

1. Get your start and end values (as DateTime objects)

2. Get the break duration (as a DateInterval object)

3. Add that interval to the start to get a second start time (as another DateTime object)

4. Diff the second start time with the original end time to get the remaining shift time (as a DateInterval object)

DateInterval does not have a sub() method - as Jacques said. What you've managed to locate is the sub() method in the DateTime class. You can tell because

$date->sub(
and

$date = new DateTime(
I still have hope that you can figure out how to do this so here's one step away from posting actual code:

1. Get your start and end values (as DateTime objects)

2. Get the break duration (as a DateInterval object)

3. Add that interval to the start to get a second start time (as another DateTime object)

4. Diff the second start time with the original end time to get the remaining shift time (as a DateInterval object)

 

Thanks mate. Have tried this. Obviously not correctly. The ADD part has me f**ked.

 

 

Maybe a bit less Guinness can speed up the learning process.

I think because I haven't had decent Guinness since leaving Ireland is what has my brain fried.

I appreciate the efforts in helping though, really do.

  • Solution

Apparently createFromDateString doesn't allow HH:MM format, even though it looks relative. It's because the relative format is shared with the other date/time parsing code and HH:MM is more of an absolute value than a relative one.

 

So break the HH:MM into HH and MM parts and create the DateInterval manually. You do need to validate the break1 value first (make sure it is, in fact, HH:MM format) but the rest of the process we described works correctly.

  • Like 1

Apparently createFromDateString doesn't allow HH:MM format, even though it looks relative. It's because the relative format is shared with the other date/time parsing code and HH:MM is more of an absolute value than a relative one.

 

So break the HH:MM into HH and MM parts and create the DateInterval manually. You do need to validate the break1 value first (make sure it is, in fact, HH:MM format) but the rest of the process we described works correctly.

You are a star. Now I get the add thingy and it works. :)

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.