gpt4 book ai didi

database - Go 语言中带时区的时间戳

转载 作者:行者123 更新时间:2023-12-04 16:24:20 25 4
gpt4 key购买 nike

我进行 HTTP 调用并从较大的 json 对象中解码一个 createdTimestamp 字段:

CreatedTimestamp string `json:"createdTimestamp"`

我从 createdTimestamp 的 HTTP 调用中收到的示例是:"2021-07-19T18:51:23" .

它不会自动将其转换为 time.Time所以它真正接受的唯一类型是一个字符串,它在 Postgresql 中的类型更改为 timestamp with timezone 之前一直有效。 < 根据 Postgresql 数据库控制台看起来像这样 > (yyyy-MM-dd HH:mm:ss.ffffff) .和以前一样 without timezone .我能够为 time.Time 实现自定义解码方法对象甚至对其进行格式化,以便我可以输出类似 2021-07-19 18:51:23.+00 的内容但这不会被 postgres 接受。

我在尝试插入它(通过 GoLang、postgres 驱动程序)时看到的确切错误是:pq: invalid input syntax for type timestamp with time zone: "" 在我尝试使用 db.Exec 执行插入后出现此错误-> db类型 *sql.DB .

我正在 Go 中执行此操作,非常感谢任何帮助!

解码 Json 的代码

type CustomTime struct {
time.Time
}

func (ct *CustomTime) UnmarshalJSON(b []byte) (err error) {
timeToInsertIntoDb := strings.Trim(string(b), "\"")
if timeToInsertIntoDb == "null" {
ct.Time = time.Time{}
return
}

timeToInsertIntoDb = timeToInsertIntoDb + "Z"
ct.Time, err = time.Parse(time.RFC3339, timeToInsertIntoDb)
return
}

格式化取决于输出,但我确实收到了任何格式的输出。所以如果我这样做,CustomTime.Time.Format(2006-02-01 15:04:05.-07)我将得到 2021-07-19 18:51:23.+00 的输出

尽管此时,我什至不确定 Timestamp with Timezone 所需的确切格式,没有太多关于 Golang Postgres 驱动程序的文档。

如果需要更多信息,请询问。我正在尽力组织这个问题。

编辑 1


按照建议,我尝试将“Z”附加到 http 调用给出的时间戳。在使用 time.RFC3339 进行解析后, 我的时间是 2021-07-19T18:51:23Z - 这仍然失败(给出了上述相同的语法错误)。使用此解析尝试了几种不同的方法。它按照我上面所说的方式格式化,并用它格式化 .String()给出 2021-07-20 18:51:23 +0000 UTC 的方法.两者都失败了 pq: invalid input syntax for type timestamp with time zone: ""

解码期间的代码更改:

func (ct *CustomTime) UnmarshalJSON(b []byte) (err error) {
timeToInsertIntoDb := strings.Trim(string(b), "\"")
if timeToInsertIntoDb == "null" {
ct.Time = time.Time{}
return
}

timeToInsertIntoDb = timeToInsertIntoDb + "Z"
ct.Time, err = time.Parse(time.RFC3339, timeToInsertIntoDb)
return
}

编辑2

另一件事是我正在使用 "database/sql"包装与 "github.com/lib/pq"作为数据库连接的 Postgres 驱动程序。这就是错误来自 pq 的原因.只是想澄清一下,因为我知道其他人正在使用 gorm。我可以写入其他表,我猜只是这个表具有带有时区 Postgres 列的时间戳。

我正在用 db.Exec("INSERT INTO db (created_timestamp) VALUES ($1)", obj.createdTimestamp.Time 调用电话我试过将它作为一个字符串传递(这是我之前在它工作时所做的)但现在这是我所在的位置,因为人们说最好传递一个 time.Time 变量。

最佳答案

如果您检查提供的时间格式 ctlayout 与时间格式标准非常匹配 RFC3339

const ctLayout = "2006-01-02T15:04:05"
const RFC3339 = "2006-01-02T15:04:05Z07:00"

从这里blogpost .

In RFC 3339, we can also know the time-zone from the format. Itdisplayed in the “Z” syntax. “Z” means UTC+0. “Z” stands for Zulutimezone which is the same with GMT or UTC(https://stackoverflow.com/a/9706777/4075313). So if we put Z on theDateTime, it’s mean its timezone is UTC+0.

如果我们更改传入时间并在末尾附加 'Z',则应该满足时间解析器的要求。

这是重构代码。您可以在 playground 上找到工作代码.

        timeToInsertInDB := "2006-01-02T15:04:05" + "Z"

testTime, err := time.Parse(time.RFC3339, timeToInsertInDB)
if err != nil {
fmt.Println(err)
}

注意:- 更详细的时区示例

2019-10-12T07:20:50.52Z      (UTC+0)
2019-10-12T07:20:50.52+00:00 (UTC+0)
2019-10-12T14:20:50.52+07:00 (UTC+7)
2019-10-12T03:20:50.52-04:00 (UTC-4)

postgres 驱动程序需要 time.Time。如果解析成功,驱动程序应该能够插入数据库并解码模型结构中的响应。在 playground 上查看此示例.

编辑1

根据 OP 的编辑,我更改了使用的驱动程序我尝试使用 database/sql 包和 github.com/lib/pq 但无法重现问题.插入和选择工作完全正常。 playground

正如 Brits 所提到的,这很可能是您代码中的逻辑错误(但由于您尚未共享代码,因此无法确认这一点)。

关于database - Go 语言中带时区的时间戳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68506136/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com