-2

I've an API that returns birthdate as 2020-11-24T00:00:00 to a React app. That react app uses that portion to display it:

new Date("2020-11-24T00:00:00").toLocaleDateString();

The issue is that on my browser and all browsers I have seems to give no issue: date is correclty shown. One or two customer complains about ir because they see the date 23/11/2020 (one dat before). I cannot reproduce the bug.

As I understood, Dates can be interpreted by browser as Zulu date so browser can translate the date from GMT+0 to browser's region. Right. Now I have to try to reproduce the bug in order to fix it and And I simply cannot because of misunderstanding.

First postulate: Date("2020-11-24T00:00:00") is going wrong, let's try that: fiddle => no, I cannot reproduce with my browser

Second postulate: .toLocaleDateString() is going wrong, let's try that: [fiddle][2] => no, I cannot reproduce with my browser when changing Location in Chrome.

How can I reproduce the issue in order to fix it?

clement
  • 4,204
  • 10
  • 65
  • 133
  • 2
    Because your date format has no time zone information, browsers will interpret the time string as meaning *local time*. That means that if you and your server are in Europe and the client browser is in Japan, the server and the client will be thinking in terms of points in time separated by hours. – Pointy Feb 02 '23 at 15:17
  • 1
    Adding `Z` to the end of the time string will make it interpreted as utc time zone `2020-11-24T00:00:00Z` – Konrad Feb 02 '23 at 15:18
  • @Pointy how to deal with my birthdate? Even if you turn aroubd the globe, birthdate won't change.. – clement Feb 02 '23 at 17:22
  • @Konrad right but it is a birthdate. My passeport birthdate doesn't change even if I'm moving... – clement Feb 02 '23 at 17:23
  • Your time string is what's called a "date-time" string. If you construct a Date instance from a string that is *only* the date, then the browser interprets it as UTC. But because you have a time, it assumes the local time zone. Time is complicated, and you have to decide what the time means: is it something about processing that happens at your server, or is it about something relative to the client? Even then, it's not easy. If I want to open a bottle of champagne at midnight on your birthday, when should I do that? – Pointy Feb 02 '23 at 17:29
  • Per ECMA-262, "2020-11-24T00:00:00" should be parsed as local and represent midnight at the start of 24 November, 2020 regardless of system regional settings. It may be that the erroneous systems are parsing it as UTC, hence the date appears to be 1 day earlier. Have those clients display the date using *toString* and check if the time has been changed by an amount that is the same as their timezone offset. – RobG Feb 02 '23 at 20:53

1 Answers1

0

The current ECMAScript standard obliges your example date string to be interpreted as a local date/time, because the time part is included and the timezone part is not.

Through time the rules for parsing strings have become a bit more standardized, but older JavaScript engines may behave differently. See for instance a post from 2013 or 2017 where a difference was reported (at that time). It is likely that some of your users run that JavaScript on much older engines which interpret this type of date string as UTC (as if suffixed by "Z").

Mozilla Contributors write about using Date.parse (which uses the same parser as when the string is passed to the constructor):

Note: Parsing of strings with Date.parse is strongly discouraged due to browser differences and inconsistencies.

To remove all ambiguity also for older browsers, parse the string yourself:

var dateStr = "2020-11-24T00:00:00";
var dateArr = dateStr.match(/\d+/g);
var date = new Date(dateArr[0], dateArr[1]-1, dateArr[2]); // Add time parts if needed

// Guaranteed to be reporting on the 24th of November 2020 (in locale format)
console.log(date.toLocaleDateString()); 
trincot
  • 317,000
  • 35
  • 244
  • 286
  • "*Parsing of strings with `Date.parse` is strongly discouraged*" - using ISO format (with `Z` suffix) does work in all browsers though, and is the recommended approach. The browsers that didn't support this format decades ago are long dead. (Admittedly the OP doesn't have a timestamp, if they really want a timezone-dependent date, your code is the way to go) – Bergi Feb 03 '23 at 10:37
  • Well, that is the thing here... The asker has a string without "Z" and expects it to be interpreted as locale time. Are you *absolutely* sure there isn't one around that is not supporting this format? – trincot Feb 03 '23 at 10:39
  • Yes, absolutely. ([Not accounting for museums](https://stackoverflow.com/questions/5802461/javascript-which-browsers-support-parsing-of-iso-8601-date-string-with-date-par)) – Bergi Feb 03 '23 at 10:43
  • There are people whose PC is like a museum -- never upgrading anything. But the question here is about a format that comes without "Z" – trincot Feb 03 '23 at 10:48