How does date comparison using .toLocaleDateString ();

5

It's a question I have for some time and I can not find an answer anywhere on the internet (I looked here and SOen).

Given the following code:

var hoje = new Date(2018, 08, 07).toLocaleDateString();
var dataQualquer = '08/05/2018';
if(dataQualquer < hoje) console.log('sucess!');

if will return true because the date will be shorter. If I set the date to '08/05/2019' , I still get true . In short: .toLocaleDateString converts a date to string. You can compare this date with another date string, and it works to some extent (disregards the year, but compares day / month).

The question is: How does this work anyway? How does javascript compare two strings and return true or false depending on the value in them? I'm still new to programming compared to most on this site, but I understand that a filled string should be considered a true value, and therefore should always return true. And regardless of this, why do you compare days and months, but not years?

I know the question is long, but I really would like to know how this process works.

Thank you for your attention in advance.

    
asked by anonymous 07.08.2018 / 21:56

3 answers

5

Strings in Javascript are compared character by character, from left to right until the characters are not the same, or that no other letters to compare.

You can compare phrases:

"a" < "b" // true
"a" < "a" // false
"abc" < "aaa" // falso, porque b é maior que a
"abc" < "abd" // verdadeiro, porque c é menor que d

As well as numbers, although the result is not the same as comparing with numeric types.

"20" < "3" // verdadeiro, porque 2 é menor que 3
"50" > "100" // verdadeiro, porque 5 é maior que 1
"305" < "31" // verdadeiro, porque 1 é maior que 0

This happens because strings is compared Lexicographically , giving each character an order that can be compared.

  

You can compare this date with another date string, and it works   to some extent (disregards the year, but compares day / month).

The same thing happens when comparing two dates in the format string :

"21/09/2018" < "21/10/2018" // true porque 0 é menor que 9 (mês)
"21/09/2018" < "31/10/2019" // verdadeiro, porque 3 é maior que 2 (dia)
"21/09/2020" < "31/10/2019" // ainda verdadeiro, porque 3 continua maior que 2 (desconsiderando assim o ano)

Lastly, for comparison between dates, always use two objects of type Date , and note that to use the != and == operators you need to use the date.getTime();

var data1 = new Date();
var data2 = new Date(data1);

data1 == data2 // false, errado
data1 != data2 // false, errado
data1.getTime() == data2.getTime() // verdadeiro, correto
data1 > data2 // false, correto
data1 >= data2 // true, correto
data1 <= data2 // true, correto
    
07.08.2018 / 22:57
2
  

The question is : How does this work anyway? How does javascript compare two strings and return true or false depending on the value in them?

When comparing two strings "2" > "14" , "2" will be greater than "14", because (in order from left to right) that 2 is greater than 1, and likewise your "Se eu sibstituir a data por '08/05/2019', ainda recebo true" is due as above and explained below.

General rule

To calculate string comparisons, JavaScript converts each character of a string to its ASCII value . Each character, starting with the left operator, is compared to the corresponding character in the right operator.

In the following example, see that character 7 is less than 8, so according to the general rule, regardless of what comes after character 7 of the left operator and after the character 8 of the right operator, the expression will always be false.

Note that in your case this is a comparison of two strings.

var hoje = new Date(2018, 08, 07).toLocaleDateString();
console.log(typeof hoje); //string

var dataQualquer = '08/05/2018';
console.log(typeof dataQualquer); //string

console.log(hoje);        // 07/09/2018
console.log(dataQualquer); //08/05/2018

if (dataQualquer<hoje){
  console.log("verdadeiro");
}else{
  console.log("falso");  //8 não é menor que 7
}
  

See that JavaScript does not compare 7 to 8, but rather its ASCII values

7 corresponde a 055 em ASCII
8 corresponde a 056 em ASCII

NOTE: For numerical values, the results are the same as you would expect from your school algebra classes.

  

Easy, right? For numeric characters the ASCII values begin with 0 (048) and end with 9 (057).

Then

           | cada centena representa o valor ASCII de cada caractere
07/09/2018 | 048 055 047 048 057 047 050 048 049 056
08/05/2018 | 048 056 047 048 053 047 050 048 049 056
                 ---

For alphabetic characters is not so easy, see the example below

    if ("mateus" < "Mateus"){
       console.log("verdadeiro");
    }else{
       console.log("falso");
    }
mateus | 109 097 116 101 117 115
Mateus | 077 097 116 101 117 115
         ---
  

ASCII values for uppercase letters are smaller than the corresponding lowercase letters.

One of several solutions, for your case, is to use the order MONTH DAY

var hoje = new Date(2018, 08, 07).toLocaleDateString();
var dataQualquer = '08/05/2018';

 hoje = hoje.split("/").reverse().join("-"); //2018-09-07
 dataQualquer = dataQualquer.split("/").reverse().join("-"); // 2018-05-08
        

     if (dataQualquer<hoje){
       console.log("verdadeiro");
     }else{
       console.log("falso"); 
     }
 2018-09-07  | 050 048 049 056 045 048 057 045 048 055
 2018-05-08  | 050 048 049 056 045 048 053 045 048 056
                                       ---
    
08.08.2018 / 05:02
2

Unfortunately, javascript does not have native support (but why ?) for comparisons between dates, as @ Vinicius mentioned: the strings are compared one by one and for you to get differences between dates would have to use the Date () object of javascript (which gives a handle job).

There are also techniques built by developers around the world. Take a look in case of interest.

I'd particularly recommend moment.js . In this link there are also some examples explaining how to use the moment. js correctly and some characteristics of dates in javascript.

    
08.08.2018 / 14:45