From 8ad477eaceed9bf0b92088b94791553a2a26589e Mon Sep 17 00:00:00 2001 From: Jean-Hadrien Chabran Date: Mon, 30 Aug 2021 12:09:17 +0200 Subject: [PATCH] Fix Date object unmarshalling Notion API can return date from page fields in the form of "yyyy-mm-dd" if the field configuration does not include time. The resulting string from the API isn't accepted by the time.RFC3339 format and thus causes an unmarshalling error. The present change fixes it by attempting to parse it as such in case the standard format fails. If it fails again, the error is returned. --- object.go | 25 ++++++++++++++++++++++++- object_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 object_test.go diff --git a/object.go b/object.go index bc09ff2..7877172 100644 --- a/object.go +++ b/object.go @@ -1,6 +1,8 @@ package notionapi -import "time" +import ( + "time" +) type ObjectType string @@ -73,6 +75,27 @@ func (d Date) MarshalText() ([]byte, error) { return []byte(d.String()), nil } +func (d *Date) UnmarshalText(data []byte) error { + t, err := time.Parse(time.RFC3339, string(data)) + + // Because the API does not distinguish between datetime with a + // timezone and dates, we eventually have to try both. + if err != nil { + if _, ok := err.(*time.ParseError); !ok { + return err + } else { + t, err = time.Parse("2006-01-02", string(data)) // Date + if err != nil { + // Still cannot parse it, nothing else to try. + return err + } + } + } + + *d = Date(t) + return nil +} + type File struct { Name string `json:"name"` } diff --git a/object_test.go b/object_test.go new file mode 100644 index 0000000..d942573 --- /dev/null +++ b/object_test.go @@ -0,0 +1,35 @@ +package notionapi_test + +import ( + "testing" + + "github.com/jomei/notionapi" +) + +func TestDate(t *testing.T) { + t.Run(".UnmarshalText", func(t *testing.T) { + var d notionapi.Date + + t.Run("OK datetime with timezone", func(t *testing.T) { + data := []byte("1987-02-13T00:00:00.000+01:00") + err := d.UnmarshalText(data) + if err != nil { + t.Fatal(err) + } + }) + t.Run("OK date", func(t *testing.T) { + data := []byte("1985-01-02") + err := d.UnmarshalText(data) + if err != nil { + t.Fatal(err) + } + }) + t.Run("NOK", func(t *testing.T) { + data := []byte("1985") + err := d.UnmarshalText(data) + if err == nil { + t.Fatalf("expected an error, got none") + } + }) + }) +}