Como calculo a data em JavaScript três meses antes de hoje?

147

Estou tentando formar uma data 3 meses antes da data atual. Recebo o mês atual pelo código abaixo

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

Vocês podem me fornecer a lógica para calcular e formar uma data (um objeto do Datetipo de dados), considerando que quando o mês é 1 de janeiro, 3 meses antes da data seria outubro (10)?

KeenUser
fonte

Respostas:

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

Isso funciona para janeiro. Execute este trecho:

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


Existem algumas advertências ...

Um mês é uma coisa curiosa. Como você define 1 mês? 30 dias? A maioria das pessoas vai dizer que há um mês meio no mesmo dia do mês em relação ao mês anterior carece de fontes . Mas mais da metade do tempo, isto é, 31 dias atrás, não 30. E se hoje é o 31 de mês (e não é agosto ou dezembro), esse dia do mês não existe no mês anterior.

Curiosamente, o Google concorda com o JavaScript se você perguntar que dia é um mês antes de outro dia :

O resultado da pesquisa do Google para "um mês antes de 31 de março" mostra "3 de março"

Ele também diz que um mês dura 30.4167 dias : O resultado da pesquisa do Google para 'um mês em dias' mostra '30 .4167 '

Então, um mês antes de 31 de março é o mesmo dia que um mês antes de 28 de março, três dias antes? Tudo isso depende do que você quer dizer com "um mês antes". Vá conversar com o proprietário do produto.

Se você deseja fazer como o momentjs, e corrigir esses erros do último dia do mês, movendo para o último dia do mês, você pode fazer algo assim:

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 seus requisitos forem mais complicados do que isso, use um pouco de matemática e escreva um código. Você é um desenvolvedor! Você não precisa instalar uma biblioteca! Você não precisa copiar e colar do stackoverflow! Você mesmo pode desenvolver o código para fazer exatamente o que precisa!

gilly3
fonte
var currentDate = new Date (); var currentMonth = currentDate.getMonth () -12; var pastDate = new Date (2011, currentMonth, 01); alerta (pastDate); isso funcionou, verificado com 12 meses
KeenUser 29/10/11
Esta é uma resposta doentia ... De onde eu vou conseguir 2012,0,15? Converter um mês existente -1?
Alex G
3
@AlexG - Se você é novo na análise de datas em JavaScript, posso ver como meu exemplo rápido seria confuso. JavaScript expressa meses como zero, onde janeiro é zero. Para evitar essa confusão, principalmente porque isso não tem nada a ver com a pergunta ou a minha resposta, atualizei minha demonstração para obter a data de uma string, o que deve ser mais intuitivo.
precisa saber é o seguinte
7
Sei que isso é antigo, mas se a data for 31 de março e você subtrair um mês usando esse método, o resultado será 2 de março. jsfiddle.net/atamata/rvumf7dg
atamata 20/01
@atamata - Sim, isso é estranho, mas previsível e esperado. 31 dias após o final do mês anterior para março é 31 de março, mas para fevereiro é 2 de março. Se você quiser contar a partir do final do mês, precisará escrever um código personalizado para isso.
precisa saber é o seguinte
28

Eu recomendo usar uma biblioteca chamada Moment.js.

É bem testado, funciona em vários navegadores e no lado do servidor (estou usando-o nos projetos Angular e Node). Ele oferece excelente suporte para datas de localidade.

http://momentjs.com/

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

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

.format()retorna a representação de string da data formatada no formato ISO 8601 . Você também pode usá-lo com formato de data personalizado como este:.format('dddd, MMMM Do YYYY, h:mm:ss a')

Jan Osch
fonte
10

Um "one liner" (em várias linhas para facilitar a leitura)) a ser colocado diretamente em uma variável:

var oneMonthAgo = new Date(
    new Date().getFullYear(),
    new Date().getMonth() - 1, 
    new Date().getDate()
);
user7394313
fonte
legais! Não tenho certeza se é aplicável a todos os cenários, mas parece funcionar bem o suficiente.
Devin Campos
8

Para simplificar as coisas, você pode usar o DateJS, uma biblioteca de datas para JavaScript:

http://www.datejs.com/

Código de exemplo para você:

Date.today().add({ months: -1 });
thinkdevcode
fonte
8

Isso deve lidar com adição / subtração, basta colocar um valor negativo para subtrair e um valor positivo para adicionar. Isso também resolve o problema de cruzamento do mês.

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;    
}
Hodeifa Baswel
fonte
6

Se o setMonthmétodo oferecido por gilly3 não for o que você procura, considere:

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".

Pode ser usado por qualquer período de tempo, basta definir os múltiplos certos.

Niet, o Escuro Absol
fonte
Eu iria com a resposta de gilly3. O seu assume um número fixo de segundos por mês. A aritmética branda da data do JavaScript manterá o dia correto. Três meses antes de 28 de setembro devem ser 28 de julho.
Ray Toal
1
Eu me pergunto o que o JavaScript calcularia em 31 de março menos 1 mês.
Niet the Dark Absol
1
Nesse caso, você recebe 3 de março (para 2011), porque é isso que 31 de fevereiro está no modo branda. Mas subtraia 2 meses e você receberá 31 de janeiro. Sob o modelo de 28 dias por mês, você não faria isso. Por mais fraca que a Dateclasse seja, e por mais que o Date.js. seja o preferido, ele pelo menos modela um calendário proléptico brando que é bom o suficiente para uso casual.
Ray Toal 29/10
Você não deve vários segundos a 1000 para corrigir setTime()?
Vlad Tsepelev 5/12/19
4

Gosto da simplicidade da resposta de gilly3 , mas os usuários provavelmente ficarão surpresos que um mês antes de 31 de março seja 3 de março. Optei por implementar uma versão que se adere ao final do mês, portanto, um mês antes de 28, 29, 30 de março, e 31 serão 28 de fevereiro, quando não for um ano bissexto.

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.');

Don Kirkby
fonte
2

Já existe uma resposta elegante, mas acho que é difícil de ler, então fiz minha própria função. Para meus propósitos, não precisava de um resultado negativo, mas não seria difícil de modificar.

    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;
    }
JamesD
fonte
2

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

pooja
fonte
1

Este é o código menor e mais fácil.

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

Declare a variável que tem data atual. apenas usando a função setMonth inbuilt, podemos obter uma data anterior de 3 meses.

Rohit Gaidhane
fonte
-1

No meu caso, eu precisava subtrair 1 mês para a data atual. A parte importante era o número do mês, por isso não importa em que dia do mês atual você está, eu precisava do mês passado. Este é o meu código:

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)

Substrato 1 mês até a data real não é preciso, por isso, em primeiro lugar, defino o primeiro dia do mês (o primeiro dia de qualquer mês sempre é o primeiro dia) e, em segundo lugar, subtraio 1 dia, que sempre o envia para o mês passado. Espero ajudá-lo, cara.

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)

miguel.angel
fonte
-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");

santhosh
fonte
-1

Passe um objeto JS Date e um número inteiro de quantos meses você deseja adicionar / subtrair. monthsToAddpode ser positivo ou negativo. Retorna um objeto de data JS.

Se você originalDateObjecté 31 de março e passa -1 como monthsToAdd, então a data de saída será 28 de fevereiro.

Se você passar um grande número de meses, digamos 36, ele também cuidará do ajuste do ano.

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);
};
Adão
fonte
-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>
Mohammad Rahman
fonte
Como essa resposta difere das outras 7 respostas bastante antigas, já presentes?
Stephen Rauch
-5

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

santhosh
fonte