Uncaught Error: `new Date()` with non-number arguments is not supported.
I'm seeing this in a mutation where I'm trying to use date-fns timezone functions - is this specific to the convex runtime?
42 Replies
This does seem specific to convex. What I need to do is convert the utc time from
new Date()
to a given timezone. date-fns-tz
utcToZonedTime()
does this, but doesn't seem to work in this context. Let me know if anyone has an approach here.
For my use case I think I'm just going to bypass all this and pass the current date in ISO to the backend since I don't actually need the time. But a solution here may be helpful for others in the future.For now: related thread from #general (we should do a better job of moving those to here for searchability!): https://discord.com/channels/1019350475847499849/1171508877095874570/1171509623937835099
Is the library function failing internally? The work-around in that thread assumes you are the one passing the string to date
Yeah the library calls
new Date()
internally
but passes in a stringGotcha - we're chatting internally about the best course of action here. My understanding is that
new Date
has inconsistent behavior so we were trying to avoid it. From https://maggiepint.com/2017/04/11/fixing-javascript-date-web-compatibility-and-reality/:
When the time zone offset is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as local time. This is due to a historical spec error that was not consistent with ISO 8601 but could not be changed due to web compatibility.Maybe it's for other reasons too. but a library should be trusted to do the right thing, so we should probably offer some implementation rather than nothing
Temporal
will save us. But in like 2028 at this rate.
@ian update - I just upgraded date-fns itself, the core lib, from 2.x to 3.x. One of the key features is that it once again accepts string dates, allowing me to get rid of all of the date parsing and stringifying I was doing all over my app - but this error is now popping up everywhere.
From a prioritization standpoint, I'd offer that the convex runtime is more or less incompatible with the latest version of the top dates library.I'm getting the same when importing some data with let
let createdAt = '2020-12-07T23:34:56.860Z'
that i'm using new Date(createdAt)
. Now i'm trying with Date.parse(createdAt)
that workedJust giving this another bump, bit of a thorn in the side.
An opinion on the matter of how best to approach this given the flakiness of the API, it feels like matching Node's behavior is the most straightforward path. It fixes any library compatibility issues, brings exactly the same caveats folks would already have encountered in Node, and introduces no special cases that Convex would need to provide extra support for, as nothing Convex specific is happening.
Current sticking point:
- date-fns timezone support happens via date-fns-tz
- date-fns-tz inescapably attempts to parse a string date in their functions here: https://github.com/marnusw/date-fns-tz/blob/00b48b2cd4505a69203aac5734773114bce13204/src/_lib/tzTokenizeDate/index.ts#L71
Trying out the temporal polyfill to see if that can fix this, but there's a chance it's also using new Date() in similar ways internally.
For anyone else that runs into this, here's my solution for timezone support that should be consistent across various environments, including react native:
- date-fns for general date handling
- Temporal (the TC39 proposal, not the platform) for timezone support (will probably move to Temporal for everything at some point)
- using this polyfill, which feels closer to production readiness than the "main" one: https://www.npmjs.com/package/temporal-polyfill
I keep forgetting Convex has a competitor named Temporal. I'm not talking about that Temporal! lol
Update in the never ending saga: due to an incomplete iOS implementation of
formatToParts()
in the Intl
API, the React Native team decided to disable the method altogether, which breaks the Temporal polyfill. They have plans to address but aren't yet known to be working on it.@erquhart I tried making the changes to package using patch-package but its not reflecting when im runing locally i added multiple console log still cant see console log also I installed it properly and rerun the app still cant see the console logs
are you using npm, and do you have date-fns-tz 3.1.3
yes
"date-fns": "^3.6.0",
"date-fns-tz": "^3.1.3",
Did you add the postinstall script
I haven't seen patch-package silently fail to work in the times I've used it, so just asking basic questions here
Yes
did you actually run patch package? the postinstall script runs if you run npm install, otherwise you need to do
npx patch-package
.yes i did it created a file also then i did npm install and npm run dev
i also tried deleting nextjs cache folder
now im moving all my logic to action so i can use this package
yeah not sure why patch package isn't working for you, sorry I couldn't be of more help there
I got this issue on Convex too with dayjs
there is no solution at the moment 😢
We're still working on a fix, it's a pickle, but we should get there soon-ish.
@Michal Srb sorry to mention you, but do we have quick workaround or draft I can try to do hot fix on my project?
Reading this thread, I think you can try @erquhart's fix of patching the library to use Date.parse() instead of new Date() directly (you might need to expand the patch).
You can make the change manually in your node_modules to see whether it helps (you can also console.log from node_modules to debug what's going on)
well, I am using dayjs, but I got the point
the coming fix will fix Convex itself or a workaound as above?
It will fix the Convex runtime itself
@Michal Srb thanks, do we have estimation time which fix released?
No estimate, will update here when we do
ok thank you for your info
🙏
does this mean we fixed it?
No it's a plea 😅
just a bump to keep it non-stale. still feeling this one.
hahah nice way of bumping
lol it worked!
maybe
hopefully
xD
@erquhart we good now? https://discord.com/channels/1019350475847499849/1019372556693815418/1278869945513545849
LET'S GOOOOO 🎉🎉
lets gooooo
refacctoring started
Should
date-fns
v4 be supported with this change? In particular @date-fns/tz
?
I didn't receive any Convex runtime error when trying to import from @date-fns/tz
so I assumed it should work, but it doesn't seem to be working correctly.
It works as expected if code is placed within a Convex action, just not within a query/mutation.Convex runtime uses UTC, your local will use local time. The action/query difference is not something I would expect, though.
Oh I missed that you’re setting the timezone nvm
Action on convex runtime works or is it using Node?
I don't think the system time matters when using
TZDate
?. Yep, it works fine within a Convex action with "use node".Yeah I missed that you were setting the timezone. Sounds like v4 is relying on a platform API that works differently between the Convex runtime and Node, would have to trace through the function you’re calling to see what that might be.
If you find this let us know, this is important — we'd prefer that a library like this obviously didn't work rather behave unexpectedly differently on Convex. Here's our Date: https://github.com/get-convex/convex-backend/blob/main/npm-packages/udf-runtime/src/setup.ts#L74-L103
it sounds like we might need to do something different here, I filed this internally but if someone does sees what part of date-fns is broken by TZDate here we can get to it sooner
Thanks. I can work around the lack of
TZDate
support in mutations, but using Convex actions.
However, for Convex queries I have no suitable workaround because they can't be switched out with actions as easily - live subscriptions would be broken. I could setup a HTTP endpoint (using an action) but is starts to be loose a lot of the Convex benefits quickly.
Essentially, I want to fetch all orders
for the current day only (dependent on my merchant.timeZone
setting). Order date is store as a timestamp. Any suggestions how I do this using a Convex query?Would it work to calculate the timestamp for the current day outside of the query—e.g. using
TZDate
on the front end—then pass the value to the query function to get matching records using an index?That’s a good idea @Clever Tagline I’ll give it a go, thanks