[英]time.Duration is unexpectedly 'divided' by 1'000'000
I'm using time.Duration
to store data in a struct as follows: 我正在使用time.Duration
将数据存储在结构中,如下所示:
type ApiAccessToken struct {
...
ExpiredIn *time.Duration `bson:"expired_in,omitempty" json:"expired_in,omitempty"`
...
}
and I set it using a constant like this: 我使用这样的常量进行设置:
...
const ApiAccessTokenDefaultExpiresIn = 7 * 24 * time.Hour
...
d := ApiAccessTokenDefaultExpiresIn
data := &ApiAccessToken{
...
ExpiredIn: &d
...
}
...
then I use mgo
to insert the data to database. 然后我使用mgo
将数据插入数据库。
I did checking after creating the data
instance and before inserting the data and the value of ExpiredIn
was 604'800'000'000'000 but in MongoDB it became 604'800'000 (or NumberLong(604800000)
). 在创建data
实例之后,插入数据之前,我做了检查,并且ExpiredIn
的值为ExpiredIn
,但是在MongoDB中,它变为604'800'000(或NumberLong(604800000)
)。
Any idea why? 知道为什么吗? Thank you! 谢谢!
We would normally write custom MarshalJSON/UnmarshalJSON for specific types to control what happens to their values before/after marshaling/unmarshaling. 我们通常会为特定类型编写自定义的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
}
Here's the test code: 这是测试代码:
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)
}
}
And you're done! 大功告成!
Current solution: multiply the returned
ExpiredIn
from MongoDB with
time.Second
so I got my Go-flavoured nanosecond
time.Duration
.
目前的解决方案:乘返回
ExpiredIn
从MongoDB中与
time.Second
所以我得到了我去味纳秒
time.Duration
。
I ended up using the string
representation of time.Duration
because it simply works. 我最终使用time.Duration
的string
表示形式,因为它很简单。
I created two functions for my ApiAccessToken
struct that does the job of writing/reading the data. 我为ApiAccessToken
结构创建了两个函数, ApiAccessToken
函数完成了写入/读取数据的工作。
func (tok *ApiAccessToken) SetExpiredIn(t time.Duration) {
s := t.String() // read the string
tok.ExpiredIn = &s
}
func (tok *ApiAccessToken) GetExpiredIn() (r bool, t time.Duration) {
if tok.ExpiredIn != nil {
var err error
t, err = time.ParseDuration(*tok.ExpiredIn) // parse the string
r = (err == nil) // can we use this?
}
return
}
And voila, it works! 瞧,它起作用了!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.