Lostnode Posted February 21, 2013 Share Posted February 21, 2013 I am working on piece of software for the computer center I work at, in actuality improving on a 7 year old application that is well overdue for an update in functionality and features. The part I am getting stuck on is that we charge the public by the 15 minute increment, and everything is done via the ISO time stamp (YYYY-MM-DD HH:MM:SS) or date('Y-m-d H:i:s'). I have no issue getting the difference via strtotime() which gives me the difference in seconds. The problem is getting it to round to the same format so that it can be displayed in format ('H:i'), and I need to somehow calculate the total cost of the time, for instance we charge library members $0.50 per 15 minute interval. My predecessor used the following, which I think is a bit overkill (was finding it hard to understand how he coded the app) if ($minutes == 0){ $minutes = 0; $chunk_minutes = 0; }elseif($minutes > 0 AND $minutes <= 7){ if ($hours > 0){ $minutes = 0; $chunk_minutes = 0; }else{ $minutes = 15; $chunk_minutes = 1; } }elseif($minutes >= 8 AND $minutes <=22){ $minutes = 15; $chunk_minutes = 1; }elseif($minutes >= 23 AND $minutes <= 37){ $minutes = 30; $chunk_minutes = 2; }elseif($minutes >= 38 AND $minutes <= 52){ $minutes = 45; $chunk_minutes = 3; }elseif($minutes >= 53){ $minutes = 60; $chunk_minutes = 4; }else{ $minutes = "error rounding"; } I am looking for something a little less complex. Then the next issue is if its less than 15 minutes, rather 7 minutes or less, I need it to round up to 15 where usually it would round down to 0. If anyone can shed some light on this it would be appreciated. Regards Quote Link to comment Share on other sites More sharing options...
Jessica Posted February 21, 2013 Share Posted February 21, 2013 (edited) //Assuming $end and $start are timestamps. $seconds = $end-$start; $minutes = $seconds/60; while($minutes%15!=0){ $minutes++; } Edited February 21, 2013 by Jessica Quote Link to comment Share on other sites More sharing options...
Lostnode Posted February 21, 2013 Author Share Posted February 21, 2013 (edited) //Assuming $end and $start are timestamps. $seconds = $end-$start; $minutes = $seconds/60; while($minutes%15!=0){ $minutes++; } Why the while? The calculation is upon the patrol looking to leave, so the time no long increments, when they check in a time stamp is placed, as well as at the time they which t check out. FOr istance: Check in: 2013-02-21 10:15:21 Check Out: 2013-02-21 11:20:12 By eyeballing it I know its 65 minutes or 1:05 in h:i format I need to figure out how to round it to the 1:00, and then charge the $2.00 based on $0.50 per 1/4 hour. If I strtotime('out_time') - strtotime('in_time') I get the total seconds, getting it to the minutes part is not hard, but I want it to displat as H:i (1:00) and not 60minites. Edited February 21, 2013 by Lostnode Quote Link to comment Share on other sites More sharing options...
Jessica Posted February 21, 2013 Share Posted February 21, 2013 Did you even try my code before asking again how to do it? add a round() around the $seconds/60 and it will be rounded. The rest of it should be fine. Quote Link to comment Share on other sites More sharing options...
Lostnode Posted February 21, 2013 Author Share Posted February 21, 2013 I was mearly asking an explanation as to why you used "while", as usully loops not used in a single calculation. Or atleast I have not seen it used often unless I am running through lots of data. I will try it out when I get back to my PC later this afternoon. Quote Link to comment Share on other sites More sharing options...
Jessica Posted February 21, 2013 Share Posted February 21, 2013 Because you said if the minutes aren't 15 minute increments you wanted it rounded up to the next 15! Quote Link to comment Share on other sites More sharing options...
Jessica Posted February 21, 2013 Share Posted February 21, 2013 You could also do it like this: $seconds = $end-$start; $minutes_rounded = ceil($seconds/(60*15))*15; echo $minutes_rounded; If you never need the actual minutes just the rounded up version. Quote Link to comment Share on other sites More sharing options...
Lostnode Posted February 21, 2013 Author Share Posted February 21, 2013 Ok, now I see the logic. However, I only want to force a round up if the total time is less than 15 minutes, say the user was in the lab for 7 minutes, I don't want to charge them based on 0 minutes (as the nearest increment is 0), only then do I want it to round up, other wise I want it to round normally, i.e. 25 minutes would round to 30, but 22 minutes would round to 15. Also, once I have my seconds, how do I format it to be in H:i format as date() doesn't do it (900 seconds, places in date('H:i', 900) = 19:15 instead of just 0:15......) Quote Link to comment Share on other sites More sharing options...
Jessica Posted February 21, 2013 Share Posted February 21, 2013 You can't use date() for that, you have to use some simple logic. Instead of using ceil() use round, and if it's 0 then set it to 15. Quote Link to comment Share on other sites More sharing options...
Barand Posted February 21, 2013 Share Posted February 21, 2013 try $a = new datetime('2013-02-21 17:00:00'); // start time $now = new datetime(); $elapsed = $a->diff($now)->format('%h:%i'); list ($h, $m) = explode(':', $elapsed); if ($h==0 && $m < 15) $m = 15; $m = round($m/15) * 15; if ($m==60) { $h++; $m = 0; } echo "Rounded time is $h hrs $m mins"; Quote Link to comment Share on other sites More sharing options...
Lostnode Posted February 21, 2013 Author Share Posted February 21, 2013 Ok, I got it working, thank you, now I just have to figure out the display, just gotta get m head wrapped around the logic. Here is what I used: $seconds = $out_time - $in_time; if ($seconds < '900') { $minutes_rounded = ceil($seconds/(60*15))*15; } else { $minutes_rounded = round($seconds/(60*15))*15; } $time_subtotal = ($minutes_rounded / 15) * $time_price; Anything under 15 rounds up, (except for 0, we need that to stay 0) everyting else rounds normally., a lot shorter of a code than what my predecessor used. Quote Link to comment Share on other sites More sharing options...
Lostnode Posted February 21, 2013 Author Share Posted February 21, 2013 try $a = new datetime('2013-02-21 17:00:00'); // start time $now = new datetime(); $elapsed = $a->diff($now)->format('%h:%i'); list ($h, $m) = explode(':', $elapsed); if ($h==0 && $m < 15) $m = 15; $m = round($m/15) * 15; if ($m==60) { $h++; $m = 0; } echo "Rounded time is $h hrs $m mins"; I got hit with an error when trying to use the diff(): [pre] Call to a member function diff() on a non-object [/pre] I am using CodeIgniter as my framework, so something don't quite work as expected. I am happy to say however that CodeIgniter has a very simple function for it.. $in_time = strtotime($this->input->post('in_time')); $out_time = strtotime($this->input->post('out_time')); [color=#002166][font=Monaco, Verdana, sans-serif][size=3][background=rgb(249, 249, 249)]echo timespan($start, $end);[/background][/size][/font][/color] Quote Link to comment Share on other sites More sharing options...
Barand Posted February 21, 2013 Share Posted February 21, 2013 I got hit with an error when trying to use the diff(): Call to a member function diff() on a non-object Requires PHP v5.3 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.