How to convert a date format to ISO 8601 in Javascript?

Asked

Viewed 662 times

1

I have here a code that performs a Javascript operation. It determines the maximum date of birth that can be entered in a form. The rule is that you can only register if you are 18 and older.

var d = new Date();
var year = d.getFullYear();
var month = d.getMonth();
var day = d.getDate();
var dtMax = new Date(year - 18, month, day);

How to pass this date of Wed May 03 2000 00:00:00 GMT-0400 (EDT) for 2000-05-03 - ISO 8601?

The method toISOString() should return the desired value. This value will be used to limit the maximum date of a datepicker.

Note: to clarify the question, the ultimate goal can be achieved with this code:

var yearMax = dtMax.getFullYear();
var monthMax = dtMax.getMonth();
var dayMax = dtMax.getDate();
var strMax = yearMax+"-"+monthMax+"-"+dayMax;

I want to know if there’s any more direct way.

Here the fiddle.

2 answers

3


The method toISOString() returns a string containing both date and time, so an alternative would be to simply take the part that matters, using substr:

let d = new Date();
d.setFullYear(d.getFullYear() - 18);
console.log(d.toISOString().substr(0, 10));


Use toLocaleDateString(), as suggested by another answer, will not always work, because this method uses the locale ("language") that is configured in the browser to know which format to use.

And depending on the locale, not always the format will be "day/month/year". For browsers configured with American English, for example, the date is returned in the "month/day/year" format, and without the left zero for values less than 10 (i.e., if the date is March 1, 2000, the result will be 2000-1-3). Other locales return fields in another order (such as "year/month/day"), while others use characters other than the bar as separators. That is, the use of this method does not guarantee that the final result will be the correct one.

One option is to force a locale which has the desired format:

let d = new Date();
d.setFullYear(d.getFullYear() - 18);
console.log(d.toLocaleDateString('pt-BR').split("/").reverse().join("-"));

The locale pt-BR has the date format "day/month/year" with values less than 10 filled with a zero on the left, which ensures that this method will work.

However, there are still some situations where this may fail. If the browser does not have the locale pt-BR installed, it ends up using the default. Or it can also happen - although I think it’s a little rarer - of the format corresponding to the locale change (since it is preset and you have no control over it - see more about this at the end of this reply).

Another detail is that toISOString() returns the date/time on UTC, while toLocaleDateString() returns the date according to the Timezone set up in the browser (that is, depending on the Timezone set and the time of the day the code runs, these methods can return a different date). But if you want, you can make toLocaleDateString() return date in UTC:

let d = new Date();
d.setFullYear(d.getFullYear() - 18);
console.log(d.toLocaleDateString('pt-BR', { timeZone: "UTC" }).split("/").reverse().join("-"));

Anyway, these are the options that Javascript’s native date API gives us, so choose the one you think best.


There is still another problem in the above code. If the date is February 29:

// lembrando que em JavaScript janeiro é zero, fevereiro é 1, etc
let d = new Date(2016, 1, 29); // 29/02/2016
d.setFullYear(d.getFullYear() - 18);
console.log(d.toISOString().substr(0, 10)); // 1998-03-01
console.log(d.toLocaleDateString('pt-BR').split("/").reverse().join("-")); // 1998-03-01

By subtracting 18 years from 02/29/2016, the result is 1 March 1998. But someone who was born on 03/01/1998 is not yet 18 years old on 02/29/2016 (still missing a day for the birthday), so this should not be a valid date to be shown in your form (a solution would be to show 02/28/1998). Unfortunately Javascript does not have an automatic way to make this adjustment, so this is a case where you should manually check.


Moment js.

An alternative to the native API is the library Moment js.. It makes it easy to do what you need:

let d = moment(); // data atual
d.subtract(18, 'years'); // menos 18 anos
console.log(d.format('YYYY-MM-DD')); // mostrar no formato ano-mês-dia
<script src="http://momentjs.com/downloads/moment.min.js"></script>

Even for the case of February 29, it already makes the adjustment automatically:

let d = moment([2016, 1, 29]); // 29/02/2016
d.subtract(18, 'years'); // menos 18 anos
console.log(d.format('YYYY-MM-DD')); // 1998-02-28
<script src="http://momentjs.com/downloads/moment.min.js"></script>

1

I don’t know if shortening a line in the code is more direct :D

var d = new Date();
d.setFullYear( d.getFullYear() - 18 );
var newdate = (d.toLocaleDateString()).split("/").reverse().join("-");
console.log(newdate);

  • This funssiona Verse well with split.

  • Has: . = .; console.log(.);

  • Aha.. to kidding... man, I don’t think there’s any way to reduce no more... it’s already good enough

Browser other questions tagged

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