From 81825d314a665c73a1e9920b11a7546efa934e2f Mon Sep 17 00:00:00 2001 From: "johannes.pichler" Date: Wed, 21 Mar 2018 21:12:45 +0100 Subject: [PATCH] Add support for local timezone on ISO8601 output to be able to provide a appropriate time representation the fix conversion to UTC is removed. Also the time.RFC3339 format is used instead of a custom format constant --- constants.go | 2 -- request.go | 4 ++-- response.go | 4 ++-- response_test.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 6 deletions(-) diff --git a/constants.go b/constants.go index 23288d3..a120113 100644 --- a/constants.go +++ b/constants.go @@ -11,8 +11,6 @@ const ( annotationISO8601 = "iso8601" annotationSeperator = "," - iso8601TimeFormat = "2006-01-02T15:04:05Z" - // MediaType is the identifier for the JSON API media type // // see http://jsonapi.org/format/#document-structure diff --git a/request.go b/request.go index fe29706..131328c 100644 --- a/request.go +++ b/request.go @@ -278,7 +278,7 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node) break } - t, err := time.Parse(iso8601TimeFormat, tm) + t, err := time.Parse(time.RFC3339, tm) if err != nil { er = ErrInvalidISO8601 break @@ -327,7 +327,7 @@ func unmarshalNode(data *Node, model reflect.Value, included *map[string]*Node) break } - v, err := time.Parse(iso8601TimeFormat, tm) + v, err := time.Parse(time.RFC3339, tm) if err != nil { er = ErrInvalidISO8601 break diff --git a/response.go b/response.go index f6a1b86..18766e0 100644 --- a/response.go +++ b/response.go @@ -311,7 +311,7 @@ func visitModelNode(model interface{}, included *map[string]*Node, } if iso8601 { - node.Attributes[args[1]] = t.UTC().Format(iso8601TimeFormat) + node.Attributes[args[1]] = t.Format(time.RFC3339) } else { node.Attributes[args[1]] = t.Unix() } @@ -331,7 +331,7 @@ func visitModelNode(model interface{}, included *map[string]*Node, } if iso8601 { - node.Attributes[args[1]] = tm.UTC().Format(iso8601TimeFormat) + node.Attributes[args[1]] = tm.Format(time.RFC3339) } else { node.Attributes[args[1]] = tm.Unix() } diff --git a/response_test.go b/response_test.go index 157f434..b7a3c84 100644 --- a/response_test.go +++ b/response_test.go @@ -468,6 +468,35 @@ func TestMarshalISO8601Time(t *testing.T) { } } +func TestMarshalISO8601TimeWithLocalTimezone(t *testing.T) { + loc, _ := time.LoadLocation("Europe/Vienna") + + testModel := &Timestamp{ + ID: 5, + Time: time.Date(2016, 8, 17, 8, 27, 12, 23849, loc), + } + + out := bytes.NewBuffer(nil) + if err := MarshalPayload(out, testModel); err != nil { + t.Fatal(err) + } + + resp := new(OnePayload) + if err := json.NewDecoder(out).Decode(resp); err != nil { + t.Fatal(err) + } + + data := resp.Data + + if data.Attributes == nil { + t.Fatalf("Expected attributes") + } + + if data.Attributes["timestamp"] != "2016-08-17T08:27:12+02:00" { + t.Fatal("Timestamp was not serialised into ISO8601 correctly") + } +} + func TestMarshalISO8601TimePointer(t *testing.T) { tm := time.Date(2016, 8, 17, 8, 27, 12, 23849, time.UTC) testModel := &Timestamp{ @@ -496,6 +525,36 @@ func TestMarshalISO8601TimePointer(t *testing.T) { } } +func TestMarshalISO8601TimePointerWithLocalTimezone(t *testing.T) { + loc, _ := time.LoadLocation("Europe/Vienna") + + tm := time.Date(2016, 8, 17, 8, 27, 12, 23849, loc) + testModel := &Timestamp{ + ID: 5, + Next: &tm, + } + + out := bytes.NewBuffer(nil) + if err := MarshalPayload(out, testModel); err != nil { + t.Fatal(err) + } + + resp := new(OnePayload) + if err := json.NewDecoder(out).Decode(resp); err != nil { + t.Fatal(err) + } + + data := resp.Data + + if data.Attributes == nil { + t.Fatalf("Expected attributes") + } + + if data.Attributes["next"] != "2016-08-17T08:27:12+02:00" { + t.Fatal("Next was not serialised into ISO8601 correctly") + } +} + func TestSupportsLinkable(t *testing.T) { testModel := &Blog{ ID: 5,