1/3
go
sử dụng Cơ sở dữ liệu múi giờ
của IANA với tên vùng chính xác. Cố gắng thiết kế ngược lại cách MySQL xác định định dạng múi giờ cục bộ từ máy chủ (Linux) và sao chép logic đó trong go
khách hàng - như @MattJohnson đã chỉ ra - được chứng minh là không đáng tin cậy.
2/3
database/sql.DB
- được tạo qua Open(drv, DSN)
- sẽ sử dụng cùng một DSN
cho tất cả các kết nối. Trong khi một sql.DB
được tạo một lần và được sử dụng nhiều lần - không có cách nào để thay đổi DSN
sau thực tế - vì vậy người ta sẽ cần tạo một sql.DB
hoàn toàn mới khi thay đổi DSN
.
3/3
Vì vậy, chiến thuật tốt hơn, dường như tận dụng MySQL
để chuyển đổi tất cả datetime
giá trị từ địa phương đến múi giờ UTC trước khi truyền đến máy khách. Điều này loại bỏ sự phức tạp của việc đặt múi giờ (có thể không xác định) của cơ sở dữ liệu tại thời điểm kết nối thông qua DSN
.
Một tùy chọn đầy hứa hẹn là đặt múi giờ phiên của kết nối:
-
SET @@session.time_zone = "+00:00";
- tuy nhiên, điều này chỉ hoạt động cho hiện tại kết nối (trong nhóm kết nối). Một
go
Tuy nhiên, khách hàng sẽ không biết họ có thể sử dụng kết nối miễn phí nào bất cứ lúc nào. - Vì vậy, để đảm bảo điều này luôn hoạt động, người ta cần phải áp dụng nó theo cách thủ công trước tất cả các truy vấn . Ngay cả khi chỉ có một kết nối DB đang được sử dụng - nếu kết nối không thành công và kết nối bắt đầu thử lại - mọi trạng thái phiên trước đó sẽ bị mất.
Vì vậy, thay vào đó, hãy gói tất cả datatime
các cột có chức năng chuyển đổi như vậy:
CONVERT_TZ(`STAMP_UPDATED`,@@session.time_zone,'+00:00')
đảm bảo việc tính toán múi giờ được thực hiện tại thời điểm truy vấn và sẽ không bị mất trong quá trình kết nối lại kết nối, v.v.
Vì vậy, bây giờ DSN
không cần chỉ định loc
nữa - dưới dạng UTC
là mặc định. Trên thực tế, DSN
chỉ cần tùy chọn hậu tố của ?parseTime=true
để cho phép datetime
được dịch sang go
time.Time
gốc của .
Cuối cùng và quan trọng nhất, điều này sẽ hoạt động với bất kỳ máy chủ nào được đặt thành bất kỳ múi giờ nào.
H / T cho câu trả lời này .