【问题标题】:Golang JSON Marshal/Unmarshal postgres now()Golang JSON Marshal/Unmarshal postgres now()
【发布时间】:2014-12-17 03:15:54
【问题描述】:

我使用 postgres 的 now() 作为我的 created 时间戳的默认值,它会生成这个:

 id | user_id | title | slug | content |          created           
----+---------+-------+------+---------+----------------------------
  1 |       1 | Foo   | foo  | bar     | 2014-12-16 19:41:31.428883
  2 |       1 | Bar   | bar  | whiz    | 2014-12-17 02:03:31.566419

我尝试使用 json.Marshaljson.Unmarshal 并最终收到此错误:

parsing time ""2014-12-16 19:41:31.428883"" as ""2006-01-02T15:04:05Z07:00"": cannot parse " 19:41:31.428883"" as "T"

所以我决定尝试创建一个自定义时间,但似乎没有任何效果。

Post.go

package models

type Post struct {
    Id      int    `json:"id"`
    UserId  int    `json:"user_id"`
    Title   string `json:"title"`
    Slug    string `json:"slug"`
    Content string `json:"content"`
    Created Tick   `json:"created"`
    User    User   `json:"user"`
}

Tick.go

package models

import (
    "fmt"
    "time"
)

type Tick struct {
    time.Time
}

var format = "2006-01-02T15:04:05.999999-07:00"

func (t *Tick) MarshalJSON() ([]byte, error) {
    return []byte(t.Time.Format(format)), nil
}

func (t *Tick) UnmarshalJSON(b []byte) (err error) {
    b = b[1 : len(b)-1]
    t.Time, err = time.Parse(format, string(b))
    return
}

任何帮助将不胜感激,运行我在这里写的内容会给我这个:

json: error calling MarshalJSON for type models.Tick: invalid character '0' after top-level value

【问题讨论】:

  • 查看gobyexample.com/time-formatting-parsing 获取一些示例。您的const format 需要使用参考时间,而不是自定义值。或者,postgres 具有其他时间和日期功能,可能会更好地满足您的需求。
  • @JeremiahWinsley 嘿,谢谢。是的,我在发布几分钟后意识到,但似乎仍然无法让它工作(编辑了问题)。我会看看你的链接,谢谢。

标签: json postgresql datetime go


【解决方案1】:

JSON 要求字符串被引用(在 JSON 中,日期是一个字符串),但是您的 MarshalJSON 函数返回一个未引用的字符串。

我稍微修改了您的代码,现在可以正常工作了:

package models

import (
    "fmt"
    "time"
)

type Tick struct {
    time.Time
}

var format = "2006-01-02T15:04:05.999999-07:00"

func (t *Tick) MarshalJSON() ([]byte, error) {
    // using `append` to avoid string concatenation
    b := make([]byte, 0, len(format)+2)
    b = append(b, '"')
    b = append(b, t.Time.Format(format)...)
    b = append(b, '"')
    return b, nil
}

func (t *Tick) UnmarshalJSON(b []byte) (err error) {
    b = b[1 : len(b)-1]
    t.Time, err = time.Parse(format, string(b))
    return
}

【讨论】:

    【解决方案2】:

    您似乎使用了错误的格式。 Postgres 使用 RFC 3339,它已经在 time 包中定义。 这应该有效:

    time.Parse(time.RFC3339, string(b))
    

    【讨论】:

    • 错误信息明确指出是json抛出错误,所以它与Postgres无关......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    • 1970-01-01
    • 2015-05-13
    • 2023-02-05
    • 2015-03-15
    • 1970-01-01
    相关资源
    最近更新 更多