1/3
go
gebruikt IANA's Tijdzonedatabase
met precieze zonenamen. Proberen te reverse-engineeren hoe MySQL het lokale tijdzoneformaat van een (Linux) host bepaalt en die logica dupliceren in een go
klanten - zoals @MattJohnson opmerkte - blijkt onbetrouwbaar te zijn.
2/3
database/sql.DB
- gemaakt via Open(drv, DSN)
- gebruikt dezelfde DSN
voor alle aansluitingen. Terwijl een sql.DB
is bedoeld om één keer te worden gemaakt en vele malen te worden gebruikt - er is geen manier om de DSN
te wijzigen achteraf - dus men zou een geheel nieuwe sql.DB
moeten maken bij het wijzigen van de DSN
.
3/3
Dus de betere tack lijkt gebruik te maken van MySQL
om alle datetime
te converteren waarden van lokaal naar UTC-tijdzone voordat ze naar de client worden verzonden. Dit verwijdert de complicatie van het instellen van de (mogelijk onbekende) tijdzone van de database op verbindingstijd via de DSN
.
Een veelbelovende optie is om de sessietijdzone van de verbinding in te stellen:
SET @@session.time_zone = "+00:00";
- dit werkt echter alleen voor de huidige aansluiting (binnen de aansluitpool). Een
go
de klant weet echter op geen enkel moment welke gratis verbinding ze gebruiken. - Dus om ervoor te zorgen dat dit altijd werkt, moet je het handmatig toepassen vóór alle zoekopdrachten . Zelfs als er slechts één DB-verbinding in gebruik is - als de verbinding mislukt en de verbinding opnieuw wordt geprobeerd - gaat een eerdere sessiestatus verloren.
Dus in plaats daarvan wikkelt u alle datatime
kolommen met een conversiefunctie zoals:
CONVERT_TZ(`STAMP_UPDATED`,@@session.time_zone,'+00:00')
zorgt ervoor dat de tijdzoneberekening wordt uitgevoerd op het moment van de vraag en niet verloren gaat tijdens het opnieuw verbinden van de verbinding enz.
Dus nu de DSN
hoeft niet langer loc
op te geven - als UTC
is de standaard. In feite de DSN
heeft alleen de achtervoegseloptie ?parseTime=true
. nodig om de datetime
. toe te staan te vertalen naar go
's eigen time.Time
.
Ten slotte en vooral, dit werkt met elke server die is ingesteld op elke tijdzone.
H/T naar dit antwoord .