Golang JSON Marshal / Unmarshal postgres now()

时间:2014-12-17 03:15:54

标签: json postgresql datetime go

我正在使用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

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:0)

好像你使用了错误的格式。 Postgres使用RFC 3339,它已在time包中定义。 这应该有效:

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