1/3
go
bruger IANAs tidszonedatabase
med præcise zonenavne. Prøver at lave omvendt udvikling af, hvordan MySQL bestemmer det lokale tidszoneformat fra en (Linux) vært og duplikere denne logik i en go
klienter - som @MattJohnson påpegede - viser sig at være upålidelige.
2/3
database/sql.DB
- oprettet via Open(drv, DSN)
- vil bruge den samme DSN
for alle forbindelser. Mens en sql.DB
er beregnet til at blive oprettet én gang og brugt mange gange - der er ingen måde at ændre DSN
bagefter - så man bliver nødt til at oprette en helt ny sql.DB
når du ændrer DSN
.
3/3
Så jo bedre tak, ser ud til at udnytte MySQL
for at konvertere alle datetime
værdier fra lokal til UTC tidszone før transmission til klienten. Dette fjerner komplikationen ved at indstille databasens (muligvis ukendte) tidszone på forbindelsestidspunktet via DSN
.
En lovende mulighed er at indstille forbindelsens sessionstidszone:
SET @@session.time_zone = "+00:00";
- dette virker dog kun for den aktuelle forbindelse (inden for tilslutningspuljen). En
go
klienten vil dog ikke vide, hvilken gratis forbindelse de kan bruge på et givet tidspunkt. - Så for at sikre, at dette altid virker, skal man anvende det manuelt før alle forespørgsler . Selvom kun én DB-forbindelse er i brug - hvis forbindelsen mislykkes, og forbindelsen starter igen - ville enhver tidligere sessionstilstand gå tabt.
Så i stedet indpakkes al datatime
kolonner med en konverteringsfunktion som sådan:
CONVERT_TZ(`STAMP_UPDATED`,@@session.time_zone,'+00:00')
sikrer, at tidszoneberegningen udføres på forespørgselstidspunktet og ikke vil gå tabt under en genforbindelse af forbindelse osv.
Så nu DSN
behøver ikke længere at angive loc
- som UTC
er standard. Faktisk DSN
behøver kun suffiksindstillingen ?parseTime=true
for at tillade datetime
skal oversættes til go
s oprindelige time.Time
.
Endelig og vigtigst af alt, vil dette fungere med enhver server indstillet til enhver tidszone.
H/T til dette svar .