Problems with correct return date with "new date()"

Asked

Viewed 369 times

0

let dataSTR = '1988-03-01'
let data = new Date(dataSTR)
let dataTimestamp = new Date(dataSTR).getTime()
console.log('[dataSTR]', dataSTR);
console.log('[Timestamp]', dataTimestamp);
console.log('[new Date]', data);
console.log('[formato Desejado]', `${data.getFullYear()}-${(data.getMonth())}-${data.getDate()}`);

The problem is basically the "[format Desired]"

Even though I added "+1" to getMonth() it returns the date with one day less

let dataSTR = '1988-03-01'
let data = new Date(dataSTR)
let dataTimestamp = new Date(dataSTR).getTime()
console.log('[dataSTR]', dataSTR);
console.log('[Timestamp]', dataTimestamp);
console.log('[new Date]', data);
console.log('[formato Desejado]', `${data.getFullYear()}-${(data.getMonth()+1)}-${data.getDate()}`);

  • someone can explain why when I change the string dataSTR = '1988-03-01' for dataSTR = '1988-03-1' the "[Format Desired]" works correctly?

1 answer

5


According to the documentation, when a string is passed to the constructor of Date, it accepts the same formats accepted by Date.parse. This method, in turn, follows some rules.

When the string has only the date (year, month and day) in the format "YYYY-MM-DD" (which is the format defined by ISO 8601 standard), to documentation says this is interpreted as UTC (moreover, the time is considered to be midnight).

The problem is that the methods getters (as getMonth(), getDate(), etc), return the values according to the browser’s Timezone (which usually follows the time zone configured in the operating system).

In my case, for example, my browser is configured with the Brasilia Time. When creating new Date('1988-03-01'), I’m actually saying that the date is "March 1, 1988 at midnight in UTC". And March 1, 1988 at midnight in UTC corresponds to February 29 at 9:00 in Brasilia Time.

When using the getters, the values returned correspond to the Timezone of the browser (that will not always be equal to UTC), so gives this "1 day difference". Ex:

let data = new Date('1988-03-01');
// meu browser está no Horário de Brasília, o resultado pode variar de acordo com a config do seu
console.log(`${data.getFullYear()}-${(data.getMonth()+1)}-${data.getDate()}`); // 1988-2-29


Fortunately, there are methods to obtain the values according to UTC (such as getUTCMonth, getUTCDate, etc.):

let data = new Date('1988-03-01');
console.log(`${data.getUTCFullYear()}-${(data.getUTCMonth()+1).toString().padStart(2, '0')}-${data.getUTCDate().toString().padStart(2, '0')}`); // 1988-03-01

I also used padStart to set zero to the left of the month and day (so is written 03 instead of 3).


As to the your comment, that "works" when the string is 1988-03-1, actually it depends on the browser.

According to this part of the Ecmascript specification: "if the string does not conform to this format, any heuristic or implementation-specific format can be used."

In this case, "this format" refers to ISO 8601, which defines that the day and month are always written with 2 digits. So when the string is 1988-03-1 (the day with only 1 digit), the format is no longer ISO 8601, and therefore each browser can interpret in a different way. Chrome ends up considering that the date is in the browser Timezone, and the getters end up returning the correct result. But in Firefox, it keeps considering UTC, and the error occurs the same way (see a more detailed discussion about these differences here).

  • Solved my problem, thank you !

Browser other questions tagged

You are not signed in. Login or sign up in order to post.