Mysql: Convert DB from local time to UTC
I need to convert an existing (datetime fields) db from local time ut UTC.
The va开发者_如何学编程lues are stored ad datetimes on a server with time zone CET (+1) (with summertime +2). When selecting data I use UNIX_TIMESTAMP()
, which magically compensates for everything, ie, time zone shift and dst (if i've read the docs right).
I'm moving the db to a new server with UTC as system time.
Simply subtracting -1 H won't work, as summer time is +2.
Any ideas for a clever way to do this? (using sql or some script lang)
First you need to make sure the mysql.time_zone_name table is populated. If it's empty, you can follow the instructions on this page to populate it:
http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html
It's typically as simple as running a command like this in the shell:
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
Once that table is populated you can use the CONVERT_TZ() function to update the existing values in the DB:
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_convert-tz
Here are two examples to show how it converts datetimes from CET to UTC in winter vs summer:
mysql> SELECT CONVERT_TZ('2010-01-22 12:00:00','CET','UTC');
+-----------------------------------------------+
| CONVERT_TZ('2010-01-22 12:00:00','CET','UTC') |
+-----------------------------------------------+
| 2010-01-22 11:00:00 |
+-----------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT CONVERT_TZ('2010-07-22 12:00:00','CET','UTC');
+-----------------------------------------------+
| CONVERT_TZ('2010-07-22 12:00:00','CET','UTC') |
+-----------------------------------------------+
| 2010-07-22 10:00:00 |
+-----------------------------------------------+
1 row in set (0.00 sec)
It should be noted that the conversion for dates from one timezone to another or to UTC can only be done reliably if the dates are in the past.
Timezone definitions change. They are a human definition of how to deviate from the "sun clock", and those definitions can and do change constantly. So the only valid conversion is for dates in the past, because that will not change anymore.
Any date in the future cannot reliably be converted, because the conversion can only take into account the currently known timezone definition.
Simple example: Let's create a meeting appointment next year in Berlin, Germany. We agree today that we want to meet at 12:00 on July 1st, 2014 at Alexanderplatz. That date would be translated to 10:00 UTC on that day.
Now if some government decides to opt out of daylight saving time in 2014, you'd have a problem deciding whether you should show up at 12:00 local time, or at 11:00 local time, because the conversion back from UTC will result in a different local time.
If you had saved the original date of "2014-07-01 12:00 Europe/Berlin", you will be there at that exact time at noon, like everyone else.
In the original server, you can use one of the following expressions inside an UPDATE query:
CONVERT_TZ(your_datetime_field,'SYSTEM','UTC')
CONVERT_TZ(your_datetime_field,@@global.time_zone,'UTC')
Alternatively, in the destination server, if you know the time zone of the original server (for example 'Europe/Berlin') you can use one of the following expressions:
CONVERT_TZ(your_datetime_field,'Europe/Berlin','UTC')
CONVERT_TZ(your_datetime_field,'Europe/Berlin',@@global.time_zone)
精彩评论