diff --git a/bson/json.go b/bson/json.go index 09df8260a..671133435 100644 --- a/bson/json.go +++ b/bson/json.go @@ -4,9 +4,11 @@ import ( "bytes" "encoding/base64" "fmt" - "gopkg.in/mgo.v2/internal/json" "strconv" + "strings" "time" + + "gopkg.in/mgo.v2/internal/json" ) // UnmarshalJSON unmarshals a JSON value that may hold non-standard @@ -155,7 +157,7 @@ func jencBinaryType(v interface{}) ([]byte, error) { return fbytes(`{"$binary":"%s","$type":"0x%x"}`, out, in.Kind), nil } -const jdateFormat = "2006-01-02T15:04:05.999Z" +const jdateFormat = "2006-01-02T15:04:05.999Z07:00" func jdecDate(data []byte) (interface{}, error) { var v struct { @@ -169,13 +171,15 @@ func jdecDate(data []byte) (interface{}, error) { v.S = v.Func.S } if v.S != "" { + var errs []string for _, format := range []string{jdateFormat, "2006-01-02"} { t, err := time.Parse(format, v.S) if err == nil { return t, nil } + errs = append(errs, err.Error()) } - return nil, fmt.Errorf("cannot parse date: %q", v.S) + return nil, fmt.Errorf("cannot parse date: %q [%s]", v.S, strings.Join(errs, ", ")) } var vn struct { diff --git a/bson/json_test.go b/bson/json_test.go index 866f51c34..efb9ee64b 100644 --- a/bson/json_test.go +++ b/bson/json_test.go @@ -1,12 +1,12 @@ package bson_test import ( - "gopkg.in/mgo.v2/bson" - - . "gopkg.in/check.v1" "reflect" "strings" "time" + + . "gopkg.in/check.v1" + "gopkg.in/mgo.v2/bson" ) type jsonTest struct { @@ -33,12 +33,18 @@ var jsonTests = []jsonTest{ { a: time.Date(2016, 5, 15, 1, 2, 3, 4000000, time.UTC), b: `{"$date":"2016-05-15T01:02:03.004Z"}`, + }, { + a: time.Date(2016, 5, 15, 1, 2, 3, 4000000, time.FixedZone("CET", 60*60)), + b: `{"$date":"2016-05-15T01:02:03.004+01:00"}`, }, { b: `{"$date": {"$numberLong": "1002"}}`, c: time.Date(1970, 1, 1, 0, 0, 1, 2e6, time.UTC), }, { b: `ISODate("2016-05-15T01:02:03.004Z")`, c: time.Date(2016, 5, 15, 1, 2, 3, 4000000, time.UTC), + }, { + b: `ISODate("2016-05-15T01:02:03.004-07:00")`, + c: time.Date(2016, 5, 15, 1, 2, 3, 4000000, time.FixedZone("PDT", -7*60*60)), }, { b: `new Date(1000)`, c: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC), @@ -179,6 +185,11 @@ func (s *S) TestJSON(c *C) { value = zerov.Elem().Interface() } c.Logf("Loaded: %#v", value) + if ctime, ok := item.c.(time.Time); ok { + // time.Time must be compared with time.Time.Equal and not reflect.DeepEquals + c.Assert(ctime.Equal(value.(time.Time)), Equals, true) + continue + } c.Assert(value, DeepEquals, item.c) } }