Come posso calcolare la data in JavaScript tre mesi prima di oggi?


147

Sto cercando di formare una data che è di 3 mesi prima della data corrente. Ottengo il mese corrente dal seguente codice

var currentDate = new Date();
var currentMonth = currentDate.getMonth()+1;

Potete fornirmi la logica per calcolare e formare una data (un oggetto del Datetipo di dati) considerando che quando il mese è gennaio (1), 3 mesi prima della data sarebbe ottobre (10)?

Risposte:


323
var d = new Date();
d.setMonth(d.getMonth() - 3);

Funziona per gennaio. Esegui questo frammento:

var d = new Date("January 14, 2012");
console.log(d.toLocaleDateString());
d.setMonth(d.getMonth() - 3);
console.log(d.toLocaleDateString());


Ci sono alcuni avvertimenti ...

Un mese è una cosa curiosa. Come si definisce 1 mese? 30 giorni? La maggior parte delle persone dirà che un mese fa significa lo stesso giorno del mese della citazione del mese precedente necessaria . Ma più della metà delle volte, cioè 31 giorni fa, non 30. E se oggi è il 31 del mese (e non è agosto o dicembre), quel giorno del mese non esiste nel mese precedente.

È interessante notare che Google concorda con JavaScript se gli chiedi che giorno è un mese prima di un altro giorno :

I risultati di ricerca di Google per "un mese prima del 31 marzo" mostrano "3 marzo"

Dice anche che un mese dura 30.4167 giorni : Il risultato di ricerca di Google per "un mese in giorni" mostra "30 .4167"

Quindi, un mese prima del 31 marzo è lo stesso giorno di un mese prima del 28 marzo, 3 giorni prima? Tutto dipende da cosa intendi per "un mese prima". Fai una conversazione con il proprietario del tuo prodotto.

Se vuoi fare come fa momentjs e correggere questi errori dell'ultimo giorno del mese spostandoti all'ultimo giorno del mese, puoi fare qualcosa del genere:

const d = new Date("March 31, 2019");
console.log(d.toLocaleDateString());
const month = d.getMonth();
d.setMonth(d.getMonth() - 1);
while (d.getMonth() === month) {
    d.setDate(d.getDate() - 1);
}
console.log(d.toLocaleDateString());

Se le tue esigenze sono più complicate di così, usa un po 'di matematica e scrivi del codice. Sei uno sviluppatore! Non è necessario installare una libreria! Non è necessario copiare e incollare da StackOverflow! Puoi sviluppare tu stesso il codice per fare esattamente ciò di cui hai bisogno!


var currentDate = new Date (); var currentMonth = currentDate.getMonth () -12; var pastDate = new Date (2011, currentMonth, 01); alert (pastDate); questo ha funzionato, verificato con 12 mesi
KeenUser

Questa è una risposta malata ... Da dove prenderò 2012,0,15? Convertire un mese esistente -1?
Alex G

3
@AlexG - Se sei nuovo nell'analisi della data JavaScript, allora posso vedere come il mio esempio veloce sarebbe confuso. JavaScript esprime i mesi come zero, dove gennaio è zero. Per evitare tale confusione, soprattutto perché non ha nulla a che fare con la domanda o la mia risposta, ho aggiornato la mia demo per ottenere la data da una stringa, che dovrebbe essere più intuitiva.
gilly3,

7
So che questo è vecchio ma se la data è il 31 marzo e sottrai un mese usando questo metodo, il risultato è il 2 marzo. jsfiddle.net/atamata/rvumf7dg
atamata

@atamata - Sì, è strano, ma prevedibile e previsto. 31 giorni dopo la fine del mese precedente per marzo è il 31 marzo, ma per febbraio è il 2 marzo. Se vuoi contare dalla fine del mese, dovrai scrivere un codice personalizzato per quello.
gilly3,

28

Consiglio di usare una libreria chiamata Moment.js.

È ben testato, funziona su più browser e sul lato server (lo sto usando sia nei progetti Angular che Node). Ha un ottimo supporto per le date locali.

http://momentjs.com/

var threeMonthsAgo = moment().subtract(3, 'months');

console.log(threeMonthsAgo.format()); // 2015-10-13T09:37:35+02:00

.format()restituisce la rappresentazione in formato stringa della data formattata nel formato ISO 8601 . Puoi anche usarlo con un formato data personalizzato come questo:.format('dddd, MMMM Do YYYY, h:mm:ss a')


10

Un "one liner" (su molte righe per una facile lettura)) da inserire direttamente in una variabile:

var oneMonthAgo = new Date(
    new Date().getFullYear(),
    new Date().getMonth() - 1, 
    new Date().getDate()
);

simpatico! Non sono sicuro che sia applicabile a tutti gli scenari, ma sembra funzionare abbastanza bene.
Devin Fields,


8

Questo dovrebbe gestire l'addizione / sottrazione, basta inserire un valore negativo da sottrarre e un valore positivo da aggiungere. Questo risolve anche il problema del crossover mensile.

function monthAdd(date, month) {
    var temp = date;
    temp = new Date(date.getFullYear(), date.getMonth(), 1);
    temp.setMonth(temp.getMonth() + (month + 1));
    temp.setDate(temp.getDate() - 1); 

    if (date.getDate() < temp.getDate()) { 
        temp.setDate(date.getDate()); 
    }

    return temp;    
}

6

Se il setMonthmetodo offerto da gilly3 non è quello che stai cercando, considera:

var someDate = new Date(); // add arguments as needed
someDate.setTime(someDate.getTime() - 3*28*24*60*60);
// assumes the definition of "one month" to be "four weeks".

Può essere utilizzato per qualsiasi periodo di tempo, basta impostare i multipli giusti.


Vorrei andare con la risposta di Gilly3. Il tuo presuppone un numero fisso di secondi al mese. L'aritmetica della data indulgente di JavaScript manterrà il giorno corretto. Tre mesi prima del 28 settembre dovrebbe essere il 28 luglio.
Ray Toal,

1
Mi chiedo quale JavaScript calcolarebbe il 31 marzo meno 1 mese.
Niet the Dark Absol,

1
In quel caso ottieni il 3 marzo (per il 2011) perché è quello che il 31 febbraio è in modalità clemente. Ma sottrai 2 mesi e otterrai il 31 gennaio. Con il modello di 28 giorni al mese non lo faresti. Per quanto debole sia la Dateclasse e per quanto sia preferito Date.js, almeno modella un calendario prolettico indulgente che è abbastanza buono per un uso occasionale.
Ray Toal,

Non dovresti più secondi da 1000 a correttamente setTime()?
Vlad Tsepelev,

4

Mi piace la semplicità della risposta di gilly3 , ma gli utenti saranno probabilmente sorpresi che un mese prima del 31 marzo è il 3 marzo. Ho scelto di implementare una versione che si attacca alla fine del mese, quindi un mese prima del 28 marzo, 29, 30 marzo, e 31 saranno tutti il ​​28 febbraio quando non sarà un anno bisestile.

function addMonths(date, months) {
  var result = new Date(date),
      expectedMonth = ((date.getMonth() + months) % 12 + 12) % 12;
  result.setMonth(result.getMonth() + months);
  if (result.getMonth() !== expectedMonth) {
    result.setDate(0);
  }
  return result;
}

var dt2004_05_31 = new Date("2004-05-31 0:00"),
    dt2001_05_31 = new Date("2001-05-31 0:00"),
    dt2001_03_31 = new Date("2001-03-31 0:00"),
    dt2001_02_28 = new Date("2001-02-28 0:00"),
    result = addMonths(dt2001_05_31, -2);
console.assert(dt2001_03_31.getTime() == result.getTime(), result.toDateString());

result = addMonths(dt2001_05_31, -3);
console.assert(dt2001_02_28.getTime() == result.getTime(), result.toDateString());

result = addMonths(dt2001_05_31, 36);
console.assert(dt2004_05_31.getTime() == result.getTime(), result.toDateString());

result = addMonths(dt2004_05_31, -38);
console.assert(dt2001_03_31.getTime() == result.getTime(), result.toDateString());

console.log('Done.');


2

C'è già una risposta elegante, ma trovo che sia difficile da leggere, quindi ho fatto la mia funzione. Per i miei scopi non avevo bisogno di un risultato negativo ma non sarebbe difficile da modificare.

    var subtractMonths = function (date1,date2) {
        if (date1-date2 <=0) {
            return 0;
        }
        var monthCount = 0;
        while (date1 > date2){
            monthCount++;
            date1.setMonth(date1.getMonth() -1);
        }
        return monthCount;
    }

2

var d = new Date("2013/01/01");
console.log(d.toLocaleDateString());
d.setMonth(d.getMonth() + 18);
console.log(d.toLocaleDateString());


1

Questo è il codice più piccolo e più semplice.

   var minDate = new Date(); 
   minDate.setMonth(minDate.getMonth() - 3);

Dichiarare la variabile che ha la data corrente. quindi solo usando la funzione integrata setMonth possiamo ottenere una data di ritorno di 3 mesi.


-1

Nel mio caso avevo bisogno di sottrarre 1 mese alla data corrente. La parte importante era il numero del mese, quindi non importa in quale giorno del mese in cui ti trovi, avevo bisogno il mese scorso. Questo è il mio codice:

var dateObj = new Date('2017-03-30 00:00:00'); //Create new date object
console.log(dateObj); // Thu Mar 30 2017 00:00:00 GMT-0300 (ART)

dateObj.setDate(1); //Set first day of the month from current date
dateObj.setDate(-1); // Substract 1 day to the first day of the month

//Now, you are in the last month
console.log(dateObj); // Mon Feb 27 2017 00:00:00 GMT-0300 (ART)

Sottrai 1 mese alla data effettiva non è preciso, ecco perché in primo luogo ho impostato il primo giorno del mese (il primo giorno di ogni mese è sempre il primo giorno) e al secondo posto sottraggo 1 giorno, che ti invio sempre al mese scorso. Spero di aiutarti amico.

var dateObj = new Date('2017-03-30 00:00:00'); //Create new date object
console.log(dateObj); // Thu Mar 30 2017 00:00:00 GMT-0300 (ART)

dateObj.setDate(1); //Set first day of the month from current date
dateObj.setDate(-1); // Substract 1 day to the first day of the month

//Now, you are in the last month
console.log(dateObj); // Mon Feb 27 2017 00:00:00 GMT-0300 (ART)


-1

   

 var date=document.getElementById("date");
    var d = new Date();
   document.write(d + "<br/>");
    d.setMonth(d.getMonth() - 6);
    document.write(d);

 if(d<date)
  document.write("lesser then 6 months");
else
  document.write("greater then 6 months");


-1

Passa un oggetto Data JS e un numero intero di quanti mesi desideri aggiungere / sottrarre. monthsToAddpuò essere positivo o negativo. Restituisce un oggetto data JS.

Se il tuo originalDateObjectè il 31 marzo e passi -1 come monthsToAdd, la data di uscita sarà il 28 febbraio.

Se passi un gran numero di mesi, diciamo 36, gestirà correttamente anche la regolazione dell'anno.

const addMonthsToDate = (originalDateObject, monthsToAdd) => {
  const originalDay = originalDateObject.getUTCDate();
  const originalMonth = originalDateObject.getUTCMonth();
  const originalYear = originalDateObject.getUTCFullYear();

  const monthDayCountMap = {
    "0": 31,
    "1": 28,
    "2": 31,
    "3": 30,
    "4": 31,
    "5": 30,
    "6": 31,
    "7": 31,
    "8": 30,
    "9": 31,
    "10": 30,
    "11": 31
  };

  let newMonth;
  if (newMonth > -1) {
    newMonth = (((originalMonth + monthsToAdd) % 12)).toString();
  } else {
    const delta = (monthsToAdd * -1) % 12;
    newMonth = originalMonth - delta < 0 ? (12+originalMonth) - delta : originalMonth - delta;
  }

  let newDay;

  if (originalDay > monthDayCountMap[newMonth]) {
    newDay = monthDayCountMap[newMonth].toString();
  } else {
    newDay = originalDay.toString();
  }

  newMonth = (+newMonth + 1).toString();

  if (newMonth.length === 1) {
    newMonth = '0' + newMonth;
  }

  if (newDay.length === 1) {
    newDay = '0' + newDay;
  }

  if (monthsToAdd <= 0) {
    monthsToAdd -= 11;
  }

  let newYear = (~~((originalMonth + monthsToAdd) / 12)) + originalYear;

  let newTime = originalDateObject.toISOString().slice(10, 24);

  const newDateISOString = `${newYear}-${newMonth}-${newDay}${newTime}`;

  return new Date(newDateISOString);
};

-5
Following code give me Just Previous Month From Current Month even the date is 31/30 of current date and last month is 30/29/28 days:

   <!DOCTYPE html>
<html>
<body>

<p>Click the button to display the date after changing the month.</p>

<button onclick="myFunction()">Try it</button>

<p id="demo"></p>

<script>
function myFunction() {

var d = new Date("March 29, 2017"); // Please Try the result also for "March 31, 2017" Or "March 30, 2017"
var OneMonthBefore =new Date(d);

OneMonthBefore.setMonth(d.getMonth(),0);
if(OneMonthBefore.getDate() < d.getDate()  )
{
d.setMonth(d.getMonth(),0);
}else
{
d.setMonth(d.getMonth()-1);

}

    document.getElementById("demo").innerHTML = d;
}
</script>

</body>
</html>

In che modo questa risposta differisce dalle altre 7, piuttosto vecchie, già presenti?
Stephen Rauch

-5

var d = new Date();
document.write(d + "<br/>");
d.setMonth(d.getMonth() - 6);
document.write(d);

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.