Convert string to dd/mm/yyyy hh:mm format

Asked

Viewed 4,742 times

6

How can I convert a date that is string to a date type?

I tried to do it this way but it didn’t work:

var string = "19/07/2019 14:18"
var date = new Date(string);

When I give a console.log(date); shows me "invalid date".

  • 2

    In accordance with the MDN, when you pass a dataString to string shall be a format recognised by the Date.parse()

  • Here is the solution: https://answall.com/questions/6526/comorformatar-data-no-javascript

3 answers

7


You need to pass a date string in a valid format.

According to the documentation, between the various forms of instantiating a date, there is the option to pass a string. In this case:

A value of type String representing a date. The string must be a format recognized by the method Date.parse() (IETF-compliant RFC 2822 timestamps and also a version of ISO8601).

Thus, the easiest way is to convert your string (which is in the Brazilian format), to the ISO compliant format. In that case:

YYYY-MM-DDTHH:mm

In which:

  • YYYY represents the year;
  • MM represents the month;
  • DD represents the day;
  • T represents the separation between "date" and time;
  • HH represents the time of day;
  • mm represents the minutes of the hour.

Then we can create a function to convert the date:

// A data passada deve estar no padrão:
// DD/MM/YYYY HH:mm
function toISOFormat(dateTimeString) {
  // Primeiro, dividimos a data completa em duas partes:
  const [date, time] = dateTimeString.split(' ');

  // Dividimos a data em dia, mês e ano:
  const [DD, MM, YYYY] = date.split('/');

  // Dividimos o tempo em hora e minutos:
  const [HH, mm] = time.split(':');

  // Retornamos a data formatada em um padrão compatível com ISO:
  return `${YYYY}-${MM}-${DD}T${HH}:${mm}`;
}

console.log(toISOFormat('19/07/2019 14:18'));

Now that you have the means to convert the date, just instantiate it:

// A data passada deve estar no padrão:
// DD/MM/YYYY HH:mm
function toISOFormat(dateTimeString) {
  // Primeiro, dividimos a data completa em duas partes:
  const [date, time] = dateTimeString.split(' ');

  // Dividimos a data em dia, mês e ano:
  const [DD, MM, YYYY] = date.split('/');

  // Dividimos o tempo em hora e minutos:
  const [HH, mm] = time.split(':');

  // Retornamos a data formatada em um padrão compatível com ISO:
  return `${YYYY}-${MM}-${DD}T${HH}:${mm}`;
}

const dateString = toISOFormat('19/07/2019 14:18');
const date = new Date(dateString);

// Testando:
console.log(date.getFullYear());

It is important to say that there are many ways to build a date in Javascript. This answer addresses only one of several possibilities. To learn more, be sure to consult documentation of Date on MDN.

  • 4

    Why the negative?

  • my date is in this format 2019-07-19 19:46:00 but when I use it on the console.log(new Date(stringDate)) it returns invalid date the date is in the correct format ?

  • What is your browser and its version? Try instantiating the date in this format: new Date('2019-07-19T19:46:00'). Works?

4

As many have said, when you pass a string to the constructor Date, to documentation says this string must be in a format recognized by Date.parse. Any other format may result in an invalid date (or in indefinite behaviour, dependent on browser).

That being said, the format you are using is not among those cited in the documentation. An alternative would be to turn the string into one of the recognized formats, as already suggested by the other answers. But the constructor of Date can also receive the numeric values directly, so just extract them from the string:

let s = "19/07/2019 14:18";
let [dia, mes, ano, hora, minuto] = s.split(/[\/: ]/).map(v => parseInt(v));
let data = new Date(ano, mes - 1, dia, hora, minuto);
console.log(data);
console.log(data.getTime());

I used the regex [\/: ] (a bar, or two points, or space) to separate all fields at once (it’s kind of "naive", because if the string is "19 07:2019/14 18", also works - if you want to be narrower about the format, you can use the options suggested in the other answers).

Then use map with parseInt to turn each section into a number (since the split returns an array of strings) - so you already validate that each part is a number, since parseInt returns NaN if you do not receive a number, and the result will be an invalid date.

Also note that I had to subtract 1 from the month, since in this API the months are indexed to zero (January is zero, February is 1, etc).

In spite of this, the constructor accepts apparently invalid values, such as month 15, day 32, etc., and makes some automatic and "non-intuitive" adjustments (day 32 turns into day 1 of the following month, month 12 turns into January of the following year, etc.). So if you want, you can still include further validations before creating the date (if (1 <= dia && dia <= 31), etc) to ensure that values are actually valid.

Finally, I print the date and also the value of getTime(), who returns the respective timestamp. And here’s a very important detail...


What is the Date javascript

A Date Javascript actually represents a timestamp: the amount of milliseconds since the Unix Epoch (that is 1970-01-01T00:00Z, or 1 January 1970 at midnight, in UTC).

The detail is that the timestamp is "universal" in the sense of being the same all over the world (different from time zones, which in every part of the world can be a different date and time).

For example, on my machine, running the code above, the return of data.getTime() was 1563556680000. This timestamp represents a single instant, a point in the timeline. This exact instant, however, may represent a different date and time in each part of the world:

  • In Brasilia Time, is 19 July 2019, at 14:18
  • In Japan, it is 20 July 2019, 02:18 am
  • In UTC, it is July 19, 2019 at 5:18 pm

The same timestamp value (1563556680000) corresponds to all dates and times above. The instant (the point on the timeline) is the same, what changes is the value of the local date and time, according to the Timezone (time zone) you use.

And why am I saying all this? Because when I created the Date above passing the date and time values, it uses the browser Timezone to calculate the timestamp (and the browser, in turn, usually uses what is configured in the operating system). As my browser is using the Time of Brasilia, he understands that I am creating a date corresponding to 19/07/2019, at 14:18, in this Timezone.

But if I change my system’s Timezone (time zone) to Japan, Javascript will create a date corresponding to 07/19/2019, at 14:18 pm, in Japan’s time zone. And in this case, the value of getTime() will be 1563513480000 (a completely different value, since 19/07/2019, at 14:18 in Japan occurred in an instant other than 19/07/2019, at 14:18 in Brazil).

Of course, depending on what you are doing with the date, it may not make a difference. But as you said in the comments who wants to calculate the difference for the current date, it may make some difference.

A string "19/07/2019 14:18", for example, was generated in what time zone? If it’s the same one the browser is using, that’s fine, because you’ll be comparing dates and times in the same Timezone. But if they are different (for example, the browser is using the US zone, but the string refers to a time in Brazil - it has not been said where or how the string was generated, so it is not safe to assume that it necessarily used the same Timezone of the environment in which the Parsing occur), then the comparison may return an incorrect result.

If you use the code of Jorge’s response, for example, you will get a date of 19/07/2019 at 14:18 in UTC (that corresponds to timestamp 1563545880000, and at 11:18 on Brasilia Time). This is because he added the Z in the end, and this indicates that the date/time is in UTC. Already the solution by Luiz Felipe does not add the Z, then the date/time is interpreted using the browser’s Timezone (behaves like the constructor that receives the numeric values).


Another bizarre case: daylight saving time

Currently Brazil does not have daylight saving time, but as this is something defined by governments, there is no guarantee that this will not change in the future (and It usually changes all the time). Anyway, there are two situations involving daylight saving time that can cause some strange results by turning a string to date.

One is when daylight saving time begins. For example, in Brazil, on November 4, 2018, at midnight the clocks were put forward an hour. In many systems this was already automated, and in practice what happens is that the clocks automatically jump from 23:59:59.999 to 01:00. That means that every minute between midnight and 12:59 does not exist on this day, in this time zone. So what happens if we try to create a date exactly this day and time (the code below assumes that your system’s Timezone is configured with the Brasilia Time and it is updated with the rules of daylight saving time):

let date = new Date(2018, 10, 4, 0, 30);
console.log(date, date.getTime());

The resulting timestamp is 1541302200000, which corresponds to 11/04/2018, at 01:30 at Brasília Time (or 03:30 at UTC). Since 00:30 does not exist on this day (thanks to the "automatic jump" of daylight saving time), then Javascript automatically adjusts it to 01:30 (it’s as if it simulates someone looking at the clock, realizing that it forgot to put it forward and correcting the time). That is, if you receive the string "04/11/2018 00:30" and is using the Timezone of Brazil, this situation may occur if the date and time fall in this interval of minutes that are skipped (also called DST Gap - Daylight Saving Time Gap).

And when daylight saving time ends, the situation is just as strange. In 2018, for example, this occurred in February. On 18/02/2018, at midnight, the clocks are delayed back to 23:00 on the 17th. That means that every minute between 11:00 and 11:59 occurs two times (one in daylight saving time, another in "normal" time - this is called DST Overlap). So if you get the string "17/02/2018 23:30", which of the two occurrences will be created?

let date = new Date(2018, 1, 17, 23, 30);
console.log(date, date.getTime());

The resulting timestamp was 1518917400000, which corresponds to the first occurrence at 23:30 (still in daylight). If I want the second occurrence (after daylight saving time is over), I have to add one hour manually:

let date = new Date(2018, 1, 17, 23, 30);
date.setTime(date.getTime() + (1000 * 60 * 60));
console.log(date, date.getTime());

This can make a difference if you are going to calculate the difference with respect to the current date (in this case you can give one hour difference). Unfortunately the native Javascript API does not provide a better way to work with dates, and especially with time zones.


Moment js.

An alternative is to use the Moment js., an excellent API to work with dates. Example:

// transformar string em data
let data = moment("19/07/2019 14:18", "DD/MM/YYYY HH:mm");

// diferença em minutos para a data atual
let minutos = moment().diff(data, 'minutes');
console.log(minutos);

// se quiser um Date do JavaScript
let jsDate = data.toDate();
console.log(jsDate);
<script src="https://momentjs.com/downloads/moment.min.js"></script>

Moment.js also uses the browser Timezone and has the same behavior described above during the gaps and overlaps of daylight saving time, so the same points of attention already mentioned apply here.

If you want the dates to be in a specific time zone, you can use the Moment Timezone. With it you can control which time zone used for the date/time:

// data no horário de Brasília
let dataBr = moment.tz("04/11/2018 00:30", "DD/MM/YYYY HH:mm", "America/Sao_Paulo");
// data no fuso do Japão
let dataJp = moment.tz("04/11/2018 00:30", "DD/MM/YYYY HH:mm", "Asia/Tokyo");

// diferença em minutos para a data atual
console.log(moment().diff(dataBr, 'minutes'));
console.log(moment().diff(dataJp, 'minutes'));

// se quiser um Date do JavaScript
console.log(dataBr.toDate());
console.log(dataJp.toDate());
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="https://momentjs.com/downloads/moment-timezone-with-data.min.js"></script>

Notice how the difference in minutes and the Date corresponding is different depending on the Timezone used, since 04/11/2018 00:30 occurred at different times in Brazil and Japan. I don’t know if you’ll need to get to such a degree of preciousness, but anyway, "the devil is in the details," so there’s the option, if necessary.

The names of timezones ("America/Sao_paulo", "Asia/Tokyo") are defined by IANA Timezone Database. To find out what timezones are provided by Moment, use moment.tz.names().

1

  • this returned me Fri Jul 19 2019 11:49:00 GMT-0300 (Brasília Standard Time) &#Xa getTime() ? @Jorge Costa

  • running the example on the page the result is 2019-07-19T14:18:00.000Z"

Browser other questions tagged

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