最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

mongodb - Cannot parse BSON datetime from string - Stack Overflow

programmeradmin1浏览0评论

I'm parsing BSON from strings using the mongo driver library.

AFAIK, the following should be valid BSON:

{
  "createdAt": {"$date": "2024-01-01T00:00:00.000Z"}
}

but the following test code

var v bson.M
bsonString = `{"createdAt": {"$date": "2024-01-01T00:00:00.000Z"}}`
err := bson.UnmarshalExtJSON([]byte(bsonString), true, &v)
if err != nil {
    t.Fatalf("cannot unmarshal: %v", err)
}

fails with error

cannot unmarshal: error decoding key createdAt: invalid JSON input; expected {

Why?

I'm parsing BSON from strings using the mongo driver library.

AFAIK, the following should be valid BSON:

{
  "createdAt": {"$date": "2024-01-01T00:00:00.000Z"}
}

but the following test code

var v bson.M
bsonString = `{"createdAt": {"$date": "2024-01-01T00:00:00.000Z"}}`
err := bson.UnmarshalExtJSON([]byte(bsonString), true, &v)
if err != nil {
    t.Fatalf("cannot unmarshal: %v", err)
}

fails with error

cannot unmarshal: error decoding key createdAt: invalid JSON input; expected {

Why?

Share Improve this question asked Jan 31 at 10:19 AleGAleG 1501 silver badge9 bronze badges 3
  • 1. bson.UnmarshalExtJSON is for Extended JSON, not BSON. If it was actually BSON, use bson.Unmarshal 2. Set canonicalOnly = false since Canonical mode requires dates to be numbers. 3. You are unmarshalling { "createdAt": {"$date": ... } } not just the $date part. I don't know if that's related to the error or how unmarshalling handles nested objects. – aneroid Commented Jan 31 at 10:47
  • 1 1. yes, it's a json representation of a bson 2. that was it, thank you! If you put it in an answer I'll accept it 3. you're right, I could've simplified more the example. Thanks! – AleG Commented Jan 31 at 11:42
  • Wrt 3. "I could've simplified more the example" - no need to simplify in this case :-) I was only curious if that nesting was a cause for the error. If it worked as-is and the only change is the canonicalOnly flag, then the example is correct and doesn't need simplification. (Wrt 2. Answer posted with more info.) – aneroid Commented Jan 31 at 11:54
Add a comment  | 

1 Answer 1

Reset to default 2

In bson.UnmarshalExtJSON, set canonicalOnly to false since Canonical-mode requires dates to be represented as quoted numbers (strings), being milliseconds relative to the epoch.

From the Extended JSON v2 reference:

Canonical: {"$date": {"$numberLong": "<millis>"}}

Relaxed: {"$date": "<ISO-8601 Date/Time Format>"}

And

Where the values are as follows:

  • "<millis>"

    • A 64-bit signed integer as string. The value represents milliseconds relative to the epoch.

So presumably negative numbers for "before 1970".

Go Playground example, output with canonicalOnly=false:

{"createdAt":{"$date":{"$numberLong":"1704067200000"}}}
发布评论

评论列表(0)

  1. 暂无评论