【问题标题】:How can I get the UTC time when I query mongodb in golang在 golang 中查询 mongodb 时如何获取 UTC 时间
【发布时间】:2014-10-12 04:44:39
【问题描述】:

我对 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 选项?

【问题讨论】:

    标签: mongodb go mgo


    【解决方案1】:

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

    【讨论】:

    • 好的。我的部分问题是我正在序列化为 json,如下所示: data, err := json.Marshal(items[0]); json数据是错误的时间。如何让我的 json 输出以 UTC 序列化?
    • 我喜欢简单的 Charlie,但希望有一种方法在序列化为 json 之前不必记住设置为 UTC。我研究了从 time.Time 创建一个自定义类型,这将允许我设置一个使用 UTC 的自定义 json 序列化程序。我会把它作为一个可能的答案发布,但我对那些对它是否是一个好选择有更多经验的人感兴趣。
    • 这正是我正在寻找的类型。似乎它得到了我需要的东西。谢谢。
    【解决方案2】:

    我知道我问过这个问题,但经过大量挖掘后,我发现这是一种可能的选择。通过使用 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)
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-12-06
      • 2013-04-03
      • 1970-01-01
      • 2018-05-25
      • 2012-04-03
      • 2019-06-05
      • 1970-01-01
      • 2012-01-29
      相关资源
      最近更新 更多