Description
This is a new attempt to add a date/time scalar to GraphQL in order to represent date and time. There has been previous discussions, which resulted in the decision not to extend GraphQL (see #315 )
Why a standard scalar for date/time
I think a scalar handling date/time is the most fundamental scalar missing in GraphQL. The arguments for having a standard scalar (or multiple) are:
- it is required by enough schemas to represent a date/time
- it is not easy do deal with date/time correctly. Having a well defined standard scalar would make it easier for the GraphQL community and take away the burden of coming up with a solution again and again on their own.
- because date/time handling is not trivial, different date/time scalars are likely to be incompatible across different GraphQL implementations if not specified
Proposal: DateTime
The proposal is to add one new scalar: DateTime.
An DateTime is a specific point in time. It is represented in input and output as yyyy-MM-dd'T'HH:mm:ss.SSSZ
. (The ultimate authority for the format is RFC 3339). For example 2011-12-03T10:15:30.123+01:00
is a valid value.
It doesn't include full timezone information (for example "Europe/Berlin").
The goal here is be very precise in the naming and strict in the allowed formats: it is an explicit non-goal to support a wide range of different formats.
Date/Time as defined in RFC 3339
The specific details of the format are defined in RFC 3339. This proposal doesn't introduce or change any new concepts.
Format definition
The format is defined in RFC 3339 section 5.6 section 5.6 date-time
.
Offset is not a full Time zone
This scalar only deals with offsets (hours and minutes differences to UTC) and not full time zones. Full time zones also include rules regarding daylight saving time. For example "Europe/Berlin" represents a full timezone, but +02:00 is an offset used by "Europe/Berlin" during the summer.
Comparison is not trivial
A comparison between different DateTime is not trivial because two DateTime can represent the same point in time: For example 2008-12-03T11:00+01:00
and 2008-12-03T12:00+02:00
are both equal in this regard, but the strings are not
Why not have more formats?
The goal here is to make it easier to communicate a specific point in time. Having one well defined (and widely supported) format is the best way to achieve that imho.
What about other scalars?
I wanted to keep this proposal as simple as possible and I think DateTime
is a good start for supporting date/time better in GraphQL.
I think having a LocalDateTime or LocalDate or LocalTime are worth having a discussion, but at the same time they can be represented as an DateTime in some way and I didn't want to make this proposal more complex.
Why not restrict to just UTC?
This is a possible alternative. (In this case the format would be yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
with a const Z
at the end). I would prefer calling this scalar not DateTime
anymore, but Instant
.
By restricting it to just UTC
it would be somehow simpler, but we would also loose flexibility.
With DateTime
one can easily imagine a type like this:
type ZoneDateTime {
dateTime: DateTime
zone: String
}
This would allow for a point in a Time in a specific zone. (for example a recurring calendar entry).
Using an Instant
in this way is not really possible, because it would always be formatted in UTC
.
I see Instant
as a possible additional scalar which could be introduced later (if needed).
DateTime or OffsetDateTime or ....
The first version of this RFC named the scalar OffsetDateTime
. It was then renamed to DateTime
to reflect that this is the name most people use for a date-time scalar.