Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Pola daty i godziny MySQL i czas letni — jak odnieść się do dodatkowej godziny?

Wymyśliłem to dla moich celów. Podsumuję to, czego się nauczyłem (przepraszam, te notatki są szczegółowe; są tak samo przydatne do mojego przyszłego skierowania, jak wszystko inne).

W przeciwieństwie do tego, co powiedziałem w jednym z moich poprzednich komentarzy, pola DATETIME i TIMESTAMP zrób zachowywać się inaczej. Pola TIMESTAMP (jak wskazują dokumenty) przyjmują wszystko, co je wysyłasz, w formacie „RRRR-MM-DD gg:mm:ss” i konwertują je z bieżącej strefy czasowej na czas UTC. Odwrotna sytuacja dzieje się w sposób przezroczysty za każdym razem, gdy pobierasz dane. Pola DATETIME nie dokonują tej konwersji. Biorą wszystko, co im wyślesz, i po prostu przechowują to bezpośrednio.

Ani pola typu DATETIME, ani TIMESTAMP nie mogą dokładnie przechowywać danych w strefie czasowej, w której obowiązuje czas letni . Jeśli zapiszesz „2009-11-01 01:30:00”, pola nie mają możliwości rozróżnienia, którą wersję 1:30 rano chciałeś — wersję -04:00 lub -05:00.

Ok, więc musimy przechowywać nasze dane w strefie czasowej innej niż czas letni (np. UTC). Pola TIMESTAMP nie są w stanie dokładnie obsłużyć tych danych z powodów, które wyjaśnię:jeśli twój system jest ustawiony na strefę czasową DST, to to, co umieścisz w TIMESTAMP, może nie być tym, co otrzymujesz. Nawet jeśli wyślesz mu dane, które już przekonwertowałeś na UTC, nadal przyjmie, że dane są w Twojej lokalnej strefie czasowej i wykona kolejną konwersję na UTC. Ta wymuszona ZNACZNIKIEM CZASOWYM podróż w obie strony z lokalnego na UTC z powrotem do lokalnego jest stratna, gdy lokalna strefa czasowa przestrzega czasu letniego (od „2009-11-01 01:30:00” mapuje się na 2 różne możliwe czasy).

Dzięki DATETIME możesz przechowywać swoje dane w dowolnej strefie czasowej i mieć pewność, że otrzymasz zwrot tego, co je wyślesz (nie będziesz zmuszony do stratnych konwersji w obie strony, które narzucają ci pola TIMESTAMP). Rozwiązaniem jest więc użycie pola DATETIME i przed zapisaniem w tym polu przekonwertuj ze strefy czasowej systemu na dowolną strefę inną niż DST, w której chcesz ją zapisać (myślę, że UTC jest prawdopodobnie najlepszą opcją). Umożliwia to wbudowanie logiki konwersji w język skryptowy, dzięki czemu można jawnie zapisać odpowiednik czasu UTC „2009-11-01 01:30:00 -04:00” lub „”2009-11-01 01:30:00 -05:00".

Inną ważną rzeczą, na którą należy zwrócić uwagę, jest to, że funkcje matematyczne MySQL dotyczące daty/godziny nie działają poprawnie w granicach czasu letniego, jeśli przechowujesz daty w DST TZ. Tym bardziej więc warto oszczędzać w UTC.

Krótko mówiąc, teraz robię to:

Podczas pobierania danych z bazy danych:

Jawnie interpretuj dane z bazy danych jako UTC poza MySQL, aby uzyskać dokładny uniksowy znacznik czasu. Używam do tego funkcji strtotime() PHP lub jej klasy DateTime. Nie można tego niezawodnie wykonać w MySQL za pomocą funkcji MySQL CONVERT_TZ() lub UNIX_TIMESTAMP(), ponieważ CONVERT_TZ wypisze tylko wartość „RRRR-MM-DD gg:mm:ss”, która ma problemy z niejednoznacznością, a UNIX_TIMESTAMP() przyjmuje jej wejście jest w strefie czasowej systemu, a nie w strefie czasowej, w której dane faktycznie były przechowywane (UTC).

Podczas przechowywania danych w bazie danych:

Konwertuj swoją datę na dokładny czas UTC, którego potrzebujesz poza MySQL. Na przykład:za pomocą klasy PHP DateTime możesz określić „2009-11-01 1:30:00 EST” wyraźnie od „2009-11-01 1:30:00 EDT”, a następnie przekonwertować to na UTC i zapisać poprawny czas UTC do pola DATETIME.

Uff. Dziękuję bardzo za wkład i pomoc wszystkich. Mam nadzieję, że oszczędzi to komuś innego bólu głowy.

BTW, widzę to w MySQL 5.0.22 i 5.0.27



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PyMySQL nie może połączyć się z MySQL na hoście lokalnym

  2. Jak działa funkcja LTRIM() w MySQL

  3. Jak mogę WYBRAĆ wiersze z MAX (wartość kolumny), PARTITION według innej kolumny w MYSQL?

  4. Instrukcja VALUES w MySQL

  5. Problem z Javą + Mysql UTF8