I’m in the process of setting up a Zinnia blog on one of my Django sites. After putting all of the necessary plumbing in place I got the following message on first visiting the blog URL:
Database returned an invalid value in QuerySet.datetimes(). Are time zone definitions for your database and pytz installed?
The solution to this is to copy your system’s time zone information across to the database.
Creating the Time Zone Tables
There’s a MySQL tool to do precisely this: mysql_tzinfo_to_sql
. You just need to pass it the path to your system’s zoneinfo
database. On my Ubuntu system the appropriate path is /usr/share/zoneinfo/
.
The following command will read the contents of your system’s zoneinfo
database, transform it into SQL statements and execute them in MySQL. You’ll need to provide the password for the root
MySQL user.
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
You can just specify a single time zone, but it makes sense to me to simply load up the entire gamut.
The result is a set of tables in the mysql
database.
mysql> SELECT * FROM time_zone LIMIT 10;
+--------------+------------------+
| Time_zone_id | Use_leap_seconds |
+--------------+------------------+
| 1 | N |
| 2 | N |
| 3 | N |
| 4 | N |
| 5 | N |
| 6 | N |
| 7 | N |
| 8 | N |
| 9 | N |
| 10 | N |
+--------------+------------------+
10 rows in set (0.00 sec)
mysql> SELECT * FROM time_zone_name LIMIT 10;
+--------------------+--------------+
| Name | Time_zone_id |
+--------------------+--------------+
| Africa/Abidjan | 1 |
| Africa/Accra | 2 |
| Africa/Addis_Ababa | 3 |
| Africa/Algiers | 4 |
| Africa/Asmara | 5 |
| Africa/Asmera | 6 |
| Africa/Bamako | 7 |
| Africa/Bangui | 8 |
| Africa/Banjul | 9 |
| Africa/Bissau | 10 |
+--------------------+--------------+
10 rows in set (0.00 sec)
mysql> SELECT * FROM time_zone_transition LIMIT 10;
+--------------+-----------------+--------------------+
| Time_zone_id | Transition_time | Transition_type_id |
+--------------+-----------------+--------------------+
| 1 | -2147483648 | 0 |
| 1 | -1830383032 | 1 |
| 2 | -2147483648 | 0 |
| 2 | -1640995148 | 2 |
| 2 | -1556841600 | 1 |
| 2 | -1546388400 | 2 |
| 2 | -1525305600 | 1 |
| 2 | -1514852400 | 2 |
| 2 | -1493769600 | 1 |
| 2 | -1483316400 | 2 |
+--------------+-----------------+--------------------+
10 rows in set (0.00 sec)
mysql> SELECT * FROM time_zone_transition_type LIMIT 10;
+--------------+--------------------+--------+--------+--------------+
| Time_zone_id | Transition_type_id | Offset | Is_DST | Abbreviation |
+--------------+--------------------+--------+--------+--------------+
| 1 | 0 | -968 | 0 | LMT |
| 1 | 1 | 0 | 0 | GMT |
| 2 | 0 | -52 | 0 | LMT |
| 2 | 1 | 1200 | 1 | +0020 |
| 2 | 2 | 0 | 0 | GMT |
| 3 | 0 | 8836 | 0 | LMT |
| 3 | 1 | 10800 | 0 | EAT |
| 3 | 2 | 9000 | 0 | +0230 |
| 3 | 3 | 9900 | 0 | +0245 |
| 3 | 4 | 10800 | 0 | EAT |
+--------------+--------------------+--------+--------+--------------+
10 rows in set (0.00 sec)
MySQL Server Time Zone
You can check the time zone that’s configured for your MySQL server as follows:
mysql> SELECT @@time_zone;
+-------------+
| @@time_zone |
+-------------+
| SYSTEM |
+-------------+
1 row in set (0.00 sec)
My MySQL server is using the same time zone as the system. We can lock that down by configuring a specific time zone for MySQL. Add the following to the end of /etc/mysql/my.cnf
.
[mysqld]
default-time-zone = 'UTC'
Now restart MySQL.
sudo service mysql restart
And check for the server time zone.
mysql> SELECT @@time_zone;
+-------------+
| @@time_zone |
+-------------+
| UTC |
+-------------+
1 row in set (0.00 sec)
Sorted.