PHP : How to calculate the remaining time in minutes? - php

Suppose the target time is 4.30 pm and the current time is 3.25 pm , how will i calculate the minutes remaining to reach the target time ? I need the result in minutes.
session_start();
$m=30;
//unset($_SESSION['starttime']);
if(!$_SESSION['starttime']){
$_SESSION['starttime']=date('Y-m-d h:i:s');
}
$stime=strtotime($_SESSION['starttime']);
$ttime=strtotime((date('Y-m-d h:i:s',strtotime("+$m minutes"))));-->Here I want to calcuate the target time; the time is session + 30 minutes. How will i do that
echo round(abs($ttime-$stime)/60);
Krishnik

A quick calculation of the difference between two times can be done like this:
$start = strtotime("4:30");
$stop = strtotime("6:30");
$diff = ($stop - $start); //Diff in seconds
echo $diff/3600; //Return 2 hours. Divide by something else to get in mins etc.
Edit*
Might as well add the answer to your problem too:
$start = strtotime("3:25");
$stop = strtotime("4:30");
$diff = ($stop - $start);
echo $diff/60; //Echoes 65 min
Oh and one more edit:) If the times are diffent dates, like start is 23:45 one day and end is 0:30 the next you need to add a date too to the strtotime.

Related

Substract Time Logic - PHP

I want to show time slots between 2 times. Start time & End time. Used below code, it's working fine. It loops start and end time and add 30 mins to time. Starts from 2:00pm, 2:30pm, 3:00pm all the way till 10:00pm
$start_time = "14:00:00";
$end_time = "22:30:00";
#for ($i = strtotime($start_time); $i < strtotime($end_time); $i=$i+1800)
<li data-time="{{date('g:i A', $i)}}" class="timefield">{{date("g:i A", $i)}}</li>
#endfor
What I am stuck on is 2 parts
Hide past time, lets say right now is 4:00pm, it should hide past time slots i-e 2:00pm,2:30pm,:3:00pm,3:30pm
If right now is 4:00pm, it should start from 5:00pm all the way till 10:00pm. Adding extra buffer time of 1 hour.
You could insert the current timestamp in your logic like this:
$start_time = strtotime("14:00:00");
$end_time = strtotime("22:30:00");
$now = (new DateTime())->getTimestamp();
$nowRemaining = $now % 1800; // Divide to half hours & get the remaining seconds
$nowRounded = $now - $nowRemaining; // Round to half hours
$nextHour = $nowRounded + ($nowRemaining == 0 ? 3600 : 5400); // Add the extra buffer
for ($i = max($start_time, $nextHour); $i < $end_time; $i=$i+1800) {
...
}

Splitting a time range into hours?

I'm currently working with a data set containing a start time, date, and a duration in seconds, and need to be able to split the range of times from start time to (start time + duration, e.g. end time) into hour "buckets" if you will.
So for instance, a start time of 08:30:00 with duration 9000 seconds (2.5 hours) covers hour 08 from 8:30:00 to 09:00:00 for 1800 seconds, hour 09 until 10:00:00 for 3600 seconds, etc. up to the end time of 11:00:00.
What would be the best way possible to do this? I'm working in PHP however a general algorithmic solution would still be incredibly helpful.
My current approach is as follows:
1. Calculate the hour difference between both times (round up to next hour if there's a non-zero number of minutes)
2. Let session progress = 0
3. Iterate the range from 1 to hour difference:
1. Let the current bucket duration = min(3600, duration)
2. Let the duration = max(0, duration - current bucket duration)
3. Let bucket start time = start time + session progress
4. Let bucket end time = bucket start time + current bucket duration
5. Do work based on these values
6. Let session progress += current bucket duration
My PHP implementation of this is as follows:
foreach ($csv as $listen_record) {
$start_dt = $listen_record['Date'] . ' ' . $listen_record['Time'];
$session_duration = $listen_record['Duration'];
$session_start_time = date_create_from_format($datetime_format, $start_dt);
$session_end_time = clone $session_start_time;
date_add($session_end_time, date_interval_create_from_date_string($session_duration . ' seconds'));
$diff = date_diff($session_end_time, $session_start_time);
$hourdiff = $diff->h;
if ($diff->m > 0)
$hourdiff += 1;
$session_progress = 0;
foreach (range(1, $hourdiff) as $hour) {
$record_duration = min(3600, $session_duration);
$session_duration = max(0, $session_duration - $record_duration);
$record_start_time = clone $session_start_time;
date_add($record_start_time, date_interval_create_from_date_string($session_progress . ' seconds'));
$record_end_time = clone $record_start_time;
date_add($record_end_time, date_interval_create_from_date_string($record_duration . ' seconds'));
if ($record_start_time == $record_end_time)
continue;
// DO WORK...
$session_progress += $record_duration;
}
}
This kind of works to separate each record into hour long buckets however gives some weird results for some cases (particularly cases where the range crosses into a new day) and doesn't align to actual wall clock hours.
Is there a better way to do this that can actually align to wall clock hours and not freak out when it has to cope with durations that cross over midnight?
Thanks!
Update: I managed to solve this on my own so I'm posting how I did it just in case anyone else needs to do similar.
Basically I did it by creating a range between the start and end timestamp, and filtering out every time stamp apart from start and end that isnt a multiple of 3600 or just before 3600. This gives me the wall clock hours in the middle of the range as timestamps. I can then split the array into chunks of 2 which contains the slot start time and end time.
My PHP code is as follows and now actually works:
function is_wall_clock_aligned_hour_boundary($timestamp) {
return ($timestamp % (60*60) === 0) || (($timestamp + 1) % (60*60) === 0);
}
function create_slot_object($slot) {
$start_time = reset($slot);
$end_time = end($slot);
$duration = $end_time - $start_time;
return array(
'startTime' => convert_timestamp_to_datetime($start_time),
'endTime' => convert_timestamp_to_datetime($end_time),
'duration' => $duration
);
}
function make_slots(DateTime $start_time, $duration) {
$start_timestamp = $start_time->getTimestamp();
$end_time = clone $start_time;
date_add($end_time, date_interval_create_from_date_string("$duration seconds"));
$end_timestamp = $end_time->getTimestamp();
$time_sequence = range($start_timestamp, $end_timestamp);
$slot_boundaries = array_filter($time_sequence, 'is_wall_clock_aligned_hour_boundary');
array_unshift($slot_boundaries, $start_timestamp);
array_push($slot_boundaries, $end_timestamp);
$slots = array_chunk($slot_boundaries, 2);
return array_map('create_slot_object', $slots);
}

PHP: Wrong Time Calculation

I am working on a project and writing a function to add two different times. The times are stored in database as a string.
I'm:
Pulling value from db
converting it into time using strtotime
adding times using date function
Here is my code:
$time_1 = '1:00';
$time_2 = '0:05';
//should be 1:05, whereas it prints 04:05
echo date("H:i", strtotime($time_1) + strtotime($time_2));
Please tell me, what is wrong with above code and how it can be fixed?
Thanks
Your problem is because strtotime returns the number of seconds since the Unix Epoch (Jan 1 1970). So what you are getting is not values of 60 and 5, but something more like 1537570800 and 1537567500. When you add those two values together, you end up with a date far in the future, with what looks effectively like a random time. To compensate for this, you need to subtract the value of strtotime at the start of the day to make the second time a relative time e.g.:
echo date("H:i", strtotime($time_1) + strtotime($time_2) - strtotime('00:00'));
Output:
01:05
Update
Since it turns out that the sum of the two times can exceed 24 hours, the above code will not work (the maximum time it will display is 23:59 before rolling over to 00:00. So it is necessary to convert both times to a relative number of minutes to the start of the day, add them and then display as hours and minutes:
$time_1 = '12:00';
$time_2 = '14:30';
$time_sum = (strtotime($time_1) + strtotime($time_2) - 2 * strtotime('00:00')) / 60;
printf('%02d:%02d', intdiv($time_sum, 60), $time_sum % 60);
Output:
26:30
Use DateTime::createFromFormat function, and taking ideas from Adding two DateTime objects in php
$time_1 = '1:00';
$time_2 = '0:05';
$t1 = DateTime::createFromFormat('G:i', $time_1);
$t2 = DateTime::createFromFormat('G:i', $time_2);
$interval1 = $t1->diff(new DateTime('00:00:00')) ;
$interval2 = $t2->diff(new DateTime('00:00:00')) ;
$e = new DateTime('00:00');
$f = clone $e;
$e->add($interval1);
$e->add($interval2);
$total = $f->diff($e)->format("%H:%I:%S");
Additional Details:
G and H 24-hour format of an hour with or without leading zeros
i Minutes with leading zeros 00 to 59

Calculate nearest hours to 00:00 in PHP

How can I calculate the nearest hours to midnight time 00:00 regardless of date in PHP. For example:
If time is 22:00 then 2 hours are required to reach 00:00
If time is 04:00 then -4 hours are the nearest to reach 00:00
Currently I have the following PHP function:
<?php
$ts1 = strtotime('00:00');
$ts2 = strtotime('04:00');
$diff = ($ts1 - $ts2) / 3600;
?>
But this won't be helpful much in the above.
If you have the php Datetime class available you can calculate the difference between two DateTimes.
$time1 = new \DateTime('00:00');
$time2 = new \DateTime('04:00');
$diff = $time1->diff($time2, true);
$hourDifference = 0;
if ($diff->h < 12) {
$hourDifference = -$diff->h;
} elseif ($diff->h > 12) {
$hourDifference = 24 - $diff->h;
} else {
$hourDifference = 12; // kann be positive or negative
}
And you'll get a DateInverall object where you can access, hours, minuts, seconds and compare them with normal php operators.
If you'r not too interested in minutes;
1. Extract minutes.
check if minutes is > or <=30
if greater, 'store' 1
2. Extract hour
check if hour is greater than 12
if not, add 12 (store flag also to say it will be minus)
3. if greater (ref. Step 1), add 1 to extracted hour.
4. 24 - extracted hour is your interval.
Please note, this may be reduced/ simplified greatly.
Your interval (should) be correct to the nearest half hour
The answer depends on the date (not only the time). This is because of daylight saving time changes. For example might 02:59 being closer to 00:00 then 21:01 on the time where daylight saving time will set back hour.

finding out difference between two times

I wrote the following code to determine the amount of time that employees spend on a task:
$time1 = $row_TicketRS['OpenTime'];
$time2= $row_TicketRS['CloseTime'];
$t1=strtotime($time1);
$t2=strtotime($time2);
$end=strtotime(143000); //143000 is reference to 14:30
//$Hours =floor((($t2 - $t1)/60)/60);
$Hours = floor((($end- $t1)/60)/60);
echo $Hours.' Hours ';
The above code is not giving me the correct time.
For example, with a start time of 09:19:00 and end time of 11:01:00 it give me duration time of only 1 hour which is wrong. What is the correct way?
Your use of floor is why you are getting only 1 hour for those inputs. Those inputs result in 1.7 hours if you keep the answer as a float. floor automatically rounds down to the lower integer value. Check out http://php.net/manual/en/function.floor.php for more info.
$t1 = strtotime('09:19:00');
$t2 = strtotime('11:01:00');
$hours = ($t2 - $t1)/3600; //$hours = 1.7
If you want a more fine-grained time difference, you can flesh it out...
echo floor($hours) . ':' . ( ($hours-floor($hours)) * 60 ); // Outputs "1:42"
UPDATE:
I just noted your comments on Long Ears' answer. Please check my comments above again, they are correct. Inputting values of '09:11:00' and '09:33:00' results in 0 hours (22 minutes).
If you input those values and got 4 hours, you likely have a decimal error in your math. Using '09:11' to '09:33', the result is .367 hours. If you divided the strtotime results by 360 instead of by 3600, you would get result 3.67 hours (or 4 hours, depending on your rounding method).
strtotime converts your time to an int value representing number of seconds since Unix epoch. Since you convert both values to seconds, and then subtract the values from each other, the resulting value is a quantity of seconds. There are 3600 seconds in 1 hour.
After changing strtotime('14:30:00') everything working fine.. see below
$time1 = '09:19:00';
$time2= '11:01:00';
echo "Time1:".$t1=strtotime($time1);
echo "<br/>Time2:".$t2=strtotime($time2);
echo "<br/>End:".$end=strtotime('14:30:00');
echo "<br/>Floor value:";
var_dump(floor((($end- $t1)/60)/60));
//$Hours =floor((($t2 - $t1)/60)/60);
$Hours = floor((($end- $t1)/60)/60);
echo $Hours.' Hours ';
function getTimeDiff($dtime,$atime)
{
$nextDay=$dtime>$atime?1:0;
$dep=explode(':',$dtime);
$arr=explode(':',$atime);
$diff=abs(mktime($dep[0],$dep[1],0,date('n'),date('j'),date('y'))-mktime($arr[0],$arr[1],0,date('n'),date('j')+$nextDay,date('y')));
//Hour
$hours=floor($diff/(60*60));
//Minute
$mins=floor(($diff-($hours*60*60))/(60));
//Second
$secs=floor(($diff-(($hours*60*60)+($mins*60))));
if(strlen($hours)<2)
{
$hours="0".$hours;
}
if(strlen($mins)<2)
{
$mins="0".$mins;
}
if(strlen($secs)<2)
{
$secs="0".$secs;
}
return $hours.':'.$mins.':'.$secs;
}
echo getTimeDiff("23:30","01:30");
A better way is to use http://php.net/manual/en/datetime.diff.php
$start_t = new DateTime($start_time);
$current_t = new DateTime($current_time);
$difference = $start_t ->diff($current_t );
$return_time = $difference ->format('%H:%I:%S');
for example the start time is 09:19:00 and end time is 11:01:00 but it give me duration time only 1 hour which is wrong
You are calculating the difference in hours. what is the correct result for "start time is 09:19:00 and end time is 11:01:00"
You need strtotime('14:30') rather than strtotime(143000)
Edit: Actually to my surprise, strtotime(143000) does seem to have the desired effect but only for double-digit hours so I still wouldn't rely on it. Anyway it's not the cause of your problem ;)
You can use $hour = ($end - $t1)/(60*60)
In this the time format is (seconds*minutes*days*months*years) => (60*60*2)

Categories