Why is date() Returning 12/31/1969?

 In PHP, a good sign that something is wrong with your date data or logic is when you start seeing dates displayed as “12/31/1969” (or however you specified the format). Unfortunately, there’s not a one-fits-all solution to that, since it could be caused by any number of things, but ultimately, the root of the matter is that you’re passing an invalid timestamp into date(). So while I can’t answer what’s wrong in your specific code, I can tell you why it is happening.

All about date()

In PHP, the date function takes in a Unix timestamp, then formats it according to the format mask you provide. To display today’s date, you only need to provide a mask, no timestamp, as the timestamp argument will default to the value of time() (as in, right that moment).

In code:

<?php echo date("m/d/Y"); ?>

Which evaluated as [date format="m/d/Y"] when this page loaded.

But when you want to display a date in the past or future, you have to provide a timestamp. A Unix timestamp to be exact.

The Unix timestamp

The Unix timestamp is defined in seconds since the Unix Epoch, otherwise known as January 1, 1970 at 0:00:00 UTC.

In PHP, you can retrieve the timestamp using the time function. In code:

<?php echo time() ?>

Which evaluated as [time] when this page loaded.

In order to get a timestamp value from a time string, such as "2009-09-09", you can use strtotime(), which will try to parse many different types of date strings. Learn more about the strtotime function at in the PHP manual. So if I wanted to use PHP to format that date as something different, say to insert into a MySQL database, I would use code that looks something like:

<?php $date = date("Y-m-d H:i:s",strtotime("09/09/2009")); ?>

Which sets date equal to "2009-09-09 00:00:00".

But when you pass a string to strtotime() that the function can’t parse, or try passing a date string directly to date() instead of a timestamp, date() can’t do anything with the invalid value.

Demystifying 12/31/1969 (or 1/1/1970 for Eastern Hemisphere folk)

Since the Unix timestamp is based off the Unix Epoch, an invalid timestamp defaults to to the Epoch (Thu, 01 Jan 1970 00:00:00 +0000).

But, date() displays the formatted time taking into account the timezone of the server or a timezone set with date_default_timezone_set(), so if your timezone is set to something like America/New_York (-0500), the date will be adjusted, resulting in a time that falls during 31 Dec 1969.

So if your server or script timezone is set to a timezone in the Western Hemisphere, any invalid timestamps will end up displayed as some incarnation of 31 Dec 1969. Likewise, in the Eastern Hemisphere, the date falls on or after the Epoch, resulting in a returned value of 1 Jan 1970.

Like Y2K except worse…

The concept of the Unix Epoch as the basis for time is causing some issues as we get deeper into the new millennium. For 32-bit systems, such as this server and hundreds of thousands (likely millions) of other computerized devices out there, time is finite. The systems will not be able to handle the large integer required to store the date based on the Epoch. When Tue, 19 Jan 2038 03:14:07 UTC rolls around, timestamps will rollover—to a value that equates to Fri, 13 Dec 1901 20:45:54 GMT.

As much as I’d like to travel back in time and see the last few days of Queen Victoria’s reign (oh the fashion!), that rollover will likely bring software systems crashing down. In fact, some systems have already started showing issues if they deal with dates farther than 27 years in the future. Luckily, electronics have been on a steady move toward 64-bit systems that can handle dates up to over 200 billion years in the future, but it’s not unlikely that some 32-bit systems will still be in use when 2038 rolls around even if their manufacture has slowed (or likely stopped).

If you’re trying to pass a perfectly valid date that falls before 13 Dec 1901 or later than 19 Jan 2038 to your PHP script, chances are you’ll see this Epoch error, because the server can’t handle that timestamp.

What’s your favorite 12/31/1969 story? Are you worried about the year 2038?

3 thoughts on “Why is date() Returning 12/31/1969?”

  1. Does this mean that we can toss out the Unix Epoch when everything converts to 64-bit? I hate the Unix Epoch with a passion. So much ridiculous compensating for this garbage. On top of that, there’s no reason date() needs to return the Unix Epoch on an invalid date… just return empty so that it will automatically be set to whatever my database table’s default value is for empty.

Comments are closed.