Skip to content
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

fix: restore serialization of DateTime scalar to pre-1.2.0 (values must be serialized to string, not to instance of Date) + clarify that timestamps are ECMAScript (milliseconds), not unix timestamps (seconds) #1641

Closed
wants to merge 3 commits into from

Conversation

falkenhawk
Copy link

@falkenhawk falkenhawk commented Jul 6, 2022

Description

fix: restore serialization of DateTime scalar to pre-1.2.0

A value cannot be serialized into something other than js primitives (boolean string, number) or array, object, null
otherwise there is no guarantee for it to be transported properly over graphql protocol.

Additionally, fixed inconsistencies in handling unix timestamps (maybe that was initial motivation to go with those changes in v1.2.0?) edit: ECMAScript timestamps, ref: #387 (comment) 95e86c0

(possibly) Related #414 (comment)

Related discussion: #1617 (reply in thread)
another one: #835

Type of change

Screenshots/Sandbox (if appropriate/relevant):

Adding links to sandbox or providing screenshots can help us understand more about this PR and take action on it as appropriate

How Has This Been Tested?

Changes to automated test suite included.

Checklist:

  • I have followed the CONTRIBUTING doc and the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests and linter rules pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Further comments

I tried to migrate from https://github.com/excitement-engineer/graphql-iso-date to this package (as recommended in their README)

Here DateTime scalar was being serialized to an instance of Date - in contrary to Date or Time scalars, which have been left untouched in v1.2.0 and still serialize to string - and that broke the expected outputs, mangling data for fractional seconds and failing to comply with graphql spec which does not allow such values.

Moreover, astFromValue('2021-10-02T00:00:00.000Z', DateTime) (a function from graphql/utilities) fails on such "serialized" value (here: Date) with TypeError: Cannot convert value to AST: 2021-10-02T00:00:00.000Z. - that was the initial reason for me to submit the PR - as it broke our toolset.

The affecting change happened in 3b1352c#diff-5bff20d592f8d56ae20cad088bf374d5ce38af414afd5631ab82f42481bb8473
with no message explaining why, no linked PR, moreover there is no release notes for v1.2.0 (https://github.com/Urigo/graphql-scalars/releases/tag/v1.2.0) only v1.2.1 but there is nothing mentioning the change in any of future releases.

@vercel
Copy link

vercel bot commented Jul 6, 2022

@falkenhawk is attempting to deploy a commit to the The Guild Team on Vercel.

A member of the Team first needs to authorize it.

@falkenhawk
Copy link
Author

I initially restored handling of Unix timestamps in #48402fe , as it was expected with graphql-iso-date and still as described in docs of graphql-scalars https://www.graphql-scalars.dev/docs/scalars/date-time

but then I noticed it was decided in #387 (comment) that timestamps with milliseconds are expected here to be used instead. (i.e. ECMAScript timestamps, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#the_ecmascript_epoch_and_timestamps)

I removed all references to "unix timestamps" in 95e86c0 to make it clear what is expected.

@falkenhawk falkenhawk changed the title fix: restore serialization of DateTime scalar to pre-1.2.0 (values must be serialized to string, not to instance of Date) fix: restore serialization of DateTime scalar to pre-1.2.0 (values must be serialized to string, not to instance of Date) + clarify that timestamps are ECMAScript (milliseconds), not unix timestamps (seconds) Jul 6, 2022
@vercel
Copy link

vercel bot commented Jul 6, 2022

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated
graphql-scalars ❌ Failed (Inspect) Jul 6, 2022 at 3:55PM (UTC)

@martinblostein
Copy link

I'll just +1 that this should be fixed. I ran into this as a breaking change while trying to migrate from graphql-iso-date.

@wzrdtales
Copy link

what is blocking here?

pre-1.2.0
A value cannot be serialized into something other than js primitives (boolean string, number) or array, object, null
otherwise there is no guarantee for it to be transported properly over graphql protocol.

Here `DateTime` scalar was being serialized to an instance of `Date` - in contrary to `Date` or `Time` scalars, which have been left untouched in v1.2.0 and still serialize to string - and that broke the expected outputs, mangling data for fractional seconds and failing to comply with graphql spec which does not allow such values.

Moreover, `astFromValue('2021-10-02T00:00:00.000Z', DateTime)` (a function from `graphql/utilities`) fails on such "serialized" value (here: `Date`) with `TypeError: Cannot convert value to AST: 2021-10-02T00:00:00.000Z.` - that was the initial reason for me to submit the PR - as it broke our toolset.

The affecting change happened in Urigo@3b1352c#diff-5bff20d592f8d56ae20cad088bf374d5ce38af414afd5631ab82f42481bb8473
with no message explaining why, no linked PR, moreover there is no release notes for v1.2.0 (https://github.com/Urigo/graphql-scalars/releases/tag/v1.2.0) only v1.2.1 but there is nothing mentioning the change in any of future releases.

Additionally, fixed inconsistencies in handling unix timestamps (maybe that was initial motivation to go with those changes in v1.2.0?)

# Conflicts:
#	src/scalars/iso-date/DateTime.ts
#	tests/iso-date/DateTime.integration.test.ts
#	tests/iso-date/DateTime.test.ts
#	tests/iso-date/formatter.test.ts
graphql-iso-date operated on Unix timestamp values, but graphql-scalars operates on ECMAScript timestamps (number of milliseconds since January 1, 1970, UTC)
as decided in Urigo#387 (comment)

It has to be clear which is used. Certainly values are not Unix timestamps and all references must be removed.
Docs are updated.

ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#the_ecmascript_epoch_and_timestamps
@falkenhawk
Copy link
Author

falkenhawk commented Dec 9, 2022

@Urigo @ardatan I've rebased the branch and fixed all conflicts. (actually had to manually re-apply the changes over again which required significant effort, which would not be necessary if this PR had a chance to be addressed before i.a. #1764)

@wzrdtales
Copy link

bug bug @Urigo @ardatan

@kleinsch
Copy link

kleinsch commented Mar 2, 2023

@ardatan @Urigo How can we get this merged? This is a breaking change and violates the contract of this package: it's supposed to serialize a Date to a string using a consistent format, not serialize to a Date and rely on toString in the underlying platform to do it.

@theguild-bot theguild-bot mentioned this pull request Apr 24, 2023
37 tasks
value of ISO string representation of ECMAScript timestamp

Co-authored-by: Sumegh Ghutke <sghutke@mdsol.com>
@ardatan
Copy link
Collaborator

ardatan commented May 18, 2023

Thank you for the PR!
But we decided to introduce a new scalar that is based on string; LocalDateTime.
You can use it instead of DateTime if you want to deal with strings.

@ardatan ardatan closed this May 18, 2023
@ardatan
Copy link
Collaborator

ardatan commented May 18, 2023

I see you downvoted my comment. Could you explain what is the problem with the new scalar? It doesn't use JavaScript Date and it keeps DateTime as string like you expected?

@kleinsch
Copy link

@ardatan Nobody wants to deal with strings, but Date isn't a GraphQL type so we have to - https://graphql.org/graphql-js/basic-types/ . The purpose of this package is to convert JS types to GraphQL types. Date isn't a GraphQL type, so string serialization is necessary.

The issue flagged here is that a breaking change in this API takes deterministic APIs that used to convert dates to strings have now been moved to rely on platform toString behavior that's nondeterministic. You can add a new type, but that doesn't address the issue that you've punted core types like Date into nondeterministic behavior.

@ardatan
Copy link
Collaborator

ardatan commented May 29, 2023

Ok we introduced DateTimeISO scalar that serializes Date to string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Date parsing fails String versions of date scalars DateTime doesn't serialize a timestamp
6 participants