views:

368

answers:

1

Setup: Multiple sites on Django on the same set of servers, being served by the same group of Apache processes. Some sites are Eastern TZ; some are Central. Database is PSQL running on a separate server.

When I started, I didn't put much thought into how the various sites would handle timezones; I guess I saw the TIMEZONE setting in Django and just figured it'd 'handle it'. Now I'm seeing the cracks.

First problem: The timezone seems to flip back and forth between Eastern and Central. My understanding of that from searching around on this site are that it's because the os environ var for TZ gets set to the Apache process depending on which Django site it's handling a request for, and if that process then handles a request for a site on another TZ, the timezone is wrong. I believe the solution I found here was that sites of different timezones need to have different process groups serving them. Please correct if wrong.

Second problem: Locally on Linux, I did a ./manage.py runserver from one of my sites with Central time (I'm in Eastern). I created an asset, whose publish date correctly displayed as one hour behind in the admin. Looking at the actual PostgresSQL entry, the publish date's timezone is still listed as -04. Does Postgres just use the timezone of the server/computer itself and ignore any TZ setting in Django? So all entries saved on a Postgres server on Eastern time would show as -04 or -05 depending on Daylight Savings?

If anyone else has dealt with something like this, advice is appreciated. Even if I split out the Apache processes for the Central sites such that their TZ settings don't cross, I still have the Postgres problem to deal with. And then I'm curious; if the PSQL timestamp is Central, and the TZ setting is Eastern, say, do the datetime fields take TZ into account? i.e., if you do datetime.datetime.now() when Django is set to EST, and it returns 2:00 PM, then you have it filter content by its publish date being less than that result, would it account for TZ by only looking for content whose publish time was 1:00PM CST or earlier?

+1  A: 

Here are some details on time zone handling in Django and Postgres, but I strongly recommend dealing exclusively with UTC on the backend and only converting to a local time zone in the frontend when presenting a UTC timestamp to a user. In Python, you can get the current time in UTC via datetime.datetime.utcnow(). I even put my servers in the UTC time zone, but that isn't strictly necessary.

Multiple time zones don't work well in Django; see this ticket. The datetime objects in the Python standard library are time zone naive, and you need a library like pytz to fix that, but as far as I know Django still returns naive datetime objects, not the time zone aware ones that you can construct with pytz.

Postgres will check several places to determine the time zone, including the TZ environment variable, but TZ will have to be in the environment of the postgres process:

PostgreSQL 8.5.3. Time Zones

If timezone is not specified in postgresql.conf nor as a postmaster command-line switch, the server attempts to use the value of the TZ environment variable as the default time zone. If TZ is not defined or is not any of the time zone names known to PostgreSQL, the server attempts to determine the operating system's default time zone by checking the behavior of the C library function localtime(). The default time zone is selected as the closest match among PostgreSQL's known time zones.

Luke Stebbing