Skip to content

Instantly share code, notes, and snippets.

@xkisu
Created June 28, 2021 02:15
Show Gist options
  • Save xkisu/469c612341387d16af8abc574fb9175f to your computer and use it in GitHub Desktop.
Save xkisu/469c612341387d16af8abc574fb9175f to your computer and use it in GitHub Desktop.
gqlgen RFC3339 Timestamp Scalar
package scalars
import (
"errors"
"io"
"strconv"
"time"
"github.com/99designs/gqlgen/graphql"
)
// MarshalTimestamp returns a marshaler to convert a Go timestamp
// to a suitable GraphQL timestamp representation.
func MarshalTimestamp(t time.Time) graphql.Marshaler {
return graphql.WriterFunc(func(w io.Writer) {
io.WriteString(w, strconv.Quote(t.Format(time.RFC3339)))
})
}
// UnmarshalTimestamp is used by GraphQL to unmarshal supplied timestamps
// into a Golang representation for further use internally.
func UnmarshalTimestamp(v interface{}) (time.Time, error) {
if tmpStr, ok := v.(string); ok {
return time.Parse(time.RFC3339, tmpStr)
}
return time.Time{}, errors.New("time should be a RFC3339 compliant ISO-8601 timestamp")
}
package scalars
import (
"strconv"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestMarshalTimestamp (t *testing.T) {
now := time.Now()
// Test that we can successfully marshal the timestamp
buf := new(strings.Builder)
MarshalTimestamp(now).MarshalGQL(buf)
// Test that the marshaled result is as expected
require.NotNil(t, buf)
require.Equal(t, strconv.Quote(now.Format(time.RFC3339)), buf.String(), "marshaled time does not match expected time string")
}
func TestUnmarshalTimestamp (t *testing.T) {
timeStr := "2021-04-05T21:03:14Z"
// Unmarshal the timestamp from the RFC 3339 string
unmarshalledTime, err := UnmarshalTimestamp(timeStr)
require.Nil(t, err, "failed to unmarshal timestamp")
// Compare the individual time components
require.Equal(t, 2021, unmarshalledTime.Year())
require.Equal(t, 04, (int)(unmarshalledTime.Month()))
require.Equal(t, 05, unmarshalledTime.Day())
require.Equal(t, 21, unmarshalledTime.Hour())
require.Equal(t, 03, unmarshalledTime.Minute())
require.Equal(t, 14, unmarshalledTime.Second())
// Quick sanity check that it converts back to it's self correctly
require.Equal(t, timeStr, unmarshalledTime.Format(time.RFC3339), "unmarshalled time does not convert back to it's self")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment