1/3
go
използва база данни за часови зони на IANA
с точни имена на зони. Опит за обратно инженерство как MySQL определя формата на местната часова зона от хост (Linux) и дублиране на тази логика в go
клиентите – както посочи @MattJohnson – се оказва ненадеждни.
2/3
database/sql.DB
- създадено чрез Open(drv, DSN)
- ще използва същия DSN
за всички връзки. Докато sql.DB
е предназначено да се създава веднъж и да се използва много пъти - няма начин да промените DSN
след факта - така че човек ще трябва да създаде чисто нов sql.DB
при промяна на DSN
.
3/3
Така че по-добрият начин изглежда използва MySQL
за да конвертирате всички datetime
стойности от локална до UTC часова зона преди предаване на клиента. Това премахва усложнението при задаване на часовата зона на базата данни (вероятно неизвестна) по време на свързване чрез DSN
.
Една обещаваща опция е да зададете часовата зона на сесията на връзката:
SET @@session.time_zone = "+00:00";
- това обаче работи само за настоящите връзка (в рамките на пула за връзки). A
go
клиентът обаче няма да знае коя безплатна връзка може да използва по всяко време. - Така че, за да сте сигурни, че това винаги работи, ще трябва да го приложите ръчно преди всички заявки . Дори ако се използва само една връзка с DB - ако връзката се провали и се въведе повторен опит - всяко предишно състояние на сесията ще бъде загубено.
Така че вместо това, увийте всички datatime
колони с функция за преобразуване, както следва:
CONVERT_TZ(`STAMP_UPDATED`,@@session.time_zone,'+00:00')
гарантира, че изчисляването на часовата зона се извършва по време на заявка и няма да бъде загубено по време на повторно свързване на връзката и т.н.
Така че сега DSN
вече не е необходимо да посочва loc
- като UTC
е по подразбиране. Всъщност DSN
се нуждае само от опцията за суфикс на ?parseTime=true
за да разрешите datetime
да бъде преведен на go
роден time.Time
.
И накрая и най-важното, това ще работи с всеки сървър, настроен на всяка часова зона.
H/T към този отговор .