1/3
go
používá databázi časových pásem
IANA s přesnými názvy zón. Snažíme se zpětně analyzovat, jak MySQL určuje formát místního časového pásma z hostitele (Linux) a duplikovat tuto logiku v go
klienti – jak zdůraznil @MattJohnson – se ukázali jako nespolehliví.
2/3
database/sql.DB
- vytvořeno pomocí Open(drv, DSN)
- bude používat stejné DSN
pro všechna připojení. Zatímco sql.DB
je určen k tomu, aby byl vytvořen jednou a použit mnohokrát - neexistuje způsob, jak změnit DSN
po faktu - takže by bylo potřeba vytvořit zbrusu nový sql.DB
při změně DSN
.
3/3
Zdá se tedy, že lepší připojení využívá MySQL
pro převod všech datetime
hodnoty z místního časového pásma na časové pásmo UTC před přenosem klientovi. Tím se odstraní komplikace s nastavováním (možná neznámého) časového pásma databáze v době připojení prostřednictvím DSN
.
Jednou slibnou možností je nastavení časového pásma relace připojení:
SET @@session.time_zone = "+00:00";
- toto však funguje pouze pro aktuální připojení (v rámci fondu připojení).
go
klient však nebude vědět, jaké bezplatné připojení může používat. - Aby to vždy fungovalo, bylo by nutné jej použít ručně před všemi dotazy . I když se používá pouze jedno připojení k databázi – pokud se připojení nezdaří a dojde k opakování připojení – jakýkoli předchozí stav relace bude ztracen.
Místo toho zabalte všechny datatime
sloupce s konverzní funkcí, jako je tato:
CONVERT_TZ(`STAMP_UPDATED`,@@session.time_zone,'+00:00')
zajišťuje, že výpočet časového pásma bude proveden v době dotazu a nebude ztracen během opětovného připojení atd.
Takže teď DSN
již není třeba zadávat loc
- jako UTC
je výchozí. Ve skutečnosti DSN
potřebuje pouze možnost přípony ?parseTime=true
povolit datetime
být přeložen do go
nativní time.Time
.
A konečně a to nejdůležitější, bude to fungovat s jakýmkoli serverem nastaveným na jakékoli časové pásmo.
H/T na tuto odpověď .