2010-04-22 8 views
11

Ho bisogno di convertire un db esistente (datetime fields) dall'ora locale UTC UT.Mysql: Converti DB dall'ora locale a UTC

I valori vengono archiviati ad un orario datato su un server con fuso orario CET (+1) (con ora legale +2). Quando si selezionano i dati, utilizzo UNIX_TIMESTAMP(), che risarcisce magicamente tutto, vale a dire lo spostamento del fuso orario e il dst (se ho letto bene i documenti).

Sto spostando il DB su un nuovo server con UTC come ora di sistema.

Semplicemente sottrarre -1 H non funziona, poiché l'ora legale è +2.

Qualche idea per un modo intelligente di farlo? (usando sql o qualche lang di script)

risposta

23

Prima di tutto è necessario assicurarsi che la tabella mysql.time_zone_name sia popolata. Se è vuoto, è possibile seguire le istruzioni in questa pagina per popolarlo:

http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html

E 'in genere semplice come l'esecuzione di un comando come questo nella shell:

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql 

Una volta che la tabella è popolato è possibile utilizzare la funzione di CONVERT_TZ() per aggiornare i valori esistenti nel DB:

http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_convert-tz

Ecco due esempi per mostrare come converte datetimes dal CET di UTC in inverno vs estate:

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) 
+0

Ciao, so che è passato un po 'di tempo da quando hai risposto, ma per qualche ragione che l'istruzione select non funziona per me ... Ho controllato il documento e sono in grado di ottenere 'SELECT CONVERT_TZ (' 2004-01-01 12 : 00: 00 ',' + 00:00 ',' + 10:00 '); ', ma non quello che hai descritto sopra ... c'è qualcosa che mi manca? Continuo a ricevere nulla per questo. – KVISH

+3

@kalvish, probabilmente è sufficiente compilare la tabella mysql.time_zone_name. Prova a eseguire questo comando nella shell per popolare quella tabella: 'mysql_tzinfo_to_sql/usr/share/zoneinfo | mysql -u root mysql' –

+0

SELECT CONVERT_TZ ('2017-02-15 08:00:00', "UTC", "CST"); return null – wyx

5

Si deve notare che la conversione per le date da un fuso orario all'altro o UTC può essere fatto solo in modo affidabile se le date sono nel passato.

Le definizioni del fuso orario cambiano. Sono una definizione umana di come deviare dal "sun clock", e queste definizioni possono cambiare continuamente. Quindi l'unica conversione valida è per le date in passato, perché non cambierà più.

Qualsiasi data futura non può essere convertita in modo affidabile, poiché la conversione può prendere in considerazione solo la definizione del fuso orario attualmente nota.

Semplice esempio: creiamo un appuntamento per l'incontro l'anno prossimo a Berlino, in Germania. Siamo d'accordo oggi che vogliamo incontrarci alle 12:00 il 1 ° luglio 2014 ad Alexanderplatz. Quella data sarebbe stata tradotta alle 10:00 UTC in quel giorno.

Ora, se alcuni governi decidono di rinunciare all'ora legale nel 2014, avresti un problema nel decidere se dovresti presentarti alle 12:00 ora locale o alle 11:00 ora locale, perché la conversione è tornata da UTC si tradurrà in un orario locale diverso.

Se avevate salvato la data originale di "2014-07-01 12:00 Europa/Berlino", sarete lì a quell'ora esatta a mezzogiorno, come tutti gli altri.

2

Nel server originale, è possibile utilizzare una delle seguenti espressioni all'interno di una query UPDATE:

CONVERT_TZ(your_datetime_field,'SYSTEM','UTC') CONVERT_TZ(your_datetime_field,@@global.time_zone,'UTC')

In alternativa, nel server di destinazione, se si conosce il fuso orario del server originale (ad esempio 'Europe/Berlin') è possibile utilizzare una delle seguenti espressioni:

CONVERT_TZ(your_datetime_field,'Europe/Berlin','UTC') CONVERT_TZ(your_datetime_field,'Europe/Berlin',@@global.time_zone)