当我在golang中查询mongodb时,如何获得UTC时间

时间:2014-10-12 04:44:39

标签: mongodb go mgo

我对Golang和MongoDB相对较新并且遇到了一个日期问题,我似乎可以在MongoDB中插入UTC日期,但是当我通过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选项吗?

2 个答案:

答案 0 :(得分:7)

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返回的值可能与您存储的值不相等。

答案 1 :(得分:0)

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

我必须赞扬UNIX time stamps in Golang以及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)
        }
    }
}