Status: Work in progress 🚧

DateTime Scalar spec

Specification for a custom GraphQL Scalar which represents an exact point in time. This point in time is specified by having an offset to UTC and does not use time zone.

Based on RFC 3339

This Scalar is a slightly refined version of RFC 3339 including the errata.

All definitions of RFC 3339 are adopted and nothing is added or removed unless explicitly mentioned here.

The following refinements/clarifications apply:

Only "date-time"

This scalar represents a “date-time” as specified in section 5.6 of RFC 3339.

The other productions in section 5.6 are only used to support "date-time" but never stand alone for this Scalar.

Non optional exact milliseconds

RFC 3339 defines time-secfrac optional as:

time-secfrac    = "." 1*DIGIT (Meaning 1 or more DIGIT)

This allows for an unlimited numbers of digits. For this scalar the rule is not optional anymore and refined as:

time-secfrac    = "." DIGIT DIGIT DIGIT

consisting always of exact three digits representing milliseconds.

No 'Unknown Local Offset Convention'

Section 4.3 says:

If the time in UTC is known, but the offset to local time is unknown, 
this can be represented with an offset of "-00:00".

In order to simplify this Scalar this convention is dropped and an offset of -00:00 is not allowed.

Result Coercion


The accepted values are implementation specific, but it is recommend to accept Strings and other types representing Dates.


The outcome of the result Coercion should always be a String formatted as "date-time" as described above.

UTC offset should be formatted as Z and not +00:00 and lower case z and t should be converted to Z and T.

Literal Coercion


Only String literals are accepted formatted as "date-time" as described above.


The output value is implementation specific, but the value should accurately capture a "date-time" as described above. It is especially discouraged to use a value with a time zone instead of an offset, because time zone to offset conversion is non trivial.

Value Coercion


The specific values for the input are implementation specific, but they should be semantically equivalent to "date-time" without any conversion. It is especially discouraged to accept values with time zones instead of offsets, because the conversion from time zone to offset is non trivial.


Implementation specific.

Test cases

These are valid Strings accepted for the input of Literal Coercion:

2011-08-30T13:22:53.108ZA DateTime with UTC offset (+00:00).
2011-08-30T13:22:53.108+00:00A DateTime with +00:00 which is the same as UTC.
2011-08-30t13:22:53.108zThe z and t may be lower case.
2011-08-30T13:22:53.108-03:00A DateTime with -3h offset.
2011-08-30T13:22:53.108+03:30A DateTime with +3h 30min offset.

These are invalid Strings which should be rejected as Literal Coercion Input and should not be an output of Result Coercion:

StringWhy is it invalid
2011-08-30T13:22:53.108-03The minutes of the offset are missing.
2011-08-30T13:22:53.108912ZToo many digits for fractions of a second. Exactly three expected.
2011-08-30T24:22:53ZFractions of a second are missing.
2011-08-30T13:22:53.108No offset provided.
2011-08-30No time provided.
2011-08-30T13:22:53.108-00:00Negative offset (-00:00) is not allowed
2011-08-30T13:22:53.108+03:30:15Seconds are not allowed for the offset
2011-08-30T24:22:53.108Z24 is not allowed as hour of the time.
2010-02-30T21:22:53.108Z30th of February is not a valid date
2010-02-11T21:22:53.108Z+25:1125 is not a valid hour for offset

Recommended Scalar name

The obvious recommended name for the Scalar is DateTime. If this name is not available then one alternative is OffsetDateTime, which describes the Scalar quite accurately.

Go back to the homepage