Monthly Archives: February 2012

PHP and date.timezone

Almost everybody has seen the following line:

First, we need to know where this comes from. The reason is simple: The PHP developers don’t trust the system’s timezone settings. Why they don’t trust it – I honestly have no idea. So basically, whenever you set up a new system with PHP, you must set the date.timezone in your php.ini or set the TZ variable – otherwise PHP will spit out that warning each time any PHP script uses date() and related functions.

Some distributions automatically set the timezone; others include a patch which magically guesses the timezone (debian is such a distribution).

If you are an end-user, you are fine with setting date.timezone in your php.ini.

However, if you are a developer who releases PHP apps, you want to make sure that date.timezone is set, in order to help your users to avoid that nasty problem.

However, things aren’t that easy. The warning is triggered when no timezone is set; however, date.timezone isn’t the only location where timezone information can come from.

The timezone can be configured by:

  • date.timezone in your php.ini
  • The TZ environment variable (< PHP 5.4.0)
  • A call to¬†date_default_timezone_set (in the application itself, or by prepending a script)
  • Distribution-specific patches which automatically set the timezone

So, if we want to check if the user has configured the timezone to avoid warnings, checking date.timezone is not enough. Additionally, even if the timezone is set, we don’t know if it is a valid one.

The first thing which came into my mind was: use date_default_timezone_get() to retrieve the timezone, then match it against a list of supported timezones. However, there isn’t a function to retrieve all supported timezones in < PHP 5.2, and I don’t feel manual matching is the way to go.

After quite some experiments and even committing a function which seemed to work in the first place, I realized: There is no good way to actually check if the timezone is set correctly.

So I make things easy and simply test if date.timezone is not empty, and forcefully set the timezone with date_default_timezone_set(). This is not a very good or complete approach, as it virtually skips distribution-related patches and the TZ environment variable.

There’s nothing much we can do; either invent a very fancy method which will probably not work in all environments, or complain to the PHP developers (so that they don’t do the same bullsh$#!! they have done again).