0

I'm using fetch to send a date to the server. This should be an exact date (no time) because the server uses Java LocalDate there.

In my timezone a date like 2020-01-01 is stringified to 2019-12-31T23:00:00.000Z. The server then drops the time part. When converting to LocalDate, it doesn't know what timezone I'm in, I could be anywhere.

So I resorted to overriding Date.prototype.toJSON by a function that moves the date to UTC so that it is stringified as 2020-01-01T00:00:00.000Z. This is of course very ugly but at least it works.

Then I thought, let's override toJSON right before the request and reset it after the request returns. But whatever I tried (additional promises, timeouts), fetch uses the native toJSON. So this doesn't work:

    Date.prototype.toJSON = function () {
        return ... // Date moved to UTC. This works when set when the page loads.
    }

    const response = await fetch(...) // Fetch uses the native toJSON

    // Setting a breakpoint here reveals that toJSON is my version as expected. But fetch didn't use it.
    Date.prototype.toJSON = toJSON // Reset back to native

I read up on tasks and microtasks but found nothing that could explain this.

I also found no one with the same issue, so I'm probably going about this the wrong way.

So my questions:

  • How do I send a date in any time zone to the server such that it is properly converted to a LocalDate (other than globally overriding toJSON)?
  • How does fetch use the native toJSON if it is overridden right before? Just so I understand what is happening.
  • The server is built using the Micronaut framework, is there something we could change there? I can't think of anything but who knows.
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Jeroen Knoef
  • 275
  • 1
  • 2
  • 11
  • Far better to create your Dates with the correct values in the first place. If your dates are being stringified as UTC, then create them as such: `new Date(Date.UTC(2020, 0, 1))` should be stringified as "2020-01-01T00:00:00Z" (actually `new Date('2020-01-01')` should be treated as UTC too). – RobG May 08 '20 at 08:21
  • Yes that is right of course. But to present the date to the user we would have to use `getUTCFullYear` etc. Which is a bit of a burden. – Jeroen Knoef May 08 '20 at 14:18
  • There are many questions on Stack Overflow with answers on how to format a UTC date so that it appears correctly, using `toLocaleString`, for instance, with no need for `getUTCFullYear`. See [How to format a JavaScript date](https://stackoverflow.com/q/3552461/215552) for instance. There are also many libraries which can help. – Heretic Monkey May 08 '20 at 15:26
  • `toLocaleString` doesn't specifically format a UTC date, you still have to take into account that it's got a time component if it's not in your timezone. – Jeroen Knoef May 08 '20 at 19:31
  • @JeroenKnoef—UTC has no timezone, it's always +0, do you mean ISO 8601 like "2020-01-01T00:00:00.000+08:30" so it has the local offset? If so, then [*How to format a JavaScript date*](https://stackoverflow.com/questions/3552461/how-to-format-a-javascript-date?r=SearchResults&s=1|1450.4192) has your answer. – RobG May 08 '20 at 22:28

0 Answers0