I allow my users to add events to my webapp. Users can originate from all around the world.
My current idea is to determine the user's time zone automatically (using an IP to location API) and insert it into the users table (I will also allow them to change it).
On the events table I will insert the event start date/end date in UTC.
Then, whenever I need to display the event info, I would take the event start date/end date from the table and do the calculation against the user's timezone.
Is that considered as good practice or is there a better way to do that?
Anything I should be aware of when doing this?
Thanks,
Yes, that is indeed a good way. Also keep in mind that if you use the TIMESTAMP
type in MySQL, MySQL handles the timezone converting for you. When you insert new dates/times to the database, MySQL converts it from the connection's timezone to UTC (TIMESTAMP
is always stored in UTC). When you retrieve a TIMESTAMP
field from database, MySQL converts it back to the connection's timezone.
So if you use TIMESTAMP
fields in MySQL, all you need to do is tell the user's timezone to MySQL at start of each your page. You do so by:
SET time_zone = 'Europe/Helsinki'
You can also use numeric timezones:
SET time_zone = '+02:00'
Keep in mind that you might need to install the tzinfo to MySQL first, which is trivial though (only for the non-numeric version though). Here's information about how to do it: http://dev.mysql.com/doc/refman/5.0/en/mysql-tzinfo-to-sql.html
In a nutshell, this is the important part:
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
Here's an example of how it works:
mysql> CREATE TEMPORARY TABLE test(foo TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)
mysql> SET time_zone = '+00:00';
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO test VALUES ('2011-02-03 16:00:00');
Query OK, 1 row affected (0.00 sec)
mysql> SET time_zone = '+02:00';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT foo FROM test;
+---------------------+
| foo |
+---------------------+
| 2011-02-03 18:00:00 |
+---------------------+
1 row in set (0.00 sec)
If you don't use TIMESTAMP
field, eg. you use DATETIME
(which also supports wider range of dates), then you just need to make sure you always insert dates in UTC; I do this by always setting connection's timezone to +00:00
. Then you can have a view helper in PHP that converts the datetime to the user's timezone, which is quite trivial to do with PHP's DateTime class and setTimezone function. There's an example in the last link. To use this method, you must make sure PHP is also set to use UTC as its default timezone, which you can do with this:
date_default_timezone_set('UTC');
Whichever method you use, you should always be aware of these facts:
TIMESTAMP
and DATETIME
types with each otherTIMESTAMP
type, set the timezone to the user's timezoneDATETIME
type, set the timezone to UTC and handle timezone convertions in PHPFew thing I would consider:
This way hopefully they won't miss anything :) Good luck with your webapp!