Question on how to calculate time difference with special conditions

Asked

Viewed 822 times

1

I’m trying to figure out the time difference between two dates using the Moment.js, but I need to observe some special conditions:

Case 1: If you enter a day in a month, it already counts as "a whole month". By example: of the day 31/09/2015 until 01/10/2015 = 2 months. In another example, of 31/07/2015 until 16/10/2015 = 4 months.

In this last example, by Moment.js the result is 2 months (77 days). It follows a fiddle what forkei of posted by @Orion in the comments.

Update 2: I think I really got it now resolve this part a gambiarra (to using the moment.js and the split, so I call twice the same values... gambiarra this right??? ) follows the fiddle commented (I will not post the code here for now to question not get bigger yet, then put as answer if it does not appear a better/simpler solution)... /update

This above is a calculation, and this below is another, unrelated to each other (one is not the condition of the other, they are independent, although starting from the same principle - put a minimum limit of days to be considered a month).

Case 2: To count as a whole month you must have more than 15 days on month. For example: of the day 16/09/2015 until 14/10/2015 = 1 month (because only the month enters 09, since September has 31 days and we always consider the start day and end day. If it were up to 15/10/2015 it would be two months). In another example, of 31/07/2015 until 13/10/2015 = 2 meses (as they did not reach 15 days, neither July nor October enter).

In PHP I managed with a huge gambiarra, breaking the dates with explode and making hundreds if's to differentiate months of 30, 31 and 28 days. As in this case the period was not more than one year, so it worked. But here in this case it has to be in the client (in or ), and the difference can be several years.

What I’ve done so far is this:

function result(e) // pega os dados do form
{
    e.preventDefault();
    var a = document.getElementById("data1").value; // INÍCIO
    var b = document.getElementById("data2").value; // FIM

    // DIFERENÇA EM DIAS DIAS DO DIA INICIAL X FINAL 

    var checkin = moment(a, 'DD-MM-YYYY');
    var checkout = moment(b, 'DD-MM-YYYY');
    var meses = checkout.diff(checkin, 'months');

    if (meses > 0) {

        $('#meses').html(meses);
    }
}

The output here, with dates between 10/10/2010 and 09/10/2011 is 11, and only if you complete a whole month becomes 12 (on 10/10/2011).

How can I solve this to achieve both logics (with only one day, or at least 15), considering the "real" months (not the calendar month - 30 days)? Can be with or without library (the moment.js or other). Thanks in advance.

  • 1

    I didn’t quite understand these rules that you put, but I created a link here http://jsfiddle.net/71adur8e/ so that you have a fresh head to make the logic.

  • Thanks @Orion, I forgot to create the fiddle! So, the logic is simple, but as the cases were together in a single quote I think it was really confusing. They are two different cases: in one calculation, I need to consider a month even if I only have one day. In the other, I need to have at least 15 days. I’ll edit the question. Thanks anyway.

  • @ Orion, I think I found a way to solve the first case (more or less the same way I did in php) using the split. Check it out > http://jsfiddle.net/gustavox/s28Lp779/11/. I haven’t tested it extensively yet, but from the tests here I think it’s okay. Now the second part needs to consider the months of 31 days and such (to see if it was 15), so I see here now...

  • Nah, forget it, it’s not right yet... I’ll have to add a few more ifs ... rsrs

1 answer

2


following, follows a possibility:

In caso1 it is very simple, just subtract the beginning month of the end month and add 1. Already the case 2 it is necessary to know how many days has the beginning month, but there is a Trick in Javascript to know this value.

var dataInicio = document.getElementById("dataInicio");
var dataTermino = document.getElementById("dataTermino");
var caso1 = document.getElementById("caso1");
var caso2 = document.getElementById("caso2");

var onInputChange = function (event) {
  var datas = {
    Inicio: new Date(dataInicio.value),
    Termino: new Date(dataTermino.value),
  }
  //verificando se ambas as datas são validas e a data de termino é posterior a de inicio.
  if (!isNaN(datas.Inicio) && !isNaN(datas.Termino) && datas.Termino > datas.Inicio) {
    var dtInicio = { 
      dia: datas.Inicio.getUTCDate(), 
      mes: datas.Inicio.getUTCMonth(),
      ano: datas.Inicio.getUTCFullYear()
    };
    var dtTermino = { 
      dia: datas.Termino.getUTCDate(), 
      mes: datas.Termino.getUTCMonth(),
      ano: datas.Termino.getUTCFullYear()
    };        
    dtInicio.totalDias = new Date(dtInicio.ano, dtInicio.mes + 1, 0);
    
    var qtdMesesCaso1 = dtTermino.mes - dtInicio.mes  + 1;
    qtdMesesCaso1 += (dtTermino.ano - dtInicio.ano) * 12
    
    var qtdMesesCaso2 = qtdMesesCaso1;
    if (dtInicio.totalDias < dtInicio.dia + 15)
      qtdMesesCaso2--;
    if (dtTermino.dia < 15)
      qtdMesesCaso2--;

    caso1.textContent = qtdMesesCaso1 + " Meses";
    caso2.textContent = qtdMesesCaso2 + " Meses";
  } else {
    caso1.textContent = "";
    caso2.textContent = "";
  }

}

dataInicio.addEventListener("change", onInputChange);
dataTermino.addEventListener("change", onInputChange);
<div>
    <label>
        Data Inicio:
        <input id="dataInicio" type="date" />
    </label>
</div>
<div>
    <label>
        Data Termino:
        <input id="dataTermino" type="date" />
    </label>
</div>
<div>
    Caso 1: <span id="caso1"></span>
</div>
<div>
    Caso 2: <span id="caso2"></span>
</div>

  • +1 Thanks man, it seems very simple... but I’m still learning Javascript, so I’m trying to understand the code here... I’ll try to create a fiddle with it to test... I saw that you used the input=time, but I need to use how text. Is it compatible? And in case 1 you said you only need to subtract the initial month from the end and add up + 1, but this in the code that you are working only works if the years are equal. In your code it sums up the months of previous years? If you take a look at this fiddle...

  • I didn’t understand these variables caso 1 and caso 2... I have nothing to pick up for them in the form. The dates are compared and in case 1, if you have a day already counts a month (and this number goes to a variable), and in case 2 you need to have 15 (and this goes to another variable), but you don’t have to take the form to create these variables...

  • really didn’t think about the case of different years

  • Giving a little more context, this calculation is to evaluate the right to unemployment insurance. So, when the person has 1 day of work in the month, it already counts as a "month of salary received" (and has an X amount to be entitled every time the insurance is claimed). This is to assess if the person is entitled. So just have worked a single day in the month, for this month already enter the account. Now to know how many installments a person is entitled, so you need to count differently (yes, it’s for !#$%$% same), and in this case the month only comes if it was worked at least 15 days.

  • Months need to be considered individually. No matter the total time elapsed, only each month individually considered.

  • 1

    @gustavox forgot to da a up, but I edited the answer.

Show 1 more comment

Browser other questions tagged

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