I very much dislike magic numbers. If your code contains something in the realm of:

if ($some_flag == 1)

You’re probably doing it wrong. What is 1? Likely not much more than an arbitrary number you created to symbolize a status. It could mean something in boolean, but the type of example I’m talking here is only boolean to a human. PHP or any language will see that as an integer. If that’s the case, then use constants. Your code really should instead look like:

if ($some_flag == Some_Class::ENABLED)

No magic number, and easily changeable when you come back to this in the future. However even worse, are magic strings. I saw this the other day and absolutely hated it, but on first glance couldn’t think of a better alternative:

if ($date_field == '0000-00-00 00:00:00')

This string of zeros is how MySQL will store a not null / not specified date field. For a myriad of reasons, having this string in your code is dangerous. Prone to typos, changes, and far too DBMS specific. After playing with data conversions and other miscellaneous date functions, here’s what I came up with and will call the “proper” way:

if ( (int) strtotime($date_field) > 0)

The date function strtotime() will return a negative number when given ’0000-00-00 00:00:00′. That’s good, but we want to be even more thorough than this. If $date_field were a string or null or anything strtotime() cannot deal with, it returns false. False cannot be compared to zero, but the integer value of it sure can. Hence the (int) data conversion.

The zero date string will come back negative, something invalid will came back false and convert to zero. If a valid date string was given, it will be a positive integer. Desired result achieved without the use of arbitrary numbers or strings. This method isn’t perfect, strtotime()’s powerful ability to convert strings like “tomorrow” could produce some pretty undesired results, but you should be expecting a date in this case anyway. You definitely have other problems if a rogue string that can be parsed by strtotime() gets passed in here.

Tagged with:
 

2 Responses to Better detecting of MySQL’s “0000-00-00 00:00:00″ in a string

  1. Cam C says:

    Hey Rich,

    Nice write up here.
    I came across it while searching for a solution of the:

    strtotime('0000-00-00 00:00:00') === false

    issue for a 64-bit machine.
    Your solution has a flaw in it.
    Any date prior to 1970-01-01 00:00:00 GMT will thought of as a bad date.
    strtotime converts anything prior to epoch as a negative number.

    Of course, if you’re only checking future dates this should work just fine.

    Just a heads up for anyone that implements your solution.

  2. rich says:

    That’s a really good point that I completely missed. Date checking like this (for the stuff I work on at least) is usually in logging, where that’s not a concern. Going to think on that.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Set your Twitter account name in your settings to use the TwitterBar Section.