Home > front end >  Why new Date("2022-08-31").toISOString() is shown as 2022-08-30T18:30:00.000Z in console.l
Why new Date("2022-08-31").toISOString() is shown as 2022-08-30T18:30:00.000Z in console.l

Time:09-15

I am sending a request to server as a date value in following format in Javascript.

new Date(year "-" month "-" "31").toISOString()

But when I log it in the console like

console.log( new Date(year "-" month "-" "31").toISOString())

It shows value as

2022-08-30T18:30:00.000Z

This is causing a serious trouble as I can not get records from database of date 31 of "some month" and "some year" as the date 31st is converted to 30 as shown above. How to overcome this problem?

CodePudding user response:

How an ECMAScript implementation parses dates is, in general, implementation-defined. The only requirement in the specification is that parsing a timestamp at one-second granularity should round-trip losslessly through Date.prototype.toString(), Date.prototype.toISOString() and Date.prototype.toUTCString(). In particular, parsing formats other than those output by those functions need not even succeed. And even if it does succeed, there is no telling if the host will interpret the date as UTC or in the local time zone. There is a proposal underway to establish a broader interoperability surface, but it’s moving slowly.

In practice, implementations are rather lenient when it comes to date formats, so if you want your dates consistently interpreted as in the UTC time zone, appending "Z" or " GMT" to the string will probably suffice. You can also look up what date formats are commonly supported in the proposal repository.

However, if you want to be sure your dates will parse consistently everywhere, better do it by hand. Especially so if you do it in a browser: at the very least until the proposal lands (and maybe a while after that), you never know what crazy browser your code may end up running under.

CodePudding user response:

Why does new Date("2022-8-31").toISOString() change the date to 2022-08-30?

First, note that the behavior of new Date(string) depends on the exact format of the string:

  • If the format is YYYY-MM-DD, where MM and DD are both two digits, then the date is treated as UTC. For example, new Date("2022-08-31") returns 2022-08-31 00:00:00 UTC.
  • If the format is YYYY-M-DD, where M is one digit, then the date is treated as local, at least in all popular browsers. (Technically, the behavior is up to the browser.) For example, new Date("2022-8-31") returns 2022-08-31 00:00:00 05:30 if you're in India.

In your case, it looks like month is either the number 8 or the string "8", not the string "08", so the date is treated as local.

Second, note that toISOString always returns a UTC date string. The conversion from midnight local time to UTC may adjust the date component one day forward or backward depending on the local time zone. For example, 2022-08-31 00:00:00 05:30 is converted to the equivalent 2022-08-30 18:30:00 UTC.

How can I fix this?

Either ensure you pass a zero-padded date to new Date(string), or better yet, avoid date parsing altogether:

new Date(Date.UTC(year, month - 1, day)).toISOString()
  • Related