时间。出乎意料的是,划分了'由1' 000' 000

时间:2018-04-21 11:24:23

标签: mongodb go mgo

我使用time.Duration在结构中存储数据,如下所示:

type ApiAccessToken struct {
    ...
    ExpiredIn   *time.Duration `bson:"expired_in,omitempty" json:"expired_in,omitempty"`
    ...
}

我用这样的常量设置它:

...
const ApiAccessTokenDefaultExpiresIn = 7 * 24 * time.Hour
...
d := ApiAccessTokenDefaultExpiresIn
data := &ApiAccessToken{
    ...
    ExpiredIn: &d
    ...
}
...

然后我使用mgo将数据插入数据库。

我在创建data实例之后和插入数据之前进行了检查,ExpiredIn的值是604' 800' 000' 000但在MongoDB中它变成了604' 800� 000(或NumberLong(604800000))。

知道为什么吗?谢谢!

2 个答案:

答案 0 :(得分:1)

我们通常会为特定类型编写自定义MarshalJSON / UnmarshalJSON,以控制编组/解编之前/之后其值的变化。

type ExpiredIn struct {
    time.Duration
}

func (e *ExpiredIn) MarshalJSON() ([]byte, error) {
    return []byte(string(e.Nanoseconds())), nil
}

func (e *ExpiredIn) UnmarshalJSON(data []byte) error {
    i, _ := strconv.ParseInt(string(data[:])), 10, 64)
    e.Duration = time.Duration(i)
    return nil

}

这是测试代码:

package main

import (
    "log"
    "time"

    "gopkg.in/mgo.v2"
)

type Token struct {
    ExpiredIn time.Duration
}

type ExpiredIn struct {
    time.Duration
}

func (e *ExpiredIn) MarshalJSON() ([]byte, error) {
    return []byte(string(e.Nanoseconds())), nil
}

func main() {
    session, err := mgo.Dial("mongodb://localhost:27017/test")
    if err != nil {
        panic(err)
    }
    defer session.Close()

    // Optional. Switch the session to a monotonic behavior.
    session.SetMode(mgo.Monotonic, true)

    c := session.DB("test").C("tokens")
    err = c.Insert(&Recipe{7 * 24 * time.Hour})
    if err != nil {
        log.Fatal(err)
    }
}

你已经完成了!

enter image description here

答案 1 :(得分:-2)

当前解决方案:将MongoDB中返回的ExpiredIntime.Second相乘,这样我就得到了Go-flavored nanosecond time.Duration

我最终使用了string的{​​{1}}表示,因为它只是有效。

我为time.Duration结构创建了两个函数,用于编写/读取数据。

ApiAccessToken

瞧,它有效!

string