在Postgres中创建的列是:
used_at timestamp with time zone NOT NULL,Postgres中的值保存时不带时区( UTC):
2022-06-30 22:49:03.970913+00使用此查询:
show timezone我得到:
Etc/UTC但是,从Ent (使用pgx stdlib)中,我得到了以下值:
2022-07-01T00:49:03.970913+02:00使用pgdriver/pq,我从DB获得UTC值。
如何设置pgx以获得UTC值?
我也尝试在下面的代码中使用这个连接字符串:
import (
"database/sql"
_ "github.com/jackc/pgx/v4/stdlib"
)
conn, err := sql.Open("pgx", "postgres://postgres:postgres@localhost/project?sslmode=disable&timezone=UTC")
//handle err问题还在这里。
我需要一种方法从DB中获取UTC值(这些值存储在DB中).
发布于 2022-06-27 12:24:24
timezone不是有效的https://www.postgresql.org/docs/14/libpq-connect.html#LIBPQ-PARAMKEYWORDS。
但是,您可以使用options关键字指定命令行选项,以便在连接开始时发送到服务器。请记住,您需要对其中的值进行百分比编码。
如何设置TimeZone的示例
package main
import (
"context"
"fmt"
"github.com/jackc/pgx/v4"
)
func main() {
ctx := context.Background()
c1, err := pgx.Connect(ctx, "postgres:///?sslmode=disable")
if err != nil {
panic(err)
}
defer c1.Close(ctx)
// sends "-c TimeZone=UTC" to server at connection start
c2, err := pgx.Connect(ctx, "postgres:///?sslmode=disable&options=-c%20TimeZone%3DUTC")
if err != nil {
panic(err)
}
defer c2.Close(ctx)
var tz1, tz2 string
if err := c1.QueryRow(ctx, "SHOW timezone").Scan(&tz1); err != nil {
panic(err)
}
if err := c2.QueryRow(ctx, "SHOW timezone").Scan(&tz2); err != nil {
panic(err)
}
fmt.Println(tz1)
fmt.Println(tz2)
}Europe/Prague
UTC但是,这只会强制执行连接的时区,这似乎对pgx在从数据库中读取时间戳时如何解析时间戳本身没有影响。实际上,它似乎直接或间接地依赖于主机的本地时区。确认您可以将全局time.Local变量更新为UTC并观察差异。
// ...
var t1, t2 time.Time
if err := c1.QueryRow(ctx, "select now()::timestamptz").Scan(&t1); err != nil {
panic(err)
}
if err := c2.QueryRow(ctx, "select now()::timestamptz").Scan(&t2); err != nil {
panic(err)
}
fmt.Println(t1)
fmt.Println(t2)
// explicitly set Local to UTC
time.Local = time.UTC
if err := c1.QueryRow(ctx, "select now()::timestamptz").Scan(&t1); err != nil {
panic(err)
}
if err := c2.QueryRow(ctx, "select now()::timestamptz").Scan(&t2); err != nil {
panic(err)
}
fmt.Println(t1)
fmt.Println(t2)
}Europe/Prague
UTC
2022-06-27 17:18:13.189557 +0200 CEST
2022-06-27 17:18:13.190047 +0200 CEST
2022-06-27 15:18:13.190401 +0000 UTC
2022-06-27 15:18:13.190443 +0000 UTC出于明显的原因,我会避免做上面的事情。如果pgx没有提供一种方法来配置它用于解析时间戳的默认位置,那么我可以想到的下一个最佳选项是使用自定义的time.Time类型。
// ...
var t1, t2 time.Time
if err := c1.QueryRow(ctx, "select now()::timestamptz").Scan(&t1); err != nil {
panic(err)
}
if err := c2.QueryRow(ctx, "select now()::timestamptz").Scan(&t2); err != nil {
panic(err)
}
fmt.Println(t1)
fmt.Println(t2)
var tt1, tt2 myTime
if err := c1.QueryRow(ctx, "select now()::timestamptz").Scan(&tt1); err != nil {
panic(err)
}
if err := c2.QueryRow(ctx, "select now()::timestamptz").Scan(&tt2); err != nil {
panic(err)
}
fmt.Println(tt1)
fmt.Println(tt2)
}
type myTime struct {
time.Time
}
func (tt *myTime) Scan(src interface{}) error {
if t, ok := src.(time.Time); ok {
tt.Time = t.In(time.UTC)
return nil
}
return fmt.Errorf("myTime: unsupported type %T", src)
}Europe/Prague
UTC
2022-06-27 17:26:45.94049 +0200 CEST
2022-06-27 17:26:45.940959 +0200 CEST
2022-06-27 15:26:45.941321 +0000 UTC
2022-06-27 15:26:45.941371 +0000 UTChttps://stackoverflow.com/questions/72771272
复制相似问题