diff --git a/README.md b/README.md index 4f0a16465..ade8e2538 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Further PR's (with tests) are welcome, but please maintain backwards compatibili * Improved connection handling ([details](https://github.com/globalsign/mgo/pull/5)) * Hides SASL warnings ([details](https://github.com/globalsign/mgo/pull/7)) * Improved multi-document transaction performance ([details](https://github.com/globalsign/mgo/pull/10), [more](https://github.com/globalsign/mgo/pull/11)) +* Fixes timezone handling ([details](https://github.com/go-mgo/mgo/pull/464)) * Fixes cursor timeouts ([detials](https://jira.mongodb.org/browse/SERVER-24899)) --- @@ -27,5 +28,6 @@ Further PR's (with tests) are welcome, but please maintain backwards compatibili * @eaglerayp * @drichelson * @jameinel +* @Reenjii * @smoya * @wgallagher \ No newline at end of file diff --git a/bson/json.go b/bson/json.go index 3cfa102c4..045c71301 100644 --- a/bson/json.go +++ b/bson/json.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "fmt" "strconv" + "strings" "time" "github.com/globalsign/mgo/internal/json" @@ -156,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 { @@ -170,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 d8ce798f9..880fb87c2 100644 --- a/bson/json_test.go +++ b/bson/json_test.go @@ -34,12 +34,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), @@ -180,6 +186,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) } }