# Calculate number of days between 2 dates

## Recommended Posts

Posted (edited)

I've tried several scripts to get the number of days between two dates, but none of them will work. Obviously I'm doing something wrong. One thing I know that is causing a problem is that I'm using variables instead of an actual typed in date. Which in my opinion is how most people would do it - variables not actual dates.

I've tried these:

```\$todaydate = date('Y/m/d');
\$now = date('Y-m-d');
\$dd2 = strtotime(\$now);
\$thisyear = 2019;
\$payment_day = 29;
\$pay_month = 6;

if(\$pay_month == 1){\$newpaymentmonth = 2;}
if(\$pay_month == 2){\$newpaymentmonth = 3;}
if(\$pay_month == 3){\$newpaymentmonth = 4;}
if(\$pay_month == 4){\$newpaymentmonth = 5;}
if(\$pay_month == 5){\$newpaymentmonth = 6;}
if(\$pay_month == 6){\$newpaymentmonth = 7;}
if(\$pay_month == 7){\$newpaymentmonth = 8;}
if(\$pay_month == 8){\$newpaymentmonth = 9;}
if(\$pay_month == 9){\$newpaymentmonth = 10;}
if(\$pay_month == 10){\$newpaymentmonth = 11;}
if(\$pay_month == 11){\$newpaymentmonth = 12;}
if(\$pay_month == 12){\$newpaymentmonth = 1;}

\$threezero = array(4, 6, 9, 11); // months with 30 days

// Deal with months that have only 28 days or 30 days, setting the payment day to accommodate months with fewer days.
if (\$payment_day > 28 && \$pay_month == 2)
{
\$payment_day = 28;
}
elseif (\$payment_day == 31 && in_array(\$pay_month, \$threezero))
{
\$payment_day = 30;
}
else
{
\$payment_day = \$payment_day;
}

if (\$newpaymentmonth == 1){\$newpaymentyear = \$thisyear + 1;}else{\$newpaymentyear = \$thisyear;}
\$newpaymentdate = date(\$newpaymentyear.'-'.\$newpaymentmonth.'-'.\$payment_day);
echo date("Y-m-d", \$newpaymentdate) . "<br><br>";

\$ddate = new DateTime(\$thisyear.'-'.\$newpaymentmonth.'-'.\$payment_day);
echo \$ddate->format('Y-m-d') . " - New month payment date with 5 day grace period added.<br><br>";```

Now, how to calculate the difference in days between today's date and \$ddate? I tried the below, but none worked.

```function DateDiff(\$strDate1,\$strDate2){
return (strtotime(\$strDate2) - strtotime(\$strDate1))/  ( 60 * 60 * 24 );  // 1 day = 60*60*24
}
echo "Date Diff = ".DateDiff(\$now,\$ddate)."<br>";

\$timeDiff = abs(\$now - \$ddate);
\$numberofdays = \$timeDiff/86400;
echo "<p>\$numberofdays - days between today's date and payment w/grace date.</p>";```
```\$date1 = \$now;
\$date2 = \$ddate;
\$diff = date_diff(\$date1,\$date2);
echo 'Days Count - '.\$diff->format("%a");```
```\$date1=\$now;
\$date2=\$ddate;
function dateDiff(\$date1, \$date2)
{
\$date1_ts = strtotime(\$date1);
\$date2_ts = strtotime(\$date2);
\$diff = \$date1_ts - \$date2_ts;
return round(\$diff / 86400);
}
\$dateDiff= dateDiff(\$date1, \$date2);
printf("Difference between in two dates : " .\$dateDiff. " Days ");
print "</br>";```

This one returns 18112 Days. Should be days 7 days from 2019-08-05.

None of these work, so I'm doing something wrong. Any ideas?

Thanks

Edited by cyberRobot
fixed typo

##### Share on other sites

try

```\$xmas = new DateTime('2019-12-25');
\$today = new DateTime();
\$daysToGo = \$xmas->diff(\$today)->days;             // 141```

##### Share on other sites

Do you have php error checking enabled?

Did you read the manual on how to use the date() and strtotime() functions?

I think you have bad values in use and that is probably causing your discrepancies.

##### Share on other sites
Posted (edited)

Bad values...no doubt. But I have been unsuccessful in finding any example of a date stored in a variable being used in any datediff, timediff, diff script. Always, the examples use dates that are typed in.

Edited by DavidPR

##### Share on other sites

Barand the script you provided returned this:

A system error occurred. We apologize for the inconvenience.

Fatal error: Uncaught Error: Call to a member function diff() on boolean in /home/....150 Stack trace: #0 {main} thrown in /home/...

Again, that was with me using a date stored in a variable. I'm obviously not correctly doing something with that variable.

##### Share on other sites
Posted (edited)

My example showed you the correct format to use.

EDIT: If they are in a different format you could use this (eg m/d/Y format)

`\$xmas = DateTime::createFromFormat('m/d/Y', '12/25/2019');`

Edited by Barand

##### Share on other sites
1 hour ago, DavidPR said:

date stored in a variable

Do you mean a string value saved in a var or do you mean a valid date value stored in a var?  Bit of a difference.  Care to elaborate?

##### Share on other sites

\$xmas = DateTime::createFromFormat('Y/m/d', \$ddate);

The variables I'm using are in my first post - in the first code section.

##### Share on other sites

\$ddate is already a DateTime object!.

It looks like the whole of the code you posted could be replaced by

```\$paymentDate = new DateTime('last day of next month');

\$daysToPay = \$paymentDate->diff(new DateTime())->days;```

##### Share on other sites

This code that I'm working on will be for a mini-storage company's online rental payment system. The mini-storage office staff will enter into the database a renter's rental information including the "day" each month that renter's payment is due and their monthly rental price.

The day a renter's rental payment is due is the day of the month they rented the unit. If it was me I would have done it differently, making all rent due on the first of the month and pro-rating the beginning and ending month. Just easier that way (seems to me), but it is what it is.

I have a case where a renter's payment day is the 30th of each month. I made a snippet to make that day the 28th in February and the same for others whose payment day is on the 31st.

Anyway, this guy made his June payment on June 30th. Then he made his July's payment on August 1st. It's past the due day date, but the mini-storage company has a 5-day grace period (on the first month - in a series of late payment months). Meaning if he didn't pay his July 30th payment or his August 30th payment, a late fee would be applied one day after his August's payment due date. No grace period of the second month.

The trouble is that my current program saw that he did not make a payment in July so it charged him a \$15 late fee even though he was within the 5-day grace period - August 1st.

So my thinking was to take the date of his payment day (2019-07-30) and subtract this date from today (or whenever day the renter logs in to pay his rent) and come up with the number of days differing from those two dates. If those days are <= 5, then no late fee is added, If more than 5 days the late fee is added. Same goes if he's 2 months behind. I take the first month's due day date that was missed, add 1 month to it and then see if today or the day he's logged in is past the due day date. If so, another late fee is added.

##### Share on other sites

Barand...okay, I'll have to digest that for a while and play with it. Thanks

##### Share on other sites

AND in my first post - did you RTFM on those two functions that you are mis-using?

##### Share on other sites

This is what I have on my test page:

```\$lastdatepaid = strtotime('2019/06/30');

\$todaydate = date('Y/m/d');
\$todaydate = strtotime(\$todaydate);
\$todaymonth = date('m', \$todaydate);
\$twodayday = date('d', \$todaydate);
\$todayyear = date('Y', \$todaydate);
\$oneday = date('j', \$todaydate);

// These variables simulate a renter's payment day and month in the database.
\$payment_day = 29;
\$pay_month = 6;

if(\$pay_month == 1){\$newpaymentmonth = 2;}
if(\$pay_month == 2){\$newpaymentmonth = 3;}
if(\$pay_month == 3){\$newpaymentmonth = 4;}
if(\$pay_month == 4){\$newpaymentmonth = 5;}
if(\$pay_month == 5){\$newpaymentmonth = 6;}
if(\$pay_month == 6){\$newpaymentmonth = 7;}
if(\$pay_month == 7){\$newpaymentmonth = 8;}
if(\$pay_month == 8){\$newpaymentmonth = 9;}
if(\$pay_month == 9){\$newpaymentmonth = 10;}
if(\$pay_month == 10){\$newpaymentmonth = 11;}
if(\$pay_month == 11){\$newpaymentmonth = 12;}
if(\$pay_month == 12){\$newpaymentmonth = 1;}

\$threezero = array(4, 6, 9, 11); // months with 30 days

// Months that have only 28 days or 30 days, setting the payment day to accommodate months with fewer days.
if (\$payment_day > 28 && \$pay_month == 2)
{
\$payment_day = 28;
}
elseif(\$payment_day == 31 && in_array(\$pay_month, \$threezero))
{
\$payment_day = 30;
}
else
{
\$payment_day = \$payment_day;
}

if(\$newpaymentmonth == 1){\$newpaymentyear = \$todayyear + 1;}else{\$newpaymentyear = \$todayyear;}

\$newpaymentdate = strtotime(\$newpaymentyear.'-'.\$newpaymentmonth.'-'.\$payment_day);

echo date("Y-m-d", \$newpaymentdate) . " The New Payment Date<br><br>";

\$ddate = new DateTime(\$todayyear.'-'.\$newpaymentmonth.'-'.\$payment_day);
echo \$ddate->format('Y-m-d') . " - New month payment date with 5 day grace period added.<br><br>";

\$ddate = strtotime(\$ddate);
\$xmas = new DateTime(\$ddate);
\$today = new DateTime();
\$daysToGo = \$xmas->diff(\$today)->days;
echo \$daysToGo;

if (\$todaydate > \$ddate){echo "<p>Charge Late Fee.</p>";}else{echo "<p>Do Not charge late fee.</p>";}```

There may be other errors, but this is the only error I get right now:

"on line 60: strtotime() expects parameter 1 to be string, object given"

Line 60:

`\$ddate = strtotime(\$ddate);`

If I comment out that line I get this:

"Fatal error: Uncaught TypeError: DateTime::__construct() expects parameter 1 to be string, object given...DateTime->__construct(Object(DateTime)) #1 {main} thrown in /home/...on line 61"

Line 61:

`\$xmas = new DateTime(\$ddate);`

##### Share on other sites

Okay, I think I've got it worked out. On this particular problem anyway. Thanks for everyone's help.

##### Share on other sites

An alternative approach...

• storage_unit: date unit rented, price per month
• storage_payment: record of  payments made for each unit
```TABLE: storage_unit                     TABLE: storage_payment
+---------+-------------+-------+       +------------+---------+--------------+--------+
| unit_id | rental_date | price |       | payment_id | unit_id | payment_date | amount |
+---------+-------------+-------+       +------------+---------+--------------+--------+
|       1 | 2019-02-28  | 20.00 |       |          1 |       1 | 2019-03-28   |  20.00 |
|       2 | 2019-04-30  | 20.00 |       |          2 |       1 | 2019-04-28   |  20.00 |
|       3 | 2019-05-01  | 20.00 |       |          3 |       1 | 2019-05-31   |  20.00 |
|       4 | 2019-05-15  | 20.00 |       |          4 |       2 | 2019-05-30   |  20.00 |
|       5 | 2019-05-30  | 20.00 |       |          5 |       2 | 2019-06-30   |  20.00 |
+---------+-------------+-------+       |          6 |       2 | 2019-07-30   |  20.00 |
|          7 |       3 | 2019-06-01   |  20.00 |
|          8 |       4 | 2019-06-19   |  20.00 |
|          9 |       3 | 2019-07-01   |  20.00 |
+------------+---------+--------------+--------+
```

use a query to calculate payments and late fees

```SELECT u.unit_id
, u.rental_date
, COALESCE(MAX(p.payment_date), u.rental_date) as `last_paid`
, timestampdiff(MONTH, COALESCE(MAX(p.payment_date), u.rental_date), CURDATE()) as mths_since_last
, @ld := u.rental_date + INTERVAL timestampdiff(MONTH, u.rental_date, CURDATE()) MONTH as last_due
, SUM(IFNULL(p.amount, 0)) as paid_to_date
, u.price * timestampdiff(MONTH, u.rental_date, CURDATE()) as due_to_date
, u.price * timestampdiff(MONTH, u.rental_date, CURDATE()) - SUM(IFNULL(p.amount, 0)) as rental_owed
, CASE WHEN ( timestampdiff(MONTH, COALESCE(MAX(p.payment_date), u.rental_date), CURDATE()) = 1 ) AND ( timestampdiff(DAY, @ld, CURDATE()) <= 5 ) THEN 0
ELSE timestampdiff(MONTH, COALESCE(MAX(p.payment_date), u.rental_date), CURDATE()) * 15
END as late_fees
FROM storage_unit u
LEFT JOIN
storage_payment p USING (unit_id)
GROUP BY unit_id;

+---------+-------------+------------+-----------------+------------+--------------+-------------+-------------+-----------+
| unit_id | rental_date | last_paid  | mths_since_last | last_due   | paid_to_date | due_to_date | rental_owed | late_fees |
+---------+-------------+------------+-----------------+------------+--------------+-------------+-------------+-----------+
|       1 | 2019-02-28  | 2019-05-31 |               2 | 2019-07-28 |        60.00 |      100.00 |       40.00 |        30 |
|       2 | 2019-04-30  | 2019-07-30 |               0 | 2019-07-30 |        60.00 |       60.00 |        0.00 |         0 |
|       3 | 2019-05-01  | 2019-07-01 |               1 | 2019-08-01 |        40.00 |       60.00 |       20.00 |        15 |
|       4 | 2019-05-15  | 2019-06-19 |               1 | 2019-07-15 |        20.00 |       40.00 |       20.00 |         0 |
|       5 | 2019-05-30  | 2019-05-30 |               2 | 2019-07-30 |         0.00 |       40.00 |       40.00 |        30 |
+---------+-------------+------------+-----------------+------------+--------------+-------------+-------------+-----------+```

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

×   Pasted as rich text.   Restore formatting

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×

×

• #### Activity

• Chat
×
• Create New...