3

我对 Golang 和 MongoDB 比较陌生,遇到了一个日期问题,我似乎可以将 UTC 日期插入 MongoDB,但是当我通过 Golang 查询时,它会自动转换为本地时间。我想在 UTC 中从 MongoDB 中取回它而无需转换。这是一个简单的例子:

type SampleItem struct {
    ObjId      bson.ObjectId `bson:"_id,omitempty" json:"-"`
    SampleDate time.Time     `bson:"sampleDate" json:"sampleDate"`
}

func TestMe() {

    var item SampleItem
    var items []SampleItem

    sess := getSession()
    defer sess.Close()

    item.SampleDate = time.Now().UTC()
    fmt.Printf("%s\n", item.SampleDate)

    collection := sess.DB("myCollection").C("sampleItems")
    collection.Insert(item)

    err := collection.Find(bson.M{}).All(&items)
    if err == nil {
        fmt.Printf("%s\n", items[0].SampleDate)
    }
}

我的输出:

2014-10-12 04:10:50.3992076 +0000 UTC

2014-10-11 23:10:50.399 -0500 CDT

似乎 mgo 驱动程序可能会自动转换它,因为当我从控制台窗口查询 mongodb 时,我的日期是 UTC。我是否错过了某个关闭此功能的 mgo 选项?

4

2 回答 2

8

Go time.Time值存储时间和位置的瞬间。mgo BSON 解码器将位置设置为time.Local

您可以设置time.Local为 UTC 位置:

time.Local = time.UTC

为第三方使用而设计的包不应该修改本地位置,但在应用程序范围内是可以的。

Time.UTC ()方法返回与接收者处于同一时刻的时间,并将位置设置为 UTC。此行将以 UTC 格式打印时间:

    fmt.Printf("%s\n", items[0].SampleDate.UTC())

因为 MongoDB 存储时间的精度低于 time.Time,所以从 MongoDB 返回的值可能不等于您存储的值。

于 2014-10-12T04:56:17.103 回答
0

我知道我问过这个问题,但经过大量挖掘后,我发现这是一种可能的选择。通过使用 time.Time 中的自定义类型,您可以覆盖 json 序列化程序接口并强制使用 UTC。但是,是否推荐做这种事情......

我必须对Golang 中的 UNIX 时间戳以及 go 源代码表示赞赏。

type JsonTime time.Time

func (t JsonTime) MarshalJSON() ([]byte, error) {
    tt := time.Time(t).UTC()
    if y := tt.Year(); y < 0 || y >= 10000 {
        return nil, errors.New("JsonTime: year outside of range [0,9999]")
    }
    if y := tt.Year(); y == 1 {
        return []byte{}, nil
    }
    return []byte(tt.Format(`"` + time.RFC3339Nano + `"`)), nil
}

func (t JsonTime) GetBSON() (interface{}, error) {
    if time.Time(t).IsZero() {
        return nil, nil
    }
    return time.Time(t), nil
}

func (t *JsonTime) SetBSON(raw bson.Raw) error {
    var tm time.Time

    if err := raw.Unmarshal(&tm); err != nil {
        return err
    }

    *t = JsonTime(tm)
    return nil
}

func (t JsonTime) String() string {
    return time.Time(t).UTC().String()
}

type SampleItem struct {
    ObjId      bson.ObjectId `bson:"_id,omitempty" json:"-"`
    SampleDate JsonTime      `bson:"sampleDate" json:"sampleDate"`
}

func TestMe() {

    var item SampleItem
    var items []SampleItem

    sess := getSession()
    defer sess.Close()

    item.SampleDate = JsonTime(time.Now().UTC())
    fmt.Printf("%s\n", item.SampleDate)

    collection := sess.DB("myCollection").C("sampleItems")
    collection.Insert(item)

    err := collection.Find(bson.M{}).All(&items)
    if err == nil {

        fmt.Printf("%s\n", items[0].SampleDate)
        if data, err := json.Marshal(items); err != nil {
            fmt.Printf("%v\n", err)
        } else {
            fmt.Printf("%s\n", data)
        }
    }
}
于 2014-10-15T01:30:10.003 回答