Moorcam Posted August 10, 2017 Share Posted August 10, 2017 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? Quote Link to comment Share on other sites More sharing options...
requinix Posted August 10, 2017 Share Posted August 10, 2017 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. Quote Link to comment Share on other sites More sharing options...
Moorcam Posted August 10, 2017 Author Share Posted August 10, 2017 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. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted August 10, 2017 Share Posted August 10, 2017 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. Quote Link to comment Share on other sites More sharing options...
Moorcam Posted August 10, 2017 Author Share Posted August 10, 2017 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. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted August 10, 2017 Share Posted August 10, 2017 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. Quote Link to comment Share on other sites More sharing options...
Moorcam Posted August 10, 2017 Author Share Posted August 10, 2017 I give up. PHP, you have defeated me. 48 hours I spent trying to figure this crap out and even experienced advice is not making a diff (pardon the pun). Over and Out. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted August 10, 2017 Share Posted August 10, 2017 (edited) 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 August 10, 2017 by Jacques1 Quote Link to comment Share on other sites More sharing options...
Moorcam Posted August 10, 2017 Author Share Posted August 10, 2017 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. Quote Link to comment Share on other sites More sharing options...
Moorcam Posted August 10, 2017 Author Share Posted August 10, 2017 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 Quote Link to comment Share on other sites More sharing options...
requinix Posted August 10, 2017 Share Posted August 10, 2017 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) Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted August 10, 2017 Share Posted August 10, 2017 Maybe a bit less Guinness can speed up the learning process. 2 Quote Link to comment Share on other sites More sharing options...
Moorcam Posted August 10, 2017 Author Share Posted August 10, 2017 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. Quote Link to comment Share on other sites More sharing options...
Solution requinix Posted August 10, 2017 Solution Share Posted August 10, 2017 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. 1 Quote Link to comment Share on other sites More sharing options...
Moorcam Posted August 10, 2017 Author Share Posted August 10, 2017 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. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted August 10, 2017 Share Posted August 10, 2017 // 05:30 hours new DateInterval('P0000-00-00T05:30:00'); 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.