2013-08-07 31 views
5

Potrzebuję przekonwertować niektóre pola TIMESTAMP na INT w naszym DB MySQL (InnoDB). Zdaję sobie sprawę, że konwersja TIMESTAMP na INT jest niezwykła, ale wciąż musimy to zrobić :)Konwersja TIMESTAMP na INTEGER Mysql - timezones

Wydaje się dość proste, ale są pewne błędy związane ze strefą czasową i czasem letnim.

Mam skrypt, który generuje mój kod SQL na kolumnę. Na przykład, generuje:

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; 

Jeśli porównać przed i po danych z wykorzystaniem select FROM_UNIXTIME(1291788036);, wynik wygląda dobrze.

Chodzi o to, aby zmienić całe oprogramowanie po stronie klienta, aby przekonwertować na UTC i użyć tej INT podczas zapisywania. Podczas pobierania ta INT jest konwertowana na bieżącą strefę czasową.

ale potem docs warn me o tym scenariuszu (letniego w CET):

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) 

Jak API i systemów operacyjnych zwykle zajmują się letni? Wiem, że mój komputer ma swój zegar w UTC, a latem system operacyjny dodaje dwie godziny, a zimą jeden. Zakładam, że używa czasu UTC do ustalenia, czy jest to czas letni, czy nie.

Jak sobie z tym poradzić? Czy jedynym rozwiązaniem jest dodanie pola do bazy danych w celu określenia przesunięcia czasu letniego?

+1

Czas letni to inna strefa czasowa. Na przykład. CET to czas środkowoeuropejski, CEST to środkowoeuropejski czas letni. Twój system operacyjny wie kiedy się przełączyć. Dopóki używasz UTC do sygnatur czasowych, to do warstwy prezentacji należy przekonwertować ją na czas lokalny. –

Odpowiedz

3

Nie musisz przechowywać czasu w INT. Typ TIMESTAMP MySQL robi to mimo to (używa standardowych znaczników czasu unix do przechowywania czasu) i zawsze jest w UTC.

Musisz jedynie ustawić strefę czasową sesji, a wszystkie kolumny TIMESTAMP zostaną przekonwertowane z/do twojej strefy po ich zaktualizowaniu/wybraniu.

Można ustawić strefę w czasie połączenia/inicjalizacji kiedyś:

SET time_zone = '+10:00'; 

a następnie można wybrać/aktualizacji czasu w swojej strefie bezpośrednio

SELECT timesamp_column FROM table ... 

nie jestem bardzo obeznany z datetime libs, ale myślę, że używają strefy czasowej, którą podałeś, i czasu, o którym mówisz, do określenia przesunięć czasowych i czasu letniego.

W podanym przykładzie myślę, że jedna z wartości jest rzeczywiście nieprawidłowa, ponieważ zegar ma przeskakiwać od 01:59:59 do 03:00:00 i 02:00:00 nigdy się nie wydarzył. Funkcja UNIX_TIMESTAMP prawdopodobnie zwróci najbliższą sekundę w takim przypadku.

+0

Wiem, że mogę używać znaczników czasu, ale nie mogę używać tego typu. Strona kliencka musi być zgodna z sqlite, a więc konwersja do INT. A także o nieważnym czasie; na koniec dnia zaoszczędzisz trochę czasu dwa razy dziennie, co miałoby ten sam problem. – Halfgaar

+0

Istnieje wiele punktów w czasie z tym samym ciągiem znaków i są również przerwy. Nie sądzę, żeby cokolwiek można z tym zrobić. Przechowuj swoje wartości jako unixowe sygnatury czasowe (INT) i zamień je na czas lokalny za pomocą funkcji MySQL lub po stronie klienta biblioteki czasu. Dopóki poprawnie ustawisz strefę czasową, powinna ona być wyświetlana poprawnie. – Vatev

+0

Właśnie testowałem wstawianie "2005-03-27 02:00:00" w kolumnie TIMESTAMP. Pobieranie go również daje "2005-03-27 03:00:00", więc myślę, że to w porządku. – Halfgaar