Jump to content

strtotime() is interpreted differently on different servers


Go to solution Solved by kicken,

Recommended Posts

For a reason that I have no idea, my developer machine is treating strtotime() differently than my server. This has not been the case in the past and I just now, this very day, realized this. I don't know whether this has to do with the PHP version running or not, but I need help to figure this out.

 

Again, I have seen the same output on the developer machine as I have on the server for years, and not until now did I notice a difference.

 

To print out the last day of the month, I have used the following code:

 

date('Y-m-d', strtotime('last day'));

 

OUTPUTS:

Server: 2013-05-31

Dev. Machine: 2013-05-06

 

PHP VERSIONS:

Server: 5.3.2

Dev. Machine: 5.3.10

 

Both machines run Ubuntu Linux (10.04 and 12.04 respectivly)

 

Does this have to do with the differences in PHP or something else? I'm now scared to death to upgrade the server as plenty of my applications and scripts rely on this function in order to process dates and time correctly. I can see how the string 'last day' can be interpreted in both ways, but I just chose this as an example. I have plenty of other strings passed to this function that is no longer interpreted "correctly", much less confusing as the string 'last day'.

 

 

date_default_timezone_get() reports America/Los_Angeles on both machines. There is no difference in the code between the machines and strtotime() has always been interpreted the same on them both. And specifically setting it (should not be needed as the default is used if missing) before code execution made not difference

Edited by MockY

Looking at the change log, nothing has happened since 5.3.0 http://php.net/manual/en/function.strtotime.php

 

I need to use this function in order to calculate how many days ahead or in the past of a given date. Like if a specific date is more than 7 days ago, send out a reminder (just as an example). Sometimes is is a string, sometimes just numbers, and at times even both. Some more complex than others. In other words, I rely heavily on strtotime() in order to fetch the accurate time stamp so I can later print it out using date().

So, get the default UTC time of the server and the developer machine and compare them.

 

If they used different UTC time just set the NTP protocol to use the same time as the server then open the php.ini file and set the date.timezone = UTC.

  • Solution

Bug# 51096

 

'last day' meaning -1 day is the correct behaviour. It returning the last day of the month was considered a bug and got fixed. Use the date('Y-m-t') method, or possibly 'last day of'.

Bug# 51096

 

'last day' meaning -1 day is the correct behaviour. It returning the last day of the month was considered a bug and got fixed. Use the date('Y-m-t') method, or possibly 'last day of'.

Ahh I see. This convinient bug is one of few bugs I actually liked. I sadly have to stop updating the server until I find a solution to my problem. Now with the bug fixed, my computations does not work out the way I'd like them to, even though I use the last of the month. If I add a month to a date with 31 days and the next day has only 30, the function skips a whole month an returns 2 more months.

 

Example

date('Y-m-t', strtotime('2013-05-31 +1month'));

 

Returns

2013-07-31

Expected

2013-06-30

 

To me, this seems like a bug in itself and they did not fix anything...just placed the bug elsewhere. I mark the thread as solved as you did in fact answer my question, but you are welcome to take a stab at the new issue.

 

EDIT:

Seems like the following did the trick:

 

strtotime('last day of 2013-05-31 +1months'))

Edited by MockY

With 05-31 + 1 month you get 06-31, which wraps to 07-01. date(Y-m-t) from that will give you 2013-07-31 because t=number of days in the month. The actual Y-m-d date is just 2013-07-01.

Using "last day of" changes the arithmetic so it only uses the last day of the month: 2013-05 + 1 month is 2013-06 and the last day is 2013-06-30.

Do you see any issues moving forward with my "solution"? I tossed all kinds of dates at it, including leap years, and it always returns what I expect to see. As long as I throw valid dates at it, that is. Using 2012-02-31 (which of cource is not a valid date) would cause it to wrap just like the date(Y-m-t) method did.

last day of 2013-05-31 +1months

The three different date parts have the following effect:

  • 2013-05-31 is evaluated: internal date 2013-05-31 (at midnight)
  • +1 months is evaluated: internal date 2013-06-31 (that's right, June 31st) the logic is simply to increment the month number without touching days
  • last day of is evaluated: internal date 2013-06-30 (June only has 30 days)
It is only after all of these steps that the date, if it is invalid, is tweaked to become valid. For example, if we didn't have "last day of" then it would have rolled around to July 1st.

 

Aside: in this case, it is not important which order the three parts are written.

Edited by salathe

MockY, I don't think so. Personally I don't like relying on strtotime() when there are simpler more straightforward methods. The last day of this month can be just

date("Y-m-t") // as I posted before
Last day of next month can be

date("Y-m-d", mktime(0, 0, 0, date("n") + 2, 0)) // day #0 of two months away
or if you don't mind the Y-m-t trick

date("Y-m-t", mktime(0, 0, 0, date("n") + 1, 1)) // day=1 guarantees no wrapping
Edited by requinix
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

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

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

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

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.