Problem with Javascript date comparison

Asked

Viewed 100 times

3

I have a Javascript function that is to check if the "current data_is" is larger than "data_validity". If larger, it is to display on the screen the "Expired" text, if not, keep the "Valid" text".

What’s the matter? The function is considering only the day of the expiry date, and not the month and year. If the expiration date is longer than the current day, it displays "Valid", even if the expiration date is 2010 for example. I believe that the problem may have some relation because the validity is in the text format, in the database as Varchar.

Follow an example of the code: https://jsfiddle.net/ec0nugyq/

var data_validade = '20/03/2010'; // Simula a data de validade do banco de dados (VARCHAR)
var data_atual = moment(new Date()).format('DD/MM/YYYY'); // Captura a data atual no formato brasileiro - Ex: 14/03/2021

if (data_atual > data_validade) {
document.write('Expirado'); // Se a data atual for maior que a validade, exibe Expirado na tela
} else {
document.write('Válido'); // Se a data atual for maior que a validade, exibe Válido na tela
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>


In case anyone knows how to solve this in a simple way, I really appreciate it!

2 answers

1


It should be noted that the library Moment js. in his documentation discourages developers from including Moment js. in new projects.
In the library documentation the reasons for this are given.

As to the problem of the question this can be easily solved using the object Javascript native Date.

//Prepara a data para ser usada como argumento do constructo Date.
let data = '20/03/2010'.split("/").reverse();    //Separa os componentes da data e os coloca na ordem ano, mês e dia para ser consumida pelo constructor Date(ano, mês, dia).
data[1]--;                                       //Reduz em uma unidade o mês pois o constructor Date trabalha com meses de 0 até 11 onde mês 0 é janeiro.

let data_validade = new Date(...data);
let data_atual = new Date();

if (data_atual > data_validade) {
  document.write('Expirado');
} else {
  document.write('Válido');
}

The main problem with your code is that in:

if (data_atual > data_validade)

You are comparing two strings because at no time data_atual has been converted to an object that models time/dates and data_validade is the string representation of the current date obtained with moment(new Date()).format('DD/MM/YYYY');. So your comparison makes only the comparison between the characters of the two strings and not the dates themselves.

To fix the problem just work with objects only Date. To convert the string 20/03/2010 in a consumable form by the constructor new Date(ano, mês, dia, hora, minuto, segundo, milissegundo); the string was broken into its components using the method String.prototype.split() that divides a String in an ordered list of substrings and returns them in a Array [dia, mês, ano] and then reversed with the method Array.prototype.reverse() so that the format is consumed by the constructor new Date(ano, mês, dia, hora, minuto, segundo, milissegundo);. Then the month suffered a decrease of one unit as the date constructor operates with the month starting with 0 for January until 11 for December. This so that the array containing the date can be consumed by the constructor new Date(ano, mês, dia, hora, minuto, segundo, milissegundo); using the scattering syntax using only the first three parameters.
Apart from the above the rest of the code remains the same.

To make it easier to use, a function can be created that converts the string into the format dd/mm/YYY in an object Date here called ptBRStringToDate(s) where s is a string containing the date.

function ptBRStringToDate(s) {
  let data = s.split("/").reverse();
  data[1]--;
  return new Date(...data);
}

let listaDatas = ["10/03/2020", "10/03/2021", "10/03/2022"]
let data_atual = new Date();

for (let d of listaDatas) {
  let data_validade = ptBRStringToDate(d);
  document.write(`${d}: ${(data_atual > data_validade)? 'Expirado':'Válido'}<br>`);
}

  • 1

    Hi Augusto Vasques, thank you for your answer! I’m a beginner in programming, but I understand the problem now with your explanation, I managed to solve the problem still using Momentjs with isAfter which is an "easy" solution, but I confess that I will try to do as you mentioned, precisely due to the statement of the Moment to avoid using in new projects. Thanks!

  • @Gabriel-Skygr, If interest and fit your project in the statement they make suggestions of other libs to replace the Momentjs.

  • Perfect, I’ll take a look, thank you!

  • 1

    When the Temporal arrive, it will be so beautiful :)

  • 1

    @Cmtecardeal but this is the noun that means heavy rain I used the common adjective of two genera relative to chronological time.

-1

    var data_validade  = new Date('03/20/2021')     //dia expirado -> mm/dd/yyyy

    var data_atual = new Date();                    //tirando o dia de hj

    if (data_atual > data_validade) {           //comparando ambos em segundos
    document.write('Expirado'); // Se a data atual for maior que a validade, exibe Expirado na tela
    } else {
    document.write('Válido'); // Se a data atual for maior que a validade, exibe Válido na tela
    }

I got it this way :) Be careful with the string because the format is "mm/dd/yyyy"

  • Hello @Indexerror, thank you for the answer, the code actually works in Jsfiddle, but when implementing it in my project it does not respond as expected, yet it only considers the day. I tried using Momentjs, tried using pure Javascript with new Date(), changed the dates from VARCHAR to DATE in the database, but I still can’t identify when the month or year of validity is earlier than the current date.

  • found my code simpler and cleaner kkk'

Browser other questions tagged

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