# Calculating a date 1 year from today minus 1 day

Hi
I need to to display 2 dates. A ‘from’ date and a ‘to’ date (which should be a year from the ‘from’ date minus 1 day).
Ive got the from date working (\$form_data[‘date_created’] is in the format dd/mm/yyyy):

`\$fromDate = date('F j, Y',strtotime(str_replace('/', '-', \$form_data['date_created'])));`

But how do I calculate the ‘to’ date? (factoring in leap years etc…)

If you look further at `strtotime()` you can specify modifiers such as “+ 1 year” and “- 1 day” to help do the heavy lifting. I don’t know personally if they deal with leap years, I imagine they do.

how do you define ‘factoring in leap years’?

What is ‘1 year from today minus 1 day’, today? January 12 2021? January 13 2021?

I’m 90 percent certain you don’t have to worry about figuring in leap years as strtotime should also do that easily.

Thanks guys. Ive done it. My code (for anyone wanting to achieve a similar thing):

``````\$fromDate = date('F j, Y',strtotime(str_replace('/', '-', \$form_data['date_created'])));
\$toDate = date('F j, Y', strtotime("-1 day", strtotime(str_replace('/', '-', \$form_data['date_created']))));
``````

How does that do the “+ 1 year” part? I can see where you subtract a day.

1 Like

How about:-

``````\$toDate = date('F j, Y', strtotime('Yesterday + 1 Year'));
``````

I’m concerned about ‘Yesterday’ if the date is the 1st of March, 2019. Because then ‘yesterday’ is Feb 28th, +1 year = 28th Feb 2020. But “1 year from today minus a day” would be the 29th…so order of operations would matter.

2 Likes

You are quite right.
It seemed logical to do it in that order to get it in one shot. Ordinarily with addition and subtraction, order of operation isn’t a concern, but in this case it is.

That said, I believe the relative string for what was asked is `strtotime("next year - 1 day")`

because the strtotime function returns a timestamp integer of seconds which is used in the second parameter if the date function…

Try:

1. find the first timestamp
2. add 365 * 24 * 60 * 60 * 1000 seconds
3. minus one day’s worth of seconds
4. pass the result to the second date parameter

#### Edit:

I believe there is a feature in the date function which returns whether or not next year is also year.

#1: Why are we doing milliseconds?
#2: Except this year, there are 366 * 24 * 60 * 60 * 1000 (milli)seconds. Your math loses a day every 4 years (except years divisible by 100, but not excepting years divisible by 400…)

I have just woken up and tapping on a tablet

I missed the intermediate step to find if the date(…) function for next year is a leap year.

1 Like

Oh dear! I forgot the bit about adding a year!

My code is now

`\$toDate = date('F j, Y', strtotime("next year - 1 day", strtotime(str_replace('/', '-', \$form_data['date_created']))));`

Or do you think I should be doing this in milliseconds?

Is there any reason you would need to be so precise? I would have thought down to the second to be sufficiently accurate for most page loads.

No, not really. It was just becuase it was mentioned above.

Is there anything wrong with me code:

`toDate = date('F j, Y', strtotime("next year - 1 day", strtotime(str_replace('/', '-', \$form_data['date_created']))));`

or do you think its better calculating it in seconds. If so would the new code be

`toDate = date('F j, Y', strtotime("365 * 24 * 60 * 60 * 100 - 1 day", strtotime(str_replace('/', '-', \$form_data['date_created']))));`

(Sorry, I havnt tried the above becuase Im not at my computer)

I can’t see why you’d need such potential for trouble. Doing it in milliseconds won’t help make it easier to decide whether you need to worry about leap years, all it’ll do is add anxiety about “leap seconds”.

That code doesn’t take into account leap years, so it’s a step backwards really. I think if I wanted to do it by number manipulation I’d probably just do something like:

``````year += 1
day-of-month -=1
if day-of-month < 1
month -=1
if month < 1 month = 12
day-of-month = last valid day of month
ifend
``````

Does it give the correct answer for all your test cases, with and without leap years, starting on the first day of a month, starting on the last day of a month, starting on New Years day, and load of others?

I think to the nearest day is the level of accuaracy you need to worry about.
So sticking with my simplistic approach, with @m_hutley’s correction, I’m throwing in:-

``````\$toDate = date('F j, Y', strtotime("next year - 1 day"));
``````

Or if not always working from the present day:-

``````\$date = '2020-01-14' ;
\$toDate = date('F j, Y', strtotime("\$date + 1 year - 1 day"));
``````

Hi guys

My code is

``````\$fromDate = date('F j, Y',strtotime(str_replace('/', '-', \$form_data['date_created'])));
\$toDate = date('F j, Y', strtotime("next year - 1 day", strtotime(str_replace('/', '-', \$form_data['date_created']))));
if(\$entry[11] == "Yes"){
\$toDate = date('F j, Y', strtotime("next year + 1 month - 1 day", strtotime(str_replace('/', '-', \$form_data['date_created']))));
}
``````

This has been working great and returns (for example):
\$fromDate = January 30, 2020
\$toDate = January 29, 2021

However! On one form submission it returned:
\$fromDate = January 30, 2020
\$toDate = March 1, 2021

Why would that be!?
Thanks

What’s `\$entry[11]`?
And why add an extra month if it’s `"yes"`?