In my form there are 2 Time Pickers where user can select a from time and to time. It doesn't have a date associated with it. And for a report generating purpose I've to calculate the time difference between them. It works perfectly to if the From and to Time is "06:00 to 10:00" but if the from and to time is "21:00 to 02:00" I get a time difference of 19 hours. Could you please help me to fix this.
For this case "21:00 to 02:00" the time difference should be 5 hours.
This is the Code
$datetime1 = new \DateTime('09:30 PM');
$datetime2 = new \DateTime('02:00 AM');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%hh');
exit;
The difference becomes negative If $totime is less than $fromtime.
DateInterval->invert == 1 indicates that. This is used with this short solution to correct the result.
$fromtime = '09:30 PM';
$totime = '02:00 AM';
$diff = date_create($fromtime)->diff(date_create($totime));
$hours = $diff->invert ? 24-$diff->h : $diff->h;
echo $hours; //5
Since you have 2 date pickers one for from time and another to time, the former will always be smaller than the latter. Hence when from time is larger than to time it means user has selected to from the next day. If we don't add a date for calculating difference, PHP will assume today's date by default. We can easily fix this by adding a condition to compare the times and prepend the dates accordingly. Below is the updated code.
<?php
$fromtime = '09:30 PM';
$totime = '02:00 AM';
$now = new \DateTime();
$today = $now->format('Y-m-d'); // Store current date
$now->add(new DateInterval('P1D')); // Add one day to current date to get next date
$nextDay = $now->format('Y-m-d'); // Store next date
if($fromtime > $totime) // If from time is bigger than to time, it means to is a next day
{
$fromdatetime = "$today $fromtime";
$todatetime = "$nextDay $totime";
}
else
{
$fromdatetime = "$today $fromtime";
$todatetime = "$today $totime";
}
$datetime1 = new \DateTime($fromdatetime);
$datetime2 = new \DateTime($todatetime);
$interval = $datetime1->diff($datetime2);
echo $interval->format('%hh');
?>
here is scenario that i have two time as given i have only time part of datetime in 24 hour format
$start_time = "23:00:00";
$end_time = "07:00:00";
How i can calculate duration hours , if the start_time's hour part is greater then $end_time's hour.
I would just create an if, where if the start time is bigger you have to calculate 24h (base_time) minus the start time first.
$start_time = "23:00:00";
$end_time = "07:00:00";
$base_time = "24:00:00";
if ($start_time>$end_time) {
$time = $base_time-$start_time+$end_time;
} else {
$time = $start_time-$end_time;
}
Or you can also have a look here, if you also have the day format given.
The way over DateTime, as far as I know, is just possible with a date. So you could add a pseudo date infront... and then use diff :
$start_time = "23:00:00";
$end_time = "07:00:00";
$st = new DateTime("0000-00-00".$start_time);
$et = new DateTime("0000-00-01".$end_time);
$interval = $st->diff($et);
$time = $interval->format('%H:%I:%S');
I am trying to take the differences of datetimes in php as follows:
$datetime1 = new DateTime();
$datetime2 = new DateTime('2015-09-23 08:09:50');
$interval = $datetime1->diff($datetime2);
$elapsed = $interval->format('%S');
echo $elapsed;
Here I am getting the difference in seconds.
I need the total time difference in seconds.
$difference = abs($datetime1->getTimestamp() - $datetime2->getTimestamp());
I want to calculate the time difference from now (lets say 18:30:00) till this evening at 20pm.
$today = date('Y-m-d', time());
$remain = strtotime($today. " 00:00:00 + 20 hours") - time();
$remain = date('H:i:s', $remain);
I get a result which is one hour larger (02:30:00) than the actual result (01:30:00). I tried setting time zones but it's always the same result.
Using the DateTime object, you can do this easily:
$d1 = new DateTime('2015-04-23 18:30');
$d2 = new DateTime('2015-04-23 20:00');
$interval = $d2->diff($d1);
echo $interval->format('%H:%i hours');
$time_start = mktime(12,0,0,1,1,2011);
$time_end = mktime(12,0,0,7,1,2011);
$format = '%m months';
$start_date = new DateTime(date(DATE_ATOM,$time_start));
$end_date = new DateTime(date(DATE_ATOM,$time_end));
$diff = $start_date->diff($end_date, true);
echo $diff->format($format);
Outputs "5 months", I guess because it's off by an hour due to DST. However, I need to calculate the difference in calendar months; is there another class/function that will do this?
Added some fixes:
if($time_start > $time_end) list($time_start, $time_end) = array($time_end, $time_start);
$time_end += (date('I',$time_end)-date('I',$time_start))*3600; // correct for DST
$start_date = new DateTime(date(DATE_ATOM,$time_start));
$end_date = new DateTime(date(DATE_ATOM,$time_end));
$start_date->modify('12pm'); // ignore time difference
$end_date->modify('12pm');
$diff = $start_date->diff($end_date);
echo $diff->format($format);
This seems to give the results I want, but I haven't fully tested it yet.
More fixes, based on Herbert's suggestions:
if($time_start > $time_end) list($time_start, $time_end) = array($time_end, $time_start);
$start_date = new DateTime();
$end_date = new DateTime();
$start_date->setTimestamp($time_start);
$end_date->setTimestamp($time_end);
$diff = $start_date->diff($end_date);
$hours = $diff->format('%h');
$mins = $diff->format('%i');
$secs = $diff->format('%s');
$start_date->setTime(12,0,0);//ignore time difference for date calculations
$end_date->setTime(12,0,0);
$diff = $start_date->diff($end_date);
$years = $diff->format('%y');
$months = $diff->format('%m');
$weeks = $diff->format('%w');
$days = $diff->format('%d');
Note that the $start_date->modify('12pm') wasn't actually doing anything at all. Not sure why it didn't error.
Update
After messing around with a lot of different ideas it occurred to me that timestamps are in GMT (UTC). date(DATE_ATOM,$time_start) is applying the default timezone. However, if you set the timestamp explicitly, DateTime will assume UTC — thus, no DST problem.
The following code seems to work regardless of timezone or DST.
<?php
$time_start = mktime(12,0,0,1,1,2011);
$time_end = mktime(12,0,0,7,1,2011)
$start_date = new DateTime();
$end_date = new DateTime();
$start_date->setTimestamp($time_start);
$end_date->setTimestamp($time_end);
$diff = $start_date->diff($end_date);
$format = '%m months';
echo $diff->format($format);
?>
I tested some edge cases — both date and time, and a variety of timezones — but I haven’t tested every possibility so if you come across an issue, I’d be interested in hearing about it.