Domanda

Come faccio a capire la differenza per due Date () oggetti in JavaScript, mentre solo restituire il numero di mesi nella differenza?

Qualsiasi aiuto sarebbe grande:)

È stato utile?

Soluzione

La definizione di "il numero di mesi nella differenza" è soggetta a un sacco di interpretazione. : -)

È possibile ottenere l'anno, il mese e il giorno del mese da una data oggetto JavaScript. A seconda di quali informazioni che stai cercando, è possibile utilizzare quelli per capire quanti mesi sono tra due punti nel tempo.

Per esempio, off-the-bracciale, questo scopre quanti mesi interi si trovano tra due date, senza contare i mesi parziali (ad esempio, escluso il mese ogni data è in):

function monthDiff(d1, d2) {
    var months;
    months = (d2.getFullYear() - d1.getFullYear()) * 12;
    months -= d1.getMonth() + 1;
    months += d2.getMonth();
    return months <= 0 ? 0 : months;
}

monthDiff(
    new Date(2008, 10, 4), // November 4th, 2008
    new Date(2010, 2, 12)  // March 12th, 2010
);
// Result: 15: December 2008, all of 2009, and Jan & Feb 2010

monthDiff(
    new Date(2010, 0, 1),  // January 1st, 2010
    new Date(2010, 2, 12)  // March 12th, 2010
);
// Result: 1: February 2010 is the only full month between them

monthDiff(
    new Date(2010, 1, 1),  // February 1st, 2010
    new Date(2010, 2, 12)  // March 12th, 2010
);
// Result: 0: There are no *full* months between them

(Si noti che i valori di mese in JavaScript iniziano con 0 = gennaio.)

Tra cui mesi frazionali in quanto sopra è molto più complicato, perché tre giorni in una tipica Febbraio è una frazione più grande di quel mese (~ 10,714%) di tre giorni nel mese di agosto (~ 9,677%), e, naturalmente, anche Febbraio è un bersaglio mobile a seconda che si tratti di un anno bisestile.

Ci sono anche alcuni data e ora librerie disponibili per JavaScript che probabilmente fanno questo genere di cose più facili.

Altri suggerimenti

Se non si considera il giorno del mese, questo è di gran lunga la soluzione più semplice

function monthDiff(dateFrom, dateTo) {
 return dateTo.getMonth() - dateFrom.getMonth() + 
   (12 * (dateTo.getFullYear() - dateFrom.getFullYear()))
}


//examples
console.log(monthDiff(new Date(2000, 01), new Date(2000, 02))) // 1
console.log(monthDiff(new Date(1999, 02), new Date(2000, 02))) // 12 full year
console.log(monthDiff(new Date(2009, 11), new Date(2010, 0))) // 1

Essere consapevoli del fatto che l'indice mese è basato su 0. Ciò significa che January = 0 e December = 11.

A volte può essere utile per ottenere solo la quantità dei mesi tra due date ignorando totalmente la parte giorno. Così, per esempio, se si ha due date-2013/06/21 e il 2013/10 / 18- e si cura solo le parti 2013/06 e 2013/10, qui ci sono gli scenari e le possibili soluzioni:

var date1=new Date(2013,5,21);//Remember, months are 0 based in JS
var date2=new Date(2013,9,18);
var year1=date1.getFullYear();
var year2=date2.getFullYear();
var month1=date1.getMonth();
var month2=date2.getMonth();
if(month1===0){ //Have to take into account
  month1++;
  month2++;
}
var numberOfMonths; 

1. Se si desidera solo il numero dei mesi tra le due date escluso sia month1 e month2

numberOfMonths = (year2 - year1) * 12 + (month2 - month1) - 1;

2. Se si desidera includere uno dei mesi

numberOfMonths = (year2 - year1) * 12 + (month2 - month1);

3. Se si desidera includere entrambi i mesi

numberOfMonths = (year2 - year1) * 12 + (month2 - month1) + 1;

Ecco una funzione che fornisce con precisione il numero di mesi tra 2 date.
Il comportamento predefinito conta solo mesi interi, per esempio 3 mesi e 1 giorno si tradurrà in una differenza di 3 mesi. È possibile evitare questo impostando il parametro roundUpFractionalMonths come true, quindi una differenza 3 mesi e 1 giorno sarà restituito come 4 mesi.

La risposta accettata sopra (risposta di T.J. Crowder) non è esatto, restituisce valori errati a volte.

Per esempio, monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015')) restituisce 0 che è ovviamente sbagliato. La differenza corretta è o 1 mese intero o 2 mesi arrotondato-up.

Ecco la funzione che ho scritto:

function getMonthsBetween(date1,date2,roundUpFractionalMonths)
{
    //Months will be calculated between start and end dates.
    //Make sure start date is less than end date.
    //But remember if the difference should be negative.
    var startDate=date1;
    var endDate=date2;
    var inverse=false;
    if(date1>date2)
    {
        startDate=date2;
        endDate=date1;
        inverse=true;
    }

    //Calculate the differences between the start and end dates
    var yearsDifference=endDate.getFullYear()-startDate.getFullYear();
    var monthsDifference=endDate.getMonth()-startDate.getMonth();
    var daysDifference=endDate.getDate()-startDate.getDate();

    var monthCorrection=0;
    //If roundUpFractionalMonths is true, check if an extra month needs to be added from rounding up.
    //The difference is done by ceiling (round up), e.g. 3 months and 1 day will be 4 months.
    if(roundUpFractionalMonths===true && daysDifference>0)
    {
        monthCorrection=1;
    }
    //If the day difference between the 2 months is negative, the last month is not a whole month.
    else if(roundUpFractionalMonths!==true && daysDifference<0)
    {
        monthCorrection=-1;
    }

    return (inverse?-1:1)*(yearsDifference*12+monthsDifference+monthCorrection);
};

Se avete bisogno di contare mesi interi, a prescindere del mese di essere 28, 29, 30 o 31 giorni. Qui di seguito dovrebbe funzionare.

var months = to.getMonth() - from.getMonth() 
    + (12 * (to.getFullYear() - from.getFullYear()));

if(to.getDate() < from.getDate()){
    months--;
}
return months;

Questa è una versione estesa della risposta https://stackoverflow.com/a/4312956/1987208 ma correzioni il caso in cui si calcola 1 mese per il caso dal 31 gennaio al 1 febbraio (1 giorno).

Questo riguarderà il seguente;

  • 1 gennaio-31 GENNAIO ---> 30 giorni ---> si tradurrà in 0 (logico dato che non è un mese intero)
  • 1 Febbraio - 1 Marzo ---> 28 o 29 giorni ---> si tradurrà in 1 (logica dal momento che è un mese intero)
  • 15 febbraio-15 marzo ---> 28 o 29 giorni ---> si tradurrà in 1 (logica dal momento che un mese passato)
  • 31 Gennaio - 1 Febbraio ---> 1 giorno ---> si tradurrà in 0 (ovvio, ma la risposta di cui i risultati postali di 1 mese)

Differenza di mesi tra due date in JavaScript:

 start_date = new Date(year, month, day); //Create start date object by passing appropiate argument
 end_date = new Date(new Date(year, month, day)

totale mesi tra data_iniziale e data finale:

 total_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth())

So che questo è davvero tardi, ma la pubblicazione è comunque solo nel caso in cui aiuta gli altri. Ecco una funzione sono arrivato fino a che sembra fare un buon lavoro di differenze di conteggio nei mesi tra due date. E 'certamente una grande quantità di raunchier Mr.Crowder di, ma fornisce risultati più precisi facendo un passo attraverso l'oggetto data. E 'in AS3, ma si dovrebbe solo essere in grado di far cadere il tipizzazione forte e dovrete JS. Sentitevi liberi di renderlo più bello guardare qualcuno là fuori!

    function countMonths ( startDate:Date, endDate:Date ):int
    {
        var stepDate:Date = new Date;
        stepDate.time = startDate.time;
        var monthCount:int;

        while( stepDate.time <= endDate.time ) { 
            stepDate.month += 1;
            monthCount += 1;
        }           

        if ( stepDate != endDate ) { 
            monthCount -= 1;
        }

        return monthCount;
    }

Consideriamo ogni data in termini di mesi, quindi sottrarre per calcolare la differenza.

var past_date = new Date('11/1/2014');
var current_date = new Date();

var difference = (current_date.getFullYear()*12 + current_date.getMonth()) - (past_date.getFullYear()*12 + past_date.getMonth());

In questo modo ottenere la differenza di mesi tra le due date, ignorando i giorni.

Per ampliare @ risposta di T.J., se siete alla ricerca di semplici mesi, piuttosto che mesi solari completi, si può solo controllare se la data di d2 è maggiore o uguale a quello di d1. Cioè, se d2 è successiva nel suo mese di d1 è nel suo mese, poi c'è 1 altro mese. Così si dovrebbe essere in grado di fare proprio questo:

function monthDiff(d1, d2) {
    var months;
    months = (d2.getFullYear() - d1.getFullYear()) * 12;
    months -= d1.getMonth() + 1;
    months += d2.getMonth();
    // edit: increment months if d2 comes later in its month than d1 in its month
    if (d2.getDate() >= d1.getDate())
        months++
    // end edit
    return months <= 0 ? 0 : months;
}

monthDiff(
    new Date(2008, 10, 4), // November 4th, 2008
    new Date(2010, 2, 12)  // March 12th, 2010
);
// Result: 16; 4 Nov – 4 Dec '08, 4 Dec '08 – 4 Dec '09, 4 Dec '09 – 4 March '10

Questo non del tutto conto per questioni di tempo (ad esempio 3 marzo alle 4:00 pm e il 3 aprile alle 03:00), ma è più preciso e solo per un paio di righe di codice.

Ci sono due approcci, matematici e veloci, ma soggetti a capricci del calendario, o iterativi e lento, ma serve per tutte le stranezze (o almeno loro movimentazione in una libreria ben collaudato delegati).

Se si scorre attraverso il calendario, incrementando la data di inizio di un mese e vedere se si passa la data di fine. Questo delegati anomalia di gestione della Data di built-in) classi (ma potrebbe essere lento IF si sta facendo questo per un gran numero di date. risposta James' prende questo approccio. Per quanto mi piace l'idea, credo che questo sia l'approccio "più sicuro", e se si sta solo facendo una di calcolo, la differenza di prestazioni è davvero trascurabile. Tendiamo a cercare di attività oltre-ottimizzare che verranno eseguite una sola volta.

Ora, se si sta calcolando questa funzione su un set di dati, probabilmente non si desidera eseguire questa funzione su ogni riga (o Dio non voglia, più volte al record). In tal caso, è possibile utilizzare quasi tutte le altre risposte qui tranne la risposta accettata, che è solo sbagliato (differenza tra new Date() e new Date() è -1)?

Ecco il mio pugnalata a un approccio matematico-e-veloce, che rappresenta diversi durata dei mesi e degli anni bisestili. Si dovrebbe utilizzare solo una funzione come questa se sarete applicando ad un set di dati (fare questo calcolo più e più). Se avete solo bisogno di farlo una volta, utilizzare approccio iterativo James' sopra, come si sta delegando la gestione di tutti i (molti) eccezioni per l'oggetto Date ().

function diffInMonths(from, to){
    var months = to.getMonth() - from.getMonth() + (12 * (to.getFullYear() - from.getFullYear()));

    if(to.getDate() < from.getDate()){
        var newFrom = new Date(to.getFullYear(),to.getMonth(),from.getDate());
        if (to < newFrom  && to.getMonth() == newFrom.getMonth() && to.getYear() %4 != 0){
            months--;
        }
    }

    return months;
}

Qui vai altro approccio con meno looping:

calculateTotalMonthsDifference = function(firstDate, secondDate) {
        var fm = firstDate.getMonth();
        var fy = firstDate.getFullYear();
        var sm = secondDate.getMonth();
        var sy = secondDate.getFullYear();
        var months = Math.abs(((fy - sy) * 12) + fm - sm);
        var firstBefore = firstDate > secondDate;
        firstDate.setFullYear(sy);
        firstDate.setMonth(sm);
        firstBefore ? firstDate < secondDate ? months-- : "" : secondDate < firstDate ? months-- : "";
        return months;
}

Calcolare la differenza tra due date comprendono frazione del mese (giorni).


var difference = (date2.getDate() - date1.getDate()) / 30 +
    date2.getMonth() - date1.getMonth() +
    (12 * (date2.getFullYear() - date1.getFullYear()));
  

Ad esempio:
   date1 : 24/09/2015 (24 settembre 2015)
   date2 : 2015/09/11 (9 novembre 2015)
  la differenza: 2.5 (mesi)

Questo dovrebbe funzionare bene:

function monthDiff(d1, d2) {
    var months;
    months = (d2.getFullYear() - d1.getFullYear()) * 12;
    months += d2.getMonth() - d1.getMonth();
    return months;
}

Si potrebbe anche prendere in considerazione questa soluzione, questo function restituisce la differenza mese nel numero intero o

Passando il data Inizio come la prima o l'ultima param, è fault tolerant. Significato, la funzione sarebbe ancora tornare lo stesso valore.

const diffInMonths = (end, start) => {
   var timeDiff = Math.abs(end.getTime() - start.getTime());
   return Math.round(timeDiff / (2e3 * 3600 * 365.25));
}

const result = diffInMonths(new Date(2015, 3, 28), new Date(2010, 1, 25));

// shows month difference as integer/number
console.log(result);

function calcualteMonthYr(){
    var fromDate =new Date($('#txtDurationFrom2').val()); //date picker (text fields)
    var toDate = new Date($('#txtDurationTo2').val());

var months=0;
        months = (toDate.getFullYear() - fromDate.getFullYear()) * 12;
        months -= fromDate.getMonth();
        months += toDate.getMonth();
            if (toDate.getDate() < fromDate.getDate()){
                months--;
            }
    $('#txtTimePeriod2').val(months);
}

codice seguente restituisce piena mesi tra due date prendendo nr di giorni di mesi parziali in considerazione pure.

var monthDiff = function(d1, d2) {
  if( d2 < d1 ) { 
    var dTmp = d2;
    d2 = d1;
    d1 = dTmp;
  }

  var months = (d2.getFullYear() - d1.getFullYear()) * 12;
  months -= d1.getMonth() + 1;
  months += d2.getMonth();

  if( d1.getDate() <= d2.getDate() ) months += 1;

  return months;
}

monthDiff(new Date(2015, 01, 20), new Date(2015, 02, 20))
> 1

monthDiff(new Date(2015, 01, 20), new Date(2015, 02, 19))
> 0

monthDiff(new Date(2015, 01, 20), new Date(2015, 01, 22))
> 0
function monthDiff(d1, d2) {
var months, d1day, d2day, d1new, d2new, diffdate,d2month,d2year,d1maxday,d2maxday;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
months += d2.getMonth();
months = (months <= 0 ? 0 : months);
d1day = d1.getDate();
d2day = d2.getDate();
if(d1day > d2day)
{
    d2month = d2.getMonth();
    d2year = d2.getFullYear();
    d1new = new Date(d2year, d2month-1, d1day,0,0,0,0);
    var timeDiff = Math.abs(d2.getTime() - d1new.getTime());
          diffdate = Math.abs(Math.ceil(timeDiff / (1000 * 3600 * 24))); 
    d1new = new Date(d2year, d2month, 1,0,0,0,0);
    d1new.setDate(d1new.getDate()-1);
    d1maxday = d1new.getDate();
    months += diffdate / d1maxday;
}
else
{
      if(!(d1.getMonth() == d2.getMonth() && d1.getFullYear() == d2.getFullYear()))
    {
        months += 1;
    }
    diffdate = d2day - d1day + 1;
    d2month = d2.getMonth();
    d2year = d2.getFullYear();
    d2new = new Date(d2year, d2month + 1, 1, 0, 0, 0, 0);
    d2new.setDate(d2new.getDate()-1);
    d2maxday = d2new.getDate();
    months += diffdate / d2maxday;
}

return months;

}

seguito logica preleverà differenza nei mesi

(endDate.getFullYear()*12+endDate.getMonth())-(startDate.getFullYear()*12+startDate.getMonth())
function monthDiff(date1, date2, countDays) {

  countDays = (typeof countDays !== 'undefined') ?  countDays : false;

  if (!date1 || !date2) {
    return 0;
  }

  let bigDate = date1;
  let smallDate = date2;

  if (date1 < date2) {
    bigDate = date2;
    smallDate = date1;
  }

  let monthsCount = (bigDate.getFullYear() - smallDate.getFullYear()) * 12 + (bigDate.getMonth() - smallDate.getMonth());

  if (countDays && bigDate.getDate() < smallDate.getDate()) {
    --monthsCount;
  }

  return monthsCount;
}

vedi quello che io uso:

function monthDiff() {
    var startdate = Date.parseExact($("#startingDate").val(), "dd/MM/yyyy");
    var enddate = Date.parseExact($("#endingDate").val(), "dd/MM/yyyy");
    var months = 0;
    while (startdate < enddate) {
        if (startdate.getMonth() === 1 && startdate.getDate() === 28) {
            months++;
            startdate.addMonths(1);
            startdate.addDays(2);
        } else {
            months++;
            startdate.addMonths(1);
        }
    }
    return months;
}
  

Si conta anche i giorni e li converte in mesi.

function monthDiff(d1, d2) {
    var months;
    months = (d2.getFullYear() - d1.getFullYear()) * 12;   //calculates months between two years
    months -= d1.getMonth() + 1; 
    months += d2.getMonth();  //calculates number of complete months between two months
    day1 = 30-d1.getDate();  
    day2 = day1 + d2.getDate();
    months += parseInt(day2/30);  //calculates no of complete months lie between two dates
    return months <= 0 ? 0 : months;
}

monthDiff(
    new Date(2017, 8, 8), // Aug 8th, 2017    (d1)
    new Date(2017, 12, 12)  // Dec 12th, 2017   (d2)
);
//return value will be 4 months 

per la prosperità,

Moment.js è possibile raggiungere questo obiettivo facendo:

const monthsLeft = moment(endDate).diff(moment(startDate), 'month');
anyVar = (((DisplayTo.getFullYear() * 12) + DisplayTo.getMonth()) - ((DisplayFrom.getFullYear() * 12) + DisplayFrom.getMonth()));

Un approccio potrebbe essere quello di scrivere un semplice servizio Web Java (REST / JSON), che utilizza la libreria JODA

http://joda-time.sourceforge.net/faq.html#datediff

per calcolare la differenza tra due date e chiamare tale servizio da javascript.

Questo presuppone che il back-end in Java.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top