我对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选项吗?
答案 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)
}
}
}