Javascript converting wrong date

Asked

Viewed 2,211 times

3

I need to convert date of type yyyy-mm-dd for dd/mm/yyyy. For this, I’m using the function in Javascript:

  data_formatar = new Date("2019-01-15")
  data = data_formatar.toLocaleDateString('pt-BR');

They could inform me why the above return is bringing 14/01/2019 and not 15/01/2019? And how to solve this problem?

4 answers

6


This code is bringing the day before, because you are only passing the date, without informing the time.

Thus the date is as follows:: 15/01/2019 00:00:00.

And as the standard Timezone of Brazil, has GMT -3 hours, as it should probably be configured on your machine, is subtracted 3 hours from the time it got, staying now 14/01/2019 21:00:00.

To fix this you can do in the following ways:

  • Passing the standard Timezone:
data_formatar = new Date("2019-01-15")
  .toLocaleDateString('pt-BR', {timeZone: 'UTC'});
console.log(data_formatar); // 15/01/2019
  • Or also informing the time:
data_formatar = new Date("2019-01-15 00:00:00")
  .toLocaleDateString('pt-BR');
console.log(data_formatar); // 15/01/2019

Useful links: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

I hope I’ve helped!

  • Being a bit pedantic: actually the locale only controls the format (if it is d/m/y, y-m-d, etc). But the values date and time come from the browser Timezone, so much so that it is done new Date("2019-01-15").toLocaleDateString('ja-JP') (locale of Japan), the value of the day continues 14, even if in Japan the equivalent date is 15 (because they are in UTC+9) - will only change the format, the values will not. And depending on the region of Brazil, will not necessarily be UTC-3: if it is regions with daylight saving time, in January is -2 (southeast) or -3 (center west), if it is in the northeast is -3, but in the Amazon is -4, etc :-)

  • 1

    Yes, true friend. I got confused locale with timeZone. Thanks for the warning!

1

1

When you pass a string in this format to the builder of Date, he uses the same method rule Date.parse().

In this case, the string contains only day, month and year in format ISO 8601, and this information is completed with the time of midnight, at UTC.

The problem is that toLocaleDateString uses the browser Timezone (which will not necessarily be the same as UTC) to get the values of the day, month and year. My browser, for example, is using the Brazilian time zone (Official Time of Brasilia).

And as 15 January 2019, at midnight in UTC, corresponds to 14 January 2019, at 22h in Brasilia time, this difference occurs (normally the Brasilia time is 3 hours behind the UTC, but in January 2019 it was in daylight time, so it was only 2 hours less, and depending on the region you are in, the difference with the UTC may have another value - anyway, your browser’s Timezone is some that is a few hours before UTC, hence the difference).

Some solutions (besides setting Timezone to UTC, as already suggested in the other answers):


Add time (ugly, but suggested by the documentation itself and it works, because then it starts to consider midnight in the browser Timezone):

let d = new Date("2019-01-15T00:00");
console.log(d.toLocaleDateString('pt-BR')); // 15/01/2019

Remembering to put the lyrics T before the time, in the format defined by ISO 8601 standard.


Do the Parsing manually:

let [ano, mes, dia] = '2019-01-15'.split('-').map(v => parseInt(v));
let d = new Date(ano, mes - 1, dia);
console.log(d.toLocaleDateString('pt-BR'));

// Ou, caso o seu browser não seja compatível com ES6:
let partes = '2019-01-15'.split('-');
ano = parseInt(partes[0]);
mes = parseInt(partes[1]);
dia = parseInt(partes[2]);
d = new Date(ano, mes - 1, dia);
console.log(d.toLocaleDateString('pt-BR'));

Remembering that in this API January is zero, February is 1, etc, so you have to subtract 1 of the month when passing to the constructor of Date.


Using a library like Moment js.:

let d = moment("2019-01-15");
console.log(d.format("DD/MM/YYYY"));
<script src="https://momentjs.com/downloads/moment.min.js"></script>

Or, to use the specific format according to the locale, use the moment-with-locales:

moment.locale('pt-BR'); // setar o locale para Português
let d = moment("2019-01-15");
console.log(d.format("L"));
<script src="https://momentjs.com/downloads/moment-with-locales.min.js"></script>

0

Opa Willian, this happens due to the time zone, by default the time zone is UTC, when changing the location toLocaleDateString takes over the local time zone. Because you do not set time he assumes it is midnight and shortens the hours, do it this way so that this problem does not happen:

data_formatar = new Date("2019-01-15")
data = data_formatar.toLocaleDateString('pt-BR', {timeZone: 'UTC'});

Browser other questions tagged

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