strtotime() - The PHP, date swiss army knife

Fri, Sep 19, 2008 10:02 PM
Man, what did I do before strtotime().  Oh, I know, I had a 482 line function to parse date formats and return timestamps.  And I still could not do really cool stuff.  Like tonight I needed to figure out when Thanksgiving was in the US.  I knew it was the 4th Thursday in November.  So, I started with some math stuff and checking what day of the week Nov. 1 would fall on.  All that was making my head hurt.  So, I just tried this for fun.
strtotime("thursday, november ".date("Y")." + 3 weeks")

That gives me Thanksgiving.  Awesome.  It is cool for other stuff too.  At its very basic, it can take a MySQL datetime field and turn it into a timestamp.  Very handy for date calculations.  It also understands RFC 2822 and ISO 8601 date formats.  These are common in HTTP headers and some XML documents like RSS and Atom feeds.  Also, PHP can output those two standard formats with the date() function.  So, this makes them a good standards compliant way to pass full, timezone specific dates around.
16 comments
Gravatar for Derick Rethans

Derick Rethans Says:

it's even smarter than you think:

strtotime("fourth thursday of Nov ".date("Y"));

And if it's for the current year, you can even leave of the date("Y") part.

Gravatar for Hodicska Gergely

Hodicska Gergely Says:

Hi! In the past there was a small bug in date('r'), it was not compatible with HTTP date format, so you should check it before you start to use it.

Gravatar for Shahar Evron

Shahar Evron Says:

@Derick: Are you referring to the ext/date/lib/parse_date.c stuff? I assume it's under the PHP license and I can just yank it freely right?

Thanks.

Gravatar for Matthew Montgomery

Matthew Montgomery Says:

@Hodicska,

You are also correct in a way, If you avoid the use of functions in WHERE conditions in general you are more likely to have the response handled out of query cache.

Gravatar for Richard Heyes

Richard Heyes Says:

> it can take a MySQL datetime field and turn it into a timestamp

You could also use the MySQL function UNIX_TIMESTAMP().

Gravatar for Hodicska Gergely

Hodicska Gergely Says:

Yes, but while MySQL does not support functional indexes it not a best practice using functions like this for example in where clause.

Gravatar for Matthew Montgomery

Matthew Montgomery Says:

@Hodicska
You can use functions in the where condition like that just fine. The problem comes in when you compare a column run through a function to a literal. i.e.

where date_col1 = from_unixtime(value); /* good */
vs.
where unix_timestamp(date_col1) = value /* bad */

This is because the optimizer can convert the from_unixtime(value) into a single literal and compare like values. The first can use and index on date_col1 where the second must convert the whole column using a tmp table before it can compare all rows.

Gravatar for Shahar Evron

Shahar Evron Says:

Does anybody know if there's a general purpose C library that implements the same functionality as strtotime() ? I looked at the PHP source and I don't think it's based on any library. I could hack it off from there, but I was wondering if that awesome functionality was conveniently available somewhere else for other C apps.

Gravatar for Mike

Mike Says:

Beware of relying on this for business critical applications.

strtotime('2008-03-21 -1 month') might not return what you would expect.

Gravatar for Brian Moon

Brian Moon Says:

@derick, not working for me.

echo date("r", strtotime('fourth thursday of Nov'));
echo "\n";
echo date("r", strtotime('4th thursday of Nov'));

Wed, 31 Dec 1969 19:00:00 -0500
Wed, 31 Dec 1969 19:00:00 -0500


@Mike, I get:

echo date("r", strtotime('2008-03-21 -1 month'));
Thu, 21 Feb 2008 00:00:00 -0500

That is exactly what I expect. Care to elaborate?

Gravatar for Hodicska Gergely

Hodicska Gergely Says:

@Matthew: I tried this out and yes it is working, thank you for point this out. In the past I run into this more time by checking the query with EXPLAIN, that is while I started to create this type of conditional value on the client code.

Gravatar for Richard Heyes

Richard Heyes Says:

@Matthew Montgomery:

You seem to have the fnunction second, and then first.Presumably the order makes no difference? Thanks.

Gravatar for Ivan

Ivan Says:

you may also interested in strptime function :)

Gravatar for Mike

Mike Says:

Whoopsie. That was supposed to be strtotime(’2008-03-31 -1 month’) . If you then do the reverse (i.e. add a month to the resulting date) you will find that you aren't back where you started.

In this corner case strtotime also behaves differently from MySQL date manipulation functions.

Gravatar for Derick Rethans

Derick Rethans Says:

@Brian: It could be a PHP 5.3 thing only...
@Shavar: The parsing is implemented in a library, contact me for the CVS location of it if you want.

Gravatar for Matthew Montgomery

Matthew Montgomery Says:

@Richard,

Correct, the order of the expressions makes no difference.

Comments are disabled for this post.