-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Initial proposal for the experimental GraphQLDateTime scalar #557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Is there any way for a client to know that something is a Date without needing to import the schema ahead of time? I suppose Would it be better to serialize as something like: {
"type": "DateTime",
"value": "ISO date here"
} I guess REST APIs often just return dates as ISO strings so this isn't really necessary, but I wonder what people's thoughts are. |
What would be your use-case for giving the client this information? I could imagine a cool use case where graphql client libraries such as apollo and relay could parse a DateTime scalar and automatically convert it to the native date type. For example, a swift client could automatically create and return NSDate instances. This would prevent developers from having to convert string dates to native date types themselves. |
Citing myself from #550:
|
BTW @excitement-engineer I must appreciate your intention but I really don't like adding new dependencies to reference implementation. Reason: It introduces uncertainty to this reference implementation |
package.json
Outdated
@@ -36,7 +36,8 @@ | |||
"prepublish": ". ./resources/prepublish.sh" | |||
}, | |||
"dependencies": { | |||
"iterall": "1.0.2" | |||
"iterall": "1.0.2", | |||
"moment": "^2.15.2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think depending on the moment library for this one experimental feature is probably not what we want. Is it possible to get the same behavior with just a little bit of specific code atop the built-in Date
object (accepting that super old versions of Node and browsers might warp behavior)?
For example, could we just use Date's toISOString()
instead of converting it through moment first? And could we use Date.parse()
which claims to parse ISO format, but protect it from parsing the other formats with a validating regex?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely agree with you on this one! I had some doubts about whether to include moment
as a dependency because it is only used for a very small proportion of the code. There are some features of moment
that I used:
- Checking for a valid date is very easy using the
isValid()
function. I ran into the problem that the invalid date2015-02-29
was regarded as a valid date in theDate
object (because days are numbered from 1-31). - Checking for correctly formatted date strings is very easy in
moment
(you can specify an array of valid date formats). I initially tried using a single validating regex to validate all the supported date formats but it quickly became too complex to understand.
I will try to overcome these problems:) I will try to write multiple easy to understand validating regex for verifying that the date string being parsed is in ISO date format and remove the moment
dependency.
I think that the important thing when doing these operations that the code remains readable and understandable. So I will make sure to write code this way:)
src/type/scalars.js
Outdated
name: 'DateTime', | ||
description: 'An ISO-8601 encoded UTC date string.', | ||
serialize(value: mixed): string { | ||
if (!(value instanceof Date)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think serialize
should be more accepting of input than just asserting Date
instances. For example, iso date strings should probably also be supported here.
Also, I'm curious how convenient we should try to be for unix timestamps? It's really common for datetimes to actually be stored as unix times in databases, and I fear that if we don't make it easy to represent these as DateTime
that they'll be lazily be represented as Int
instead. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! We should promote the use of this scalar by making it very convenient to link to any dateTime representation that are used by the underlying systems: Date
, ISO string or unix timestamp. I will include support for all of these!
Thanks for the great tips!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will update the PR in the weekend:)
@stubailo, there isn't a way for a client to know anything without looking at the schema, so I'm not sure it makes sense to try to create new wrapper types for something like this. If the alternative is using the
@langpavel I disagree. Unix timestamps are great for capturing exact machine time for the present day, but terrible for human time that we often have to represent in products. The datetime ISO standard was designed to represent the real ambiguity that needs to exist to represent a full range of times described by humans when talking about relative times, events, and things that will happen in the future. We have this a similar kind of DateTime representation at Facebook for our Events/Calendar product, and use it all the time. For example:
Not to say that unix timestamps aren't great or aren't suitable for APIs. When your API is depicting moments by machines and for machines, unix time can be a great choice. But if your API is depicting human times, then you need something like ISO time. |
@leebyron Really nice examples, thanks for them! |
That's a great question, I'm not sure! I think part of what evaluating this PR should entail is how this kind of scalar should be introduced. If it should be considered a candidate for addition to the spec, then it should be included in this reference implementation. If not, then perhaps we fold this out into another npm module that just makes it easy to get common behavior. |
I'd say one way to resolve the question of Date/DateTime/Timestamp is to map the type onto what it's most likely to turn into on the client, since GraphQL seems to be client-focused. In JavaScript, I'd suggest that |
I have updated the PR:
Curious to hear your comments on the updates:) |
Travis has failed to build because node version 4 and 0.12 consider `2016-01-01T24:00Z as an invalid date format while version 6 and 7 don't. I have updated the code to restrict the hour range from 0 to 23 to prevent these inconsistencies. |
@stubailo you can use NSDate for this in obj-c and LocalDateTime in java. Would be great if the graphql clients could map straight to these types, would safe the developer a lot of hassle in performing conversions:) |
@excitement-engineer @stubailo on JVM it's a bit more involving... In my experience though, For the moment being, I decided to just document it in sangria. So people need to implement it themselves. On the other hand, some data transfer formats naively support dates (like Amazon Ion). For this, i implemented a mechanism to communicate these capabilities of a data format to a scalar type, so that it can output raw date objects (without any conversion to string), but only when data format supports it. (this is why you see Also, considering all of the patterns you have described:
In my opinion, it would not be correct to represent them with a single data type. For example in java 8
I personally would model them in the same way in my GraphQL schema. In fact this is what I do in my projects. For example, I have following GraphQL types in my schema:
(I don't use |
I have used the 'java.time' package in java and it works quite well! I like the separation between the different date/time formats. It enforces a stronger contract when it comes to date/time representations. @leebyron may I ask what conventions Facebook's GraphQL API maintains for representing dates/times, do you use a single scalar or several (for representing Date, Time, DateTime, YearMonth etc. individually)? |
Any updates on the status of this PR? |
@excitement-engineer pending and answer from Lee, we deal with mixed We are doing financial reporting and we have a lot of transactions with timezones that are colated. The result of that colation is then timezone-less, ie everything that is reported for We use time with TZ to manage daily jobs at the local time. I'm more or less with Oleg (and think Oleg's mention of Java8 is apropos, especially the
and without TZ:
I'd be explicit about the The reason to put I've deliberately left off This all begs the question of whether this should go into the spec and then the reference implementation. To do this well I think it needs to be quite heavy-weight. I like the idea of it being in the spec, but I'm not sure what the maintainers position on it's weight is. One suggestion is to fit a strong-typed version into your graphql-iso-date lib in the interim. tl;dr - strong typing of date-time objects makes an API easier to understand. Open question on how much to stuff into the graphql spec. * we also have LocalDateTime in data we're receiving but get a timezone into it as soon as it hits our system. |
Thanks for your thoughts @jamesgorman2 ! I really appreciate it your input:)
I agree with you:) Java does a great job of distinguishing between these two (and other date types) ! Having very specific types (compared to a single type for representing all dates) makes an API much easier to understand and prevents confusion from implicit assumptions about date representations in my opinion. An issue I ran into with the current implementation in this PR is that the
It seems that java initially also started out with a single class ( An idea would be to update the date/time representation in GraphQL to the following: GraphQLYear Serializes into string
Parsed from string in one of the allowed ISO formats. Allowed ISO formats
GraphQLYearMonth Serializes into string
Parsed from string in one of the allowed ISO formats. Allowed ISO formats
GraphQLDate Serializes into string
Parsed from string in one of the allowed ISO formats. Allowed ISO formats
GraphQLDateTime Serializes into string
Parsed from string in one of the allowed ISO formats. Allowed ISO formats
GraphQLTime Serializes into string
Parsed from string in one of the allowed ISO formats. Allowed ISO formats
What do you guys think of such a representation? Is this a better API compared to the one currently implemented in this PR? |
On the whole I think this is coming along. The general direction feels right but still needs tightening up. After a bit of reflection I've come to:
|
Great idea on the spec @jamesgorman2! I am gonna be on holiday next week but I will work on it when I get back:) The datetime formats I specified above are in UTC; in ISO 8601 the Z indicates that it is in UTC. I think that the GraphQL datetime should be timezoneless, it should be in UTC. Refer to earlier by comment @leebyron on why adding timezone information is not a good idea. As a reference, the Github GraphQL api also uses UTC for their DateTime scalar. The advantage of using UTC is that clients can add the relevant timezone information depending on the timezone that they are in. You don't want timezone information of your server bleeding into your GraphQL layer. |
No worries @excitement-engineer. For the on-the-wire-format I'm less concerned about UTC/non-UTC. Active TZ of a datetime is signal but not super important.* I think we're using the word timezoneless a little differently - I'm referring to temporal objects with no timezone info (cf Lee's Christmas and Happy Hour examples), contrasted with temporal objects with a timezone regardless of whether the it has been shifted from the local TZ to UTC or not. For rich data applications being able to use both is important and being able to talk about which one is coming down the wire is since there is a big difference semantically between shifting a DateTime beween UTC/+0000 to +1100 and appending +1100 to a LocalDateTime.** In the former the absolute time is maintained but the rendered time is changed. In the latter an absolute time is created from a relative time. Beyond this, there needs to be a spec around how a -zoned or -zoneless temporal object is coerced into other types. I prefer permissive input, so I can send a JS Hopefully this help firm up the definitions around timezoned vs -zoneless. I'm happy to use other words for these but I think the distinction is critical. Enjoy your holiday Dirk-Jan. * we use a lot of postgres which has a |
Thanks for your explanation @jamesgorman2! We were talking about different things but now I think that we are on the same level:) I had some time on the plane yesterday so I wrote up an initial version of what the specification could look like. Note that the text in the final draft should be more elaborate, this initial version in just to get the main concepts across. Please provide some feedback on this initial spec so that we can make it better and more complete. I'd like to hear thoughts on whether:
Furthermore, I have not included duration in the spec proposal yet. Is this something that we would like to support? If anybody has any use cases for duration please write them down in this thread, this will help in deciding whether to include it or not:) |
ISO 8601 Date/Time Scalar ProposalThis document contains a proposal for adding ISO 8601 encoded Date/Time scalars to the GraphQL specification. The goal is to create a standardized way of representing Date/Time in GraphQL. The GraphQL scalar types defined below use the ISO 8601 standard for representing dates as string. Below is a list containing all the Date/Time formats supported by the various scalar types together with their meaning. Note, each of the different scalars can be coerced from different subsets of formats in the list below, the supported formats are indicated for each specific scalar type.
Where:
A note on coercion: All of the Scalars defined below can be coerced (both for input/result) from a date/time string formatted according to a list of supported formats. This list is a subset of the formats in the list above. A field error should be raised for strings that do not conform to one of the supported formats. A note on the Native date object/type In the sections below a reference is made to the "native date object/type". The "native" type refers to the standard date type of the language that GraphQL is implemented in. So in Java this could be GraphQLLocalDateUsed for representing specific dates without timezone in format Input coercion:Coerced from date-string in one of the supported formats. Result Coercion:Returns date-string in format
Supported formats:The following formats are supported for input/result coercion. Note, all the formats are truncated to
GraphQLDateTimeUsed to represent a UTC encoded date-time in format Input coercion:Coerced from date-time-string in one of the supported formats. Result Coercion:Returns date-time-string in format
Supported formats:The following formats are supported for input/result coercion. Note, formats with a less than millisecond precision are "zeroed" to millisecond precision. So, the date-time-string "2016-01-01T10Z" is "zeroed" to "2016-01-01T10:00:00.000Z" for example.
GraphQLLocalDateTimeUsed to represent a date-time without a timezone in format Input coercion:Coerced from a date-time-string in one of the supported formats Result Coercion:Returns string in format
Supported formats:The following formats are supported for input/result coercion. Note, formats with a less than millisecond precision are "zeroed" to millisecond precision. So, the date-time-string "2016-01-01T10" is "zeroed" to "2016-01-01T10:00:00.000" for example.
GraphQLLocalTimeRepresents a time without a time-zone in format Input coercion:Coerced from time-string in format specified below Result Coercion:Returns string in format
Supported formats:The following formats are supported for input/result coercion. Note, formats with a less than millisecond precision are "zeroed" to millisecond precision. So, the time-string "10:20" is "zeroed" to "10:00:00.000" for example.
GraphQLTimeRepresents a UTC encoded time in the format Input coercion:Coerced from a time-string in one of the supported formats. Result Coercion:Returns string in format
Supported formats:The following formats are supported for input/result coercion. Note, formats with a less than millisecond precision are "zeroed". So the time-string "10" is "zeroed" to "10:00:00.000" for example.
GraphQLYearUsed to represent a year in format Input coercion:Coerced from:
Result Coercion:Returns string in format
Supported formats:The following formats are supported for input/result coercion. Note, all the formats are truncated to
GraphQLYearMonthUsed to represent a year-month combination in format Input coercion:Coerced from a date-string in one of the supported formats. Result Coercion:Returns string in format
Supported formats:The following formats are supported for input/result coercion. Note, all the formats are truncated to
GraphQLMonthDayUsed to represent a specific month-day pair in format Input coercion:Coerced from a date-string in one of the supported formats. Result Coercion:Returns string in format
Supported formats:The following formats are supported for input/result coercion. Note, all the formats are truncated to
|
@leebyron I am really curious to hear your opinion and feedback on the proposal:) Do these scalars cover the use cases that need to be supported for facebook's GraphQL API? |
My immediate reaction is that this is the wrong balance between simplicity and usefulness, I think having people pick between many different time formats will result in mistakes and confusion and there will be a bunch of collisions where these slightly incompatible date formats are used in overlapping ways - like a variable provided or extensions of interfaces |
The most important question that needs to be answered though is if a date scalar should be added to the GraphQL specification - since graphql.js is a reference implementation of the spec, it would probably be confusing to add additional scalars that were not described by the spec. Adding to the spec is a double-edged sword. It reduces the amount of things that you can do in user space, but in exchange you get guarantees about what to expect when you encounter it in any arbitrary (spec compliant) GraphQL server. That means if If we choose not to specify time scalars, then this work can still be useful as a separate npm library for use by anyone who agrees with these opinions on how date time should work, however if not specified then servers could be free to disagree and define scalar types with the same names that have different behavior. Also I should point out that if we were to write specification for |
If we look at this from an introspection perspective and global APIs, how could a client developer know how to handle a dateTime value she is being sent? In other words, if we look at it from the client's/ customer perspective, how would she ingest this dateTime value to then know how to properly format it, to present it to her client/ customer/ viewer? When it comes to public APIs, will this "freedom of choice" of not putting such types in the spec always work? Public APIs need a specification to go by, so that any ingested data can be consistently used. If a client dev sees a "dateTime" type value, she should know it is of a certain format and will always be that format and also what the reference time is. Going off on a tangent, if you think about it, dateTime or Time values are always compounds (which others have pointed out too, in different ways). Time values are always a reference value and a formatting value compounded together. In other words, a time value cannot be a scalar value really, if you go by the definition of a scalar. Or put another way, there is no way to represent a time value, without a format and a reference! 😄 Looking at a just made public API, I went to the Github GraphiQL Explorer and looked for a
Simple enough. 😄 I know exactly what I need to do with it. Is there anything more really needed? Scott |
Thanks for the awesome feedback @jamesgorman2, I really appreciate it! I have updated the proposal according to your feedback and reduced the number of scalars to only include the more fundamental ones such as date, time and date-time.
LocalDateA date without a time-zone in the ISO-8601 calendar system, such as 2007-12-03. LocalDate is a representation of a date, viewed as year-month-day. This scalar does not represent a time or time-zone. Instead, it is a description of the date, as used for birthdays for example. It cannot represent an instant on the time-line. LocalDate is encoded as a string in the format For example, the value "2nd of January 2015" is encoded as string "2015-01-02". LocalTimeA time without a time-zone in the ISO-8601 calendar system, such as 10:15:30.000. LocalTime is a representation of a time, viewed as hour-minute-second. Time is represented to millisecond precision. Where a time does not have millisecond resolution, any missing units are implied to be zero. This scalar does not represent a date or time-zone. Instead, it is a description of the local time as seen on a wall clock for example. It cannot represent an instant on the time-line. LocalTime is encoded as a string in the format The value "14:10:20.987" is encoded as string "14:10:20.987". A time with less than millisecond precision such as "14:10" is encoded as "14:10:00.000". TimeA time at UTC in the ISO-8601 calendar system, such as 10:15:30.000Z. Time is a representation of a time instant, viewed as hour-minute-second at UTC. A time instant is represented to millisecond precision. Where an instant does not have millisecond resolution, any missing units are implied to be zero. Where an instant has a time-zone other than UTC, it is shifted to UTC. Time does not represents a date. Instead, it is a description of a time instant such as the opening bell of the New York Stock Exchange for example. It cannot represent an instant on the time-line. By representing an instant as a date-time at UTC, it allows the local time at which the instant occurs to be derived for each time-zone. Time is encoded as a string in the format The value "14:10:20.987 at UTC" is encoded as string "14:10:20.987Z". A time instant with less than millisecond precision such as "14:10 at UTC" is encoded as "14:10:00.000Z". A time instant with a time-zone other than UTC such as "14:10:20.987 at UTC +1 hour" is encoded as "13:10:20.987Z". LocalDateTimeA date-time without a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30.000. LocalDateTime is a representation of a full date with a local time, viewed as a combination of LocalDate and LocalTime. This scalar does not represent a time-zone. Instead, it is a description of the date, as used for birthdays for example, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line. LocalDateTime is encoded encoded as a concatenation of the string encoding of LocalDate and LocalTime in the format For example, the value "2nd December 2009 at 14:10.20.987" is encoded as string "2009-12-02T14:10.20.987". DateTimeA date-time at UTC in the ISO-8601 calendar system, such as 2007-12-03T10:15:30.000Z. DateTime is a representation of a full date with a time at UTC, viewed as a combination of LocalDate and Time. DateTime represents an exact instant on the time-line to millisecond precision. It is description of the instant that a user account was created for example. By representing an instant as a date-time at UTC it allows the local date-time at which the instant occurs to be derived for each time-zone. DateTime is encoded as a concatenation of the string encoding of LocalDate and Time in the format For example, the value "2nd December 2009, 14:10.20.987 at UTC" is encoded as string "2009-12-02T14:10.20.987Z". |
@excitement-engineer A lot of work has come into this PR. Wow! When reading over the comments I was missing a few points that I would like to add: Making sure that the timestamps are somehow correct are not always easy. This is even worse between client ←→ server. So: even if a timezone formatted value arrives at the graphql server instance the syncing might be off. User Example: If the timestamp between server is out-of-sync, an application that alerts the user might alert the user too early or too late. Out of this very problem, There is another tangent to this: Servers - particularly
where the This sort of API would imho. be useful in the Relay and graphql standard and because it is used here: the type to implement it: |
Hey @martinheidegger thanks for contributing to the thread! I personally do not have any experience syncing timestamps between client-server and server-server so I will defer my opinion to someone with more experience on this issue so that they can evaluate your proposal. |
I'm currently busy upgrading the graphql-iso-date library with support for some of these date/time scalars. Implementing this stuff gave me so insights on ways to deal with dates/times. Following your earlier comment @leebyron I decided to implement these scalars based on the RFC 3339 ISO 8601 profile. This profile is concise and easy to understand, this makes it easy for people use in their graphQL schemas but also decreases the implementation overhead compared to the full ISO 8601 standard which is very extensive. I like the idea of using the profile for the DateTime here as well! Below is a description of the DateTime that I ended up implementing. I would love to hear feedback:) One issue I ran into was dealing with leap seconds. Leap seconds cannot be predicted far into the future which creates a nightmare for software because it needs to be updated whenever new leap seconds are announced. Javascript Dates ignore leap seconds for example. I therefore decided to ignore leap seconds as well. What do you guys think, should we take leap seconds into account? DateTimeA date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the date-time format outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. This scalar is a description of an exact instant on the time-line such as the instant that a user account was created for example. This scalar ignores leap seconds (thereby assuming that a minute constitutes of 59 seconds), in this respect it diverges from the RFC 3339 profile. Where an RFC 3339 compliant date-time string has a time-zone other than UTC, it is shifted to UTC. For example, the date-time string "2016-01-01T14:10:20.987+01:00" is shifted to "2016-01-01T13:10:20.987Z". Result Coercion Javascript Date instances and Unix timestamps (represented as 32-bit signed integers) are coerced to RFC 3339 compliant date-time strings. Invalid Date instances raise a field error. Input Coercion When expected as an input type, only RFC 3339 compliant date-time strings are accepted. All other input values raise a query error indicating an incorrect type. |
Any reasons to exclude zoned or offset times? For my use-case the time zone is important, so converting to UTC means losing information. |
@ghostganz I tried to keep the API as simple as possible, there is a very simple contract that is upheld here: You always get UTC! Any opinions on how we should go about this from the others, is UTC too restrictive? |
@excitement-engineer the timezone show in which timezone a server operates, at least in theory you could use that to identify where the db is running. |
@martijnwalraven Even for small locally running projects I'm using and enforcing UTC. I'm almost sure most of experienced admins using UTC on server.. |
@martinheidegger @langpavel Yes you are right, it would not be good to expose the timezone of a server in an API! But I don't think that's what @ghostganz 's meant with his comment I interpreted @ghostganz 's use case as follows: suppose a client makes a request and sends the timezone where the request was made in the ISO date-time string as input for the API. In the current setup the scalar automatically shifts this date-time string to UTC thereby losing the timezone offset info. Perhaps there are some use cases where the server needs this timezone info. |
@ghostganz - could you please explain your use case? Scott |
@excitement-engineer @ghostganz Yes, there are use cases where timezone info is helpful, but I'm still not sure this should be part of GraphQL. Thinking about proper storage types for time is deep app specific. This discussion is out of range of GraphQL specification and should be finally closed I think. Everybody can create own type and/or publish module which cover most widely used formats of representing datetime values across RFC/ISO specifications. In GraphQL it can always ends up as |
In my use-case we originally used local time in ISO 8601, with no specified time zone. This was nicely human readable etc., but broke down once the clients were abroad. We realized every 5 o'clock implicitly meant 5 o'clock in CET. The time zone of the server or database itself has no relevance here. For us the time zone is data. This is why there are time zones in the 8601 standard in the first place. (Or really, 5 o'clock in +0100) |
@ghostganz - If you send a time value over the wire, it will either be the UTC value, or it will be a time value with the offset already calculated into it. So, according to this proposal, you should either get the "Z" at the end, or not. As you said, the user's time offset is data, but it should be stored separately from the time value/ reference. Think about it this way. When do you store a user's offset (the time zone) and when do you store time values? They are two separate occurrences or at least they should be. 😄 Scott |
@smolinari No, the user's offset is not data, but the time zones of dates in our responses are. Let me re-phrase: In our use-case an article can be published 5 o'clock CET and should be displayed as "published 5 o'clock" no matter where the user is. But sending as local time won't do, because the client can't display a relative time ("published 10 minutes ago") unless it knows the time zone of the article. |
So if I am in mountain time and it is 4:10 pm, I'd see 5 o'clock in the future as the articles published time?
If you save the published time as UTC and you know each user's offset plus the local time (which you can get the offset from too), you can easily calculate "published 10 minutes ago" without a time zone. That is why time values are usually saved in Zulu time. In fact, trying to calculate times with time zones is much more complicated, especially when DST comes into the picture. Scott |
While generally true, the ISO time format has its advantages, one being the timezones the other being that you never run into integer overflows. |
@langpavel In my opinion there is some value in providing a good default option for representing date-time that covers the vast majority of use cases. This will give clients standard behaviour w.r.t. date-time and will prevent people from incorrectly representing date-time as a GraphQLString or GraphQLInt (timestamps) for example. In addition, date-time representations is something that comes up so often in APIs that there is a place for a standard representation. Of course it is impossible to cover every possible use case with this scalar, in this case the developer can implement their own custom solution that satisfies their specific use case. |
@excitement-engineer. will prevent people from incorrectly representing date-time as a GraphQLString or GraphQLInt Don't think so. If you look at APIs around you, you will see what craziness can people create 😈 And, if you enforce them to one good way, will be mostly the bad one. So let people think about, they will start looking around and then can possibly find and pick more fitting, all opt-in. So, conclusion: GraphQL does not include data type for representing Date and/or Time values, but you can choose from multiple custom data types.. (enumeration here...) And yes, It is possible to implement universal multi-format, with localization custom object types which can represent any date-time value, may be this library becomes well ported across languages BUT no any unnecessary byte in this reference implementation and every custom server (client)! At last, every time implementation is opinionated and simply there is no best representation across internet. |
Support or not support any types of date formats to create an universal date/time format will be a mess, in my opinion. 😛 Any of the formats choosed will not fit the use case for someone. But keep it simple, will help to put this to the specification based on comments of @leebyron. If we use the ISO format, we can all the benefits of timezones and whatever you want, and it can be stringified, with this information, you can use at the server any library to parse this information to your favorite format. We keep the timezone and ability to convert to any format using ISO dates, and in mind this is a reference spec, we need (again) to keep it simple, let's give the responsibility to decide how to use the "date" information to the client and server. |
Implementation of the DateTime scalar proposed in graphql/graphql-spec#315.
Again and again, this is evergreen 🙂 For me, timestamp is enough — in millis, but for atom which catching fancy foton from neighbours, well he don't incept time in same way… 🙂 Joking, but not much. This is not obvious at first spot. But similarities — to the hell with fractals 😆 — yes; there are. You cannot smoothly convert date and time and timezone to universal format. Proof of this thesis is observable in this debate, from born of internet to today. Yes, there are norms, like ISO — but how this is not universal… So NO.
Why I'm against norm:If you introduce the standart then all relevant points mentioned above will be in very hard and outstanding position. Be careful — history and opinion here: I'm from Czech. We have a total gov. We make a Velvet revolution, but we experiencing return of normalization with very bad expectations. Norms are good as far as they help with participating. If they are too fixed, they devaluates work, because they are too tight — no carrying of losing facta. We cannot allow loosing facta in so modern transport layer like GraphQL is! @excitement-engineer So sorry, but GraphQL is only (and at all) about data exchange, semantics is on the App. — Peace and sleep, forgive me a typos please |
I think the conclusion from this PR is that there is not one DateTime type to rule them all. Tradeoffs involved will lead to reasonable different decisions for different APIs. Having these utility scalar types available in a package on NPM would be highly valuable, but since there isn't consensus on a single one, this package is probably the wrong place to host it. It's been incredibly valuable to work through this discussion in this forum! |
This PR contains an initial proposal for a graphQL
DateTime
scalar following the discussion in issue #550. Let me know what you think:)The scalar has the following properties:
YYYY-MM-DDThh:mm:ss.sssZ
.moment
as a dependency in order to perform all the date operations.