Get the EXACT difference between two dates - php

I am implementing a real Estate application and I need to EXACTLY check the date difference between two dates.
I will prefer for this a javascript jquery approach, but any other solution will be welcome.
My goal is to not allow users to enter dates where the difference is EXACTLY bigger than 2 (or 5) years.
I have tried, along with many others, this solution:
How to get the months between 2 dates
Unfortunately, this is not what I really need.
When I do:
The rent will start at 01-01-2017
And will end at 31-12-2018
I will get 24 months (exactly rented for 2 years), which is correct for my purpose.
But if I try:
The rent will start at 01-01-2017
And will end at 01-01-2019
I will still get 24 months (but it is rented for 2 years and 1 day), which is not correct for my purpose.
Due to the law regulations in my country (Netherlands) there is for the contracts a big difference between the two above mentioned situations.
I will appreciate any help from your side.

As mentioned in the comment, add 2 years and subtract 1 day. Best to do it with DateTime class:
$dt = DateTime::createFromFormat('d-m-Y', '01-01-2017');
$dt->add(new DateInterval('P2Y'));
$dt->sub(new DateInterval('P1D'));
var_dump($dt->format('d-m-Y'));
This will produce the desired result:
string(10) "31-12-2018"

Here's an excellent function by SunilKmCharde, from the User Contributed Notes in the PHP manual:
<?php
//////////////////////////////////////////////////////////////////////
//PARA: Date Should In YYYY-MM-DD Format
//RESULT FORMAT:
// '%y Year %m Month %d Day %h Hours %i Minute %s Seconds' => 1 Year 3 Month 14 Day 11 Hours 49 Minute 36 Seconds
// '%y Year %m Month %d Day' => 1 Year 3 Month 14 Days
// '%m Month %d Day' => 3 Month 14 Day
// '%d Day %h Hours' => 14 Day 11 Hours
// '%d Day' => 14 Days
// '%h Hours %i Minute %s Seconds' => 11 Hours 49 Minute 36 Seconds
// '%i Minute %s Seconds' => 49 Minute 36 Seconds
// '%h Hours => 11 Hours
// '%a Days => 468 Days
//////////////////////////////////////////////////////////////////////
function dateDifference($date_1 , $date_2 , $differenceFormat = '%a' )
{
$datetime1 = date_create($date_1);
$datetime2 = date_create($date_2);
$interval = date_diff($datetime1, $datetime2);
return $interval->format($differenceFormat);
}
?>

This should be accurate and be aware of leap years etc...
<?php
$date = date_create('02-01-2017');
date_add($date, date_interval_create_from_date_string('2 years'));
$twoyears = date_format($date, 'd-m-Y');
echo $twoyears; // 02-01-2019
$rentperiod = $twoyears->sub(DateInterval::createFromDateString('1 day'));
echo $rentperiod; //01-31-2019

Javascript:
function diff( d1, d2){
x = new Date(d2-d1);
return x.getUTCDate() + " " + x.getUTCMonth() + " " + (x.getUTCFullYear() - 1970);
}
example:
a = new Date('01-01-2017');
b = new Date('01-01-2019');
diff(a,b);
"Days:1, Months: 0, Years: 2"

Related

How to correctly calculate time remaining from php date time

The expiry date is in unix timestamp approx 30th sept 2020 6AM
$expiry_date_time = 160142766; //30 sept 2020 6AM
$dt1 = new DateTime();
$dt1->setTimestamp($expiry_date_time);
$now = new DateTime();
$i = $now->diff($dt1);
$time_remaining = $i->format('%y years %m months %a days %h hours %i minutes');
echo $time_remaining;
Output today when i ran the code (11th OCT 2020)
0 years 0 months 11 days 7 hours 19 minutes
This code doesn't give incorrect result but it cannot differentiate between expired and not expired, like in the above case the subscription had expired it gives the output 11 days which is not entirely incorrect because it has been 11 days since its expired if you calculate but shouldn't it be Negative 11 days ?
If I make the expiry date to two days in the future it will correctly calculate and output 2 days, xx hours and xx minutes.
How to make it differentiate between expired and not expired ?
DateInterval has an invert flag for this very purpose:
invert
Is 1 if the interval represents a negative time period and 0 otherwise.
$expiry_date_time = 160142766; //30 sept 2020 6AM
$dt1 = new DateTime();
$dt1->setTimestamp($expiry_date_time);
$now = new DateTime();
// What you're doing right now
$i = $now->diff($dt1);
var_dump($i->invert); // int(1)
// If you're doing it the other way around
$i = $dt1->diff($now);
var_dump($i->invert); // int(0)
Demo
$expiry_date_time = 160142766; //30 sept 2020 6AM
$dt1 = new DateTime();
$dt1->setTimestamp($expiry_date_time);
$now = new DateTime();
$i = $now->diff($dt1);
$time_remaining = $i->format('%y years %m months %a days %h hours %i minutes');
if($expiry_date_time - $now()->getTimestamp() < 0) {
$time_remaining = "expired $time_remaining ago";
}
echo $time_remaining;
This will add some text to the text if it is in the past, to make sure you know if it is expired or not yet.

How to display days and hours with date() in php

I have a timestamp which calculates remaining time between 2 dates.
$job_expiration = strtotime($job['job_expiration']) - time(); like so.
Right now, I'm showing only 1 day or 2 days with the date() function.
date('j', $job_expiration) like so.
I also want to show hours instead of 2 days. let's say the time remaining is 1 day 16 hours or only 30 minutes. then I want to show the hours with day too.
1 day, 16 hours or only 30 minutes
how can I do that?
function convert_seconds($seconds) {
$dt1 = new DateTime("#0");
$dt2 = new DateTime("#$seconds");
return $dt1->diff($dt2)->format('%a days, %h hours, %i minutes and %s seconds');
}
echo convert_seconds(200000)."\n";
Sample output:
2 days, 7 hours, 33 minutes and 20 seconds
In your case you should use this function like convert_seconds($job_expiration)

Count days between two dates in yii2

Today I am counting days between two dates in yii2. One date is on column of database. Database column is due_date. The other date is current date.
Here is the code for what I done so far in yii2 :
$abc=Yii::$app->db->createCommand('select * from lib_chekout where patron_id=:patron_id AND is_checkedin=0')
->bindValue(':patron_id',$patron_id)
->queryAll();
$datetime1 = $abc[0]['due_date'];
$datetime2 = date("Y-m-d H:i:s");
$interval = $datetime1->diff($datetime2);
print_r($interval);
exit;
My due_date is no $abc array . Now how can I count the dates ?
For reference due_date has date 2011-08-13 00:00:00. And today date is 2016-12-13.
How can I do it ?
as #kashif said you can use date_diff function. first you need to convert you date to DateTimeInterface then pass it to date_diff.
//PARA: Date Should In YYYY-MM-DD Format
//RESULT FORMAT:
// '%y Year %m Month %d Day %h Hours %i Minute %s Seconds' => 1 Year 3 Month 14 Day 11 Hours 49 Minute 36 Seconds
// '%y Year %m Month %d Day' => 1 Year 3 Month 14 Days
// '%m Month %d Day' => 3 Month 14 Day
// '%d Day %h Hours' => 14 Day 11 Hours
// '%d Day' => 14 Days
// '%h Hours %i Minute %s Seconds' => 11 Hours 49 Minute 36 Seconds
// '%i Minute %s Seconds' => 49 Minute 36 Seconds
// '%h Hours => 11 Hours
// '%a Days => 468 Days
//////////////////////////////////////////////////////////////////////
function dateDifference($date_1 , $date_2 , $differenceFormat = '%a' )
{
$datetime1 = date_create($date_1);
$datetime2 = date_create($date_2);
$interval = date_diff($datetime1, $datetime2);
return $interval->format($differenceFormat);
}
from here
DateTime::diff -- DateTimeImmutable::diff -- DateTimeInterface::diff -- date_diff — Returns the difference between two DateTime objects
You must convert your date string into datetime object
$abc = Yii::$app->db->createCommand('select * from lib_chekout where patron_id=:patron_id AND is_checkedin=0')
->bindValue(':patron_id',$patron_id)
->queryAll();
$datetime1 = new Datetime($abc[0]['due_date']);
$datetime2 = new Datetime(date("Y-m-d H:i:s"));
$interval = $datetime1->diff($datetime2)->days;
print_r($interval);
exit;
Demo
Try this way.
$datetime1 and $datetime2 should be DateTime object.
$datetime1 = new DateTime('2011-08-13 00:00:00');
//$datetime1 = new DateTime($abc[0]['due_date']);
$datetime2 = new DateTIme('Now');
$interval = $datetime1->diff($datetime2);
print_r($interval->format('%R%a'));

PHP DateTime->diff

I was going through a php code today and found this to be really weird.
<?php
$now = new DateTime("2015-07-29 03:38:55");
$previous = new DateTime("2013-07-29 05:06:40");
$diff = $now->diff($previous);
$diff2 = $previous->diff($now);
printf("%d years, %d month, %d days, %d hours, %d minutes %d seconds.<br/>", $diff->y, $diff->m, $diff->d, $diff->h, $diff->i, $diff->s);
printf('%d years, %d month, %d days, %d hours, %d minutes %d seconds', $diff->y, $diff->m, $diff2->d, $diff2->h, $diff2->i, $diff2->s);
The output is
1 years, 11 month, 30 days, 22 hours, 32 minutes 15 seconds
1 years, 11 month, 29 days, 22 hours, 32 minutes 15 seconds
I have two questions
I read the document it said that $previous->diff($now); shows $now - $previous. However, if it is the other way around, wouldn't it be negative?
Why is one 30 days and the other is 29 days?
I have a speculation that this could be due to the invert. I'm not entirely sure why it is adding an extra day... but a quick change I did was:
$now = new DateTime("2015-07-29 03:38:55");
$previous = new DateTime("2013-07-29 05:06:40");
$diff = $now->diff($previous);
$diff2 = $previous->diff($now);
printf("%d years, %d month, %d days, %d hours, %d minutes %d seconds\r\n", $diff->y, $diff->m, ($diff->d - $diff->invert), $diff->h, $diff->i, $diff->s);
printf('%d years, %d month, %d days, %d hours, %d minutes %d seconds', $diff->y, $diff->m, ($diff2->d - $diff2->invert), $diff2->h, $diff2->i, $diff2->s);
And the output is:
1 years, 11 month, 29 days, 22 hours, 32 minutes 15 seconds
1 years, 11 month, 29 days, 22 hours, 32 minutes 15 seconds
Or, alternatively, the above is completely wrong and is just a coincidence... another explanation may be that the diff days was a float value for $diff, and so it was rounded down... yielding 29 days. Possible leap-year issue as well.
Edit
The above is also wrong... if you change the output to floats, it will show whole numbers. This adds to the confusion. I'll leave this answer to possibly help someone else figure out the solution.
$now = new DateTime("2015-07-29 03:38:55", new DateTimeZone('GMT'));
$previous = new DateTime("2013-07-29 05:06:40", new DateTimeZone('GMT'));
$diff = $now->diff($previous);
$diff2 = $previous->diff($now);
printf("%f years, %f month, %f days, %f hours, %f minutes %f seconds %f total days\r\n", $diff->y, $diff->m, $diff->d, $diff->h, $diff->i, $diff->s, $diff->days);
printf('%f years, %f month, %f days, %f hours, %f minutes %f seconds %f total days', $diff->y, $diff->m, $diff2->d, $diff2->h, $diff2->i, $diff2->s, $diff2->days);
I even set the timezone in hopes to help. Still yields whole numbers:
1.000000 years, 11.000000 month, 30.000000 days, 22.000000 hours, 32.000000 minutes 15.000000 seconds 729.000000 total days
1.000000 years, 11.000000 month, 29.000000 days, 22.000000 hours, 32.000000 minutes 15.000000 seconds 729.000000 total days
the sign of the difference is in the invert property: $diff->invert=1 and $diff2->invert=0
You can see in the php source here a day correction by 1 when:
the 1st of the dates is in DST and the 2nd is not
the timestamp of the 2nd date starts after the timetstamp of the 1st one without the DST correction
the timestamp of the 2nd date starts before the timetstamp of the 1st one with the DST correction
This is what is causing one to show 30 days and the other to show 29. In #Half Crazed's example, both dates are in DST, so no correction there. If the previous date of the OP were 2013-07-29 03:06:40, their wouldn't be a difference

date_diff outputs wrong value

$end=date_create("2013-07-30 00:30:33");
$now=date_create();
$x=date_diff($end,$now);
echo $x->format('%a days');
When I use %a it returns 45 days which is correct, when I use %d it returns 15 days. What is problem there?
Number 15 are the days calculated from difference by the months.
For example: (from http://www.php.net/manual/en/dateinterval.format.php)
<?php
$january = new DateTime('2010-01-01');
$february = new DateTime('2010-02-01');
$interval = $february->diff($january);
// %a will output the total number of days.
echo $interval->format('%a total days')."\n";
// While %d will only output the number of days not already covered by the
// month.
echo $interval->format('%m month, %d days');
?>
The above example will output:
31 total days
1 month, 0 days
Note that date_diff($end,$now); returns DateInterval and it has its own format:
FROM PHP DOC
a = Total number of days as a result of a DateTime::diff() or (unknown) otherwise
And
d = Days, numeric
You can not have 45 days in a single month so its basically using %d or %m month %d days
45 days //or
1 month 15 days

Categories