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í).
goklient 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ěď .