2013-08-07 15 views
5

Ich muss einige TIMESTAMP Felder zu INT in unserem MySQL (InnoDB) DB konvertieren. Ich weiß, dass die Umwandlung eines TIMESTAMP in INT ungewöhnlich ist, aber wir müssen es trotzdem tun :)Mysql TIMESTAMP zu INTEGER konvertieren - Zeitzonen

Es scheint einfach genug zu tun, aber es gibt einige Zeitzone und Sommerzeit Fehler.

Ich habe ein Skript, das meinen SQL-Code pro Spalte generiert. Zum Beispiel erzeugt es:

ALTER TABLE alarmLog ADD COLUMN started_tmp INT UNSIGNED; 
UPDATE alarmLog SET started_tmp = UNIX_TIMESTAMP(started); 
ALTER TABLE alarmLog DROP started; 
alter TABLE alarmLog CHANGE started_tmp started INT UNSIGNED NULL DEFAULT 0; 

Wenn ich das vor und nach Daten unter Verwendung von select FROM_UNIXTIME(1291788036); vergleichen zu können, sieht das Ergebnis gut.

Die Idee ist dann, alle clientseitige Software in UTC zu konvertieren und diese INT beim Speichern zu verwenden. Beim Abruf wird dieser INT in die aktuelle Zeitzone konvertiert.

Aber dann warn me die Dokumentation zu diesem Szenario (Sommerzeit in MEZ):

mysql> SELECT UNIX_TIMESTAMP('2005-03-27 02:00:00'); 
+---------------------------------------+ 
| UNIX_TIMESTAMP('2005-03-27 02:00:00') | 
+---------------------------------------+ 
|       1111885200 | 
+---------------------------------------+ 
1 row in set (0.00 sec) 

mysql> SELECT UNIX_TIMESTAMP('2005-03-27 03:00:00'); 
+---------------------------------------+ 
| UNIX_TIMESTAMP('2005-03-27 03:00:00') | 
+---------------------------------------+ 
|       1111885200 | 
+---------------------------------------+ 
1 row in set (0.00 sec) 

Wie API und OS normalerweise mit Tageslichtsparungen umgehen? Ich weiß, dass mein PC seine Uhr in UTC hat und im Sommer, das OS fügt zwei Stunden hinzu, und im Winter eine. Ich nehme an, dass es die UTC-Zeit verwendet, um zu bestimmen, ob es DST ist oder nicht.

Also, wie gehe ich damit um? Ist die einzige Lösung, um der Datenbank ein Feld hinzuzufügen, um den DST-Offset anzugeben?

+1

Sommerzeit ist eine andere Zeitzone. Z.B. CET ist Mitteleuropäische Zeit, MESZ ist Mitteleuropäische Sommerzeit. Ihr Betriebssystem weiß, wann es wechseln soll. Solange Sie UTC für Zeitstempel verwenden, muss die Darstellungsschicht in die lokale Zeit konvertiert werden. –

Antwort

3

Sie müssen die Zeit nicht in INTs speichern. Der TIMESTAMP-Typ von MySQL macht das trotzdem (er verwendet Standard-Unix-Zeitstempel, um die Zeit zu speichern) und sie sind immer in UTC.

Sie müssen nur die Sitzungszeitzone festlegen und alle TIMESTAMP-Spalten werden von/in Ihre Zone konvertiert, wenn Sie sie aktualisieren/auswählen.

Sie können die Zone bei connect/Initialisierungszeit eingestellt einmal:

SET time_zone = '+10:00'; 

Und dann können Sie wählen,/die Zeit in Ihrer Zone

SELECT timesamp_column FROM table ... 

Ich bin nicht sehr vertraut direkt aktualisieren mit datetime libs, aber ich schätze, dass sie die Zeitzone, die du zur Verfügung gestellt hast, und die fragliche Zeit verwenden, um Zeitzonen- und Sommerzeit-Offsets zu bestimmen.

In dem Beispiel, das Sie angegeben haben, denke ich, dass einer der Werte tatsächlich ungültig ist, weil die Uhr von 01:59:59 bis 03:00:00 springen soll und 02:00:00 nie wirklich passiert ist. Die Funktion UNIX_TIMESTAMP gibt in diesem Fall wahrscheinlich die nächste Sekunde zurück.

+0

Ich weiß, dass ich Zeitstempel verwenden kann, aber ich kann diesen Typ nicht verwenden. Die Client-Seite muss mit sqlite kompatibel sein, also also die Konvertierung in INT. Und über die ungültige Zeit; Am Ende der Sommerzeit sparen Sie eine gewisse Zeit zweimal am Tag, was das gleiche Problem hätte. – Halfgaar

+0

Es gibt mehrere Zeitpunkte mit der gleichen String-Darstellung und es gibt auch Lücken. Ich glaube nicht, dass Sie irgendetwas dagegen tun können. Speichern Sie Ihre Werte als Unix-Zeitstempel (INT) und konvertieren Sie sie mit den Funktionen von MySQL oder der Client-Seite der Zeitbibliothek in lokale Zeit. Solange Sie die Zeitzone richtig eingestellt haben, sollte sie korrekt angezeigt werden. – Vatev

+0

Ich habe gerade das Einfügen von '2005-03-27 02:00:00' in eine TIMESTAMP-Spalte getestet. Das Abrufen gibt Ihnen auch "2005-03-27 03:00:00", also denke ich, dass es gut ist. – Halfgaar