I am trying to calculate the difference in time between two times using this:
round(abs(strtotime("17:30") - strtotime("18:30")) / 60,2);
= '1'
which works fine, but as soon as i make it over 2 days its not calculating correctly
round(abs(strtotime("17:30") - strtotime("02:00")) / 60,2);
= '15.5' this should be '8.5'
For more accurate and correct results you can use ->diff() function. As an example:
<?php
$val1 = '2014-03-18 10:34:09.939';
$val2 = '2014-03-14 10:34:09.940';
$datetime1 = new DateTime($val1);
$datetime2 = new DateTime($val2);
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days');
?>
Output:
-4 days
strtotime returns an timestamp. Currently your calculation is only partly correct, because you ignore negative values. In case of negative values (that should be the case, if the second time is on the next day), you should add 86400 (24*60*60 - the seconds of a day).
$start = strtotime("17:30");
$end = strtotime("02:00");
$diff = $end - $start;
// end date is on the next day
if ($diff < 0) {
$diff += 86400;
}
$hours = $diff / 3600;
echo round($hours, 2);
You can do the math yourself by converting dates into unixtime:
strtotime('2017-12-29 02:00')-strtotime('2017-12-28 17:30')
This will return the difference in seconds, so if I want to print the value in hours, I have to divide by 60 twice:
php > print((strtotime('2017-12-29 02:00')-strtotime('2017-12-28 17:30'))/60/60);
8.5
Related
I have following code that add 2 days to a given date.
$myDate = 2018-07-28 11:00:00; // the date is picked from db
$penaltyDays = 2;
$date1 = new DateTime($myDate);
$date1->add(new DateInterval("P{$penaltyDays}D")); // add N days
$now = new DateTime();
$interval = $date1->diff($now); // get difference
$days = $interval->d; // difference in days
I want value of $days must be 0 after passing exactly 48 hours. If 3 days are passed the value of $days should be -1.
I will also appreciate if someone tell me efficient/proper way to get the result.
To make an efficient code according to your specification then I would rather use strtotime than DateTime.
This code checks if the current time is larger than the database time + two (or three) days in seconds.
$myDate = "2018-07-28 11:00:00";
$unix = strtotime($myDate);
if(time() > ($unix + 86400*3)){
$days = -1;
}else if(time() > ($unix + 86400*2)){
$days = 0;
}else{
$days = "something else";
}
Echo $days;
https://3v4l.org/d6Q15
I am creating a timesheet whereby it shows expected and actual hours.
The durations are saved like the below
23:15 - 23 hours and 15 mins
25:45 - 25 hours and 45 mins
I need to work out the difference in hours and mins between the two (extra hours worked)
I have tried the below
$acutal=='23:15';
$expected=='25:45';
$start_time = new DateTime("1970-01-01 $acutal:00");
$time = $start_date->diff(new DateTime("1970-01-01 $expected:00"));
This does work, however when the hours are over 24:00 it throws an error (obviously because it's reading it as time)
Uncaught exception 'Exception' with message 'DateTime::__construct():
Failed to parse time string (1970-01-01 25:45:00)
Is there another way to do this?
You could check if the number of hours are greater than 24, and if so, add a day, and remove 24 hours.
$actual='23:15';
$expected='25:45';
$day = 1;
list($hrs, $min) = explode(':', $expected);
if ($hrs > 24) { $day += 1; $hrs -= 24; }
$start_time = new DateTime("1970-01-01 $actual:00");
$time = $start_time->diff(new DateTime("1970-01-$day $hrs:$min:00"));
echo $time->format('%hh %Im');
Output:
2h 30m
Please also note that == is used to compare, not to assign.
You can also change the if ($hrs > 24) by while(), if there is 48 hours or more.
edit
As pointed out by #CollinD, if the time exceed the number of days of the month, it will fail. Here is another solution:
$actual='23:15';
$expected='25:45';
list($hrs, $min) = explode(':', $actual);
$total1 = $min + $hrs * 60;
list($hrs, $min) = explode(':', $expected);
$diff = $min + $hrs * 60 - $total1;
$start_time = new DateTime();
$expected_time = new DateTime();
$expected_time->modify("+ $diff minutes");
$time = $start_time->diff($expected_time);
echo $time->format('%hh %Im');
You can do it manually by keeping track of the number of minutes worked - this will be exact and will also allow you to show negative differences.
<?php
// get the difference in H:mm between two H:mm
function diff_time($actual, $expected) {
$diff_mins = mins($actual) - mins($expected);
return format_mins($diff_mins);
}
// convert a HH:mm to number of minutes
function mins($t) {
$parts = explode(':', $t);
return $parts[0] * 60 + $parts[1];
}
// convert number of minutes into HH:mm
function format_mins($m) {
$mins = $m % 60;
$hours = ($m - $mins) / 60;
// format HH:mm
return $hours . ':' . sprintf('%02d', abs($mins));
}
var_dump(diff_time('23:15', '25:45'));
var_dump(diff_time('25:15', '23:45'));
This outputs:
string(5) "-2:30"
string(4) "1:30"
.. first, 2:30 less than expected, for the second 1:30 more than expected.
You can try using datetime functions but it seems a lot more straightforward to me to treat the times as string, use split or explode to get hours and minutes, convert to integers, get the difference in minutes and convert it back to hours and minutes (integer divide by 60 and remainder).
$t1=explode(':',$expected);
$t2=explode(':',$actual);
$d=60*($t1[0]-$t2[0])+t1[1]-t2[1];
$result=str_pad(floor($d/60),2,'0',STR_PAD_LEFT).':'.str_pad($d%60,2,'0',STR_PAD_LEFT);
I have this code to subtract two dates and get the difference between them in minutes:
date_default_timezone_set('Asia/Istanbul');
$date1 = '2014-07-01 09:07:25';
$date1 = date_create($date1);
$current_pc_date = date('Y-m-d H:i:s');
$current_pc_date = date_create($current_pc_date);
$diff = date_diff($current_pc_date,$date1);
$minutes_diff = $diff->format("%R%i");
echo $minutes_diff;
if($minutes_diff<5 && $minutes_diff>0)
{
echo 'yes';
}
else
{
echo 'no';
}
I want to subtract the dates and get the results in minutes but here it subtract the minute parts in the two dates so if I changed the hour part of the $date it still giving the same result when subtracting from the other date for example :
2014-07-01 02:25:48
2014-07-01 02:23:48
it will result in 2 minutes
if I changed the hour part it will still giving the same result :
2014-07-01 03:25:48
2014-07-01 02:23:48
it will result in 2 minutes
I want to have the result in the second example like 62 minutes
You can try:
function timeDiff($start_date,$end_date="now"){
$time_diff = (new Datetime($start_date))->diff(new Datetime($end_date));
$time_diff_minute = $time_diff->days * 24 * 60;
$time_diff_minute += $time_diff->h * 60;
$time_diff_minute += $time_diff->i;
return $time_diff_minute;
}
timeDiff('2014-07-01 03:25:48', '2014-07-01 02:23:48'); // 62
You could just convert your times to seconds, then subtract, then convert the difference to minutes:
$t1 = '2014-07-01 03:25:48';
$t2 = '2014-07-01 02:23:48';
$minutes_diff = abs(strtotime($t1) - strtotime($t2)) / 60;
echo $minutes_diff; //62
See demo
References:
strtotime() converts the date to a timestamp (seconds since Jan 1 1970)
abs() gets the absolute value of the difference (in case $t2 is greater than $t1)
i use ths method to find the difference between two timestamp and get the number of seconds between those two times, and i refresh the information with jquery like a counter.
$diff = strtotime(date('Y-m-d H:i:s')) - strtotime('2014-06-25 14:50:03');
$time = intval(date('s', $diff));
echo $time;
When the difference is more than 60 seconds, the $time comes back to 0, like a reset.
i would like to display 1 min XX s for example
The s flag for date() will never return a value greater than 59 as it only represents the current number of seconds of a given time which can never be more than 59 before rolling over into a new minute.
If you want the total number of seconds you can actually remove your second line of code as the difference between two Unix Timestamps is always in seconds:
$time = strtotime(date('Y-m-d H:i:s')) - strtotime('2014-06-25 14:50:03');
echo $time;
If you want to display this as minutes and seconds you can use DateTime() which offers better tools for this:
$now = new DateTime();
$then = new DateTime('2014-06-25 14:50:03');
$diff = $now->diff($then);
echo $diff->format('%i minutes %s seconds');
format the date
$diff = strtotime(date('Y-m-d H:i:s')) - strtotime('2014-06-25 14:50:03');
$time = date('i:s', $diff);
echo $time;
Pass time like 1 & now 2
function diffrencePassTimeAction($DataTime){
$im = $DataTime - strtotime("now");
return $im;
}
Future time like 2 & now 1
function diffrenceFuturTimeAction($DataTime){
$im = strtotime("now") - $DataTime;
return $im;
}
this function delete (-less)
function diffrencePassTimeAction($DataTime){
if ($DataTime > 0)
return $DataTime - strtotime("now");
else
return strtotime("now"); // OR return 0;
}
This question already has answers here:
Get interval seconds between two datetime in PHP?
(8 answers)
Closed last year.
HI, i have a couple of posts in my MySql database server, one of the info content in each post is the date and time in the format datetime (Ex. 2010-11-26 21:55:09) when the post was made.
So, i want to retrive the actual date and time from the SQL server with the function NOW() and calculates how many seconds or minutes or hours or days ago was post the info.
I dont know how to create this php script but i know that for sure is allready made, so thanks for any help.
you could use the date_diff() function
http://php.net/manual/en/function.date-diff.php
Something like...
<?php
$now = time();
$then = $posttime;
$diff = date_diff($now,$then);
echo $diff->format('%R%d days'); #change format for different timescales
?>
edit --
I actually solve this issue on one of my twitter apps using this function...
function time_since ( $start )
{
$end = time();
$diff = $end - $start;
$days = floor ( $diff/86400 ); //calculate the days
$diff = $diff - ($days*86400); // subtract the days
$hours = floor ( $diff/3600 ); // calculate the hours
$diff = $diff - ($hours*3600); // subtract the hours
$mins = floor ( $diff/60 ); // calculate the minutes
$diff = $diff - ($mins*60); // subtract the mins
$secs = $diff; // what's left is the seconds;
if ($secs!=0)
{
$secs .= " seconds";
if ($secs=="1 seconds") $secs = "1 second";
}
else $secs = '';
if ($mins!=0)
{
$mins .= " mins ";
if ($mins=="1 mins ") $mins = "1 min ";
$secs = '';
}
else $mins = '';
if ($hours!=0)
{
$hours .= " hours ";
if ($hours=="1 hours ") $hours = "1 hour ";
$secs = '';
}
else $hours = '';
if ($days!=0)
{
$days .= " days ";
if ($days=="1 days ") $days = "1 day ";
$mins = '';
$secs = '';
if ($days == "-1 days ") {
$days = $hours = $mins = '';
$secs = "less than 10 seconds";
}
}
else $days = '';
return "$days $hours $mins $secs ago";
}
You pass it in a unix timestamp of the time to check (the post time) and it returns the various string.
As billythekid said, you can use the date_diff() function if you are using PHP5.3+, if you are not then there are various methods. As shown by other posters. The quickest method in MySQL if you want to know the time split in to the "hours:mins:secs" hierarchy is to use the TIMEDIFF() function.
SELECT TIMEDIFF(NOW(), '2010-11-26 12:00:00');
If you want it as seconds, use the unix timestamp features in MySQL or in PHP, you can convert MySQL dates to PHP quickly using strtotime().
Usually, you do this kind of thing in a query, but MySQL isn't very good with intervals (it would be very easy with PostgreSQL). You could convert it to unix timestamp, then it would give the number of seconds between the two dates :
SELECT UNIX_TIMESTAMP() - UNIX_TIMESTAMP(your_datetime_column);
I thought about DATEDIFF, but it only returns the number of days between the two dates.
You can do it in PHP, for instance, with DateTime class :
$date1 = new DateTime();
$date2 = new Datetime('2010-11-26 12:00:00');
var_dump($date1->diff($date2));
(There's a procedural way to do this, if you're not a fan of OOP.)
This is definitely the solution I'd use if I can't do it with the RDBMS. DateTime::diff returns a DateInterval object, which contains the number of seconds, minutes, hours, days, etc. between the two dates.
You could also do it with timestamps in PHP :
$num_sec = time() - strtotime('2010-11-26 12:00:00');
Which would return the same thing as the SQL query.
An easy solution is possible from within the SQL Query:
SELECT UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(post_date) AS seconds_ago FROM posts
Documentation here: MySQL Ref
I actually needed to do this in PHP myself and while billythekid's post was in the right direction it fell short. I've minimized the code though it should be clear that the second parameter is from a database with a DATETIME column type.
<?php
$interval = date_diff(date_create(date('Y-m-d H:i:s')), date_create($row1['date']));
echo $interval->format('%R%a days');
//Database: 2019-02-22
//PHP's date: 2018-07-07
//Result: +306 days
?>
A reminder of the obvious: you can also just use substr($interval->format('%R%a days'),1) if you need just the integer.