1/3
go
korzysta z bazy danych stref czasowych
z dokładnymi nazwami stref. Próba odtworzenia sposobu, w jaki MySQL określa lokalny format strefy czasowej z hosta (Linux) i powiela tę logikę w go
klientów - jak zauważył @MattJohnson - okazuje się nierzetelny.
2/3
database/sql.DB
- utworzony przez Open(drv, DSN)
- użyje tego samego DSN
dla wszystkich połączeń. Podczas gdy sql.DB
ma być tworzony raz i używany wiele razy - nie ma możliwości zmiany DSN
po fakcie - więc trzeba by stworzyć zupełnie nowy sql.DB
podczas zmiany DSN
.
3/3
Więc lepsza taktyka, wydaje się wykorzystywać MySQL
przekonwertować wszystkie datetime
wartości od strefy czasowej lokalnej do UTC przed transmisją do klienta. Usuwa to komplikację ustawiania strefy czasowej bazy danych (prawdopodobnie nieznanej) w czasie połączenia za pośrednictwem DSN
.
Jedną z obiecujących opcji jest ustawienie strefy czasowej sesji połączenia:
SET @@session.time_zone = "+00:00";
- jednak działa to tylko dla bieżącego połączenie (w ramach puli połączeń).
go
klient jednak nie będzie wiedział, z którego bezpłatnego połączenia może korzystać w danym momencie. - Aby mieć pewność, że to zawsze działa, należy zastosować je ręcznie przed wszystkimi zapytaniami . Nawet jeśli używane jest tylko jedno połączenie z bazą danych - jeśli połączenie się nie powiedzie i nastąpi ponowna próba połączenia - wszelkie poprzednie stany sesji zostaną utracone.
Więc zamiast tego, zawijanie całego datatime
kolumny z funkcją konwersji, jak na przykład:
CONVERT_TZ(`STAMP_UPDATED`,@@session.time_zone,'+00:00')
zapewnia, że obliczenia strefy czasowej są wykonywane w czasie zapytania i nie zostaną utracone podczas ponownego połączenia itp.
Więc teraz DSN
nie trzeba już określać loc
- jako UTC
jest wartością domyślną. W rzeczywistości DSN
potrzebuje tylko opcji sufiksu ?parseTime=true
aby zezwolić na datetime
do przetłumaczenia na go
natywny time.Time
.
Wreszcie, co najważniejsze, będzie to działać z dowolnym serwerem ustawionym na dowolną strefę czasową.
H/T do tej odpowiedzi .