Comment calculer la date en JavaScript trois mois avant aujourd'hui?

147

J'essaie de former une date qui est de 3 mois avant la date actuelle. J'obtiens le mois en cours par le code ci-dessous

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

Pouvez-vous me fournir la logique pour calculer et former une date (un objet du Datetype de données) en considérant que lorsque le mois est janvier (1), 3 mois avant la date serait OCtober (10)?

KeenUser
la source

Réponses:

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

Cela fonctionne pour janvier. Exécutez cet extrait:

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


Il y a quelques mises en garde ...

Un mois est une chose curieuse. Comment définissez-vous 1 mois? 30 jours? La plupart des gens diront qu'il y a un mois signifie le même jour du mois sur la citation du mois précédent nécessaire . Mais plus de la moitié du temps, c'est-à-dire il y a 31 jours, pas 30. Et si aujourd'hui est le 31 du mois (et ce n'est ni août ni décembre), ce jour du mois n'existe pas le mois précédent.

Fait intéressant, Google est d'accord avec JavaScript si vous lui demandez quel jour est un mois avant un autre jour :

Le résultat de la recherche Google pour "un mois avant le 31 mars" indique "3 mars"

Il dit également qu'un mois dure 30,4167 jours : Le résultat de la recherche Google pour "un mois en jours" indique "30 .4167".

Alors, un mois avant le 31 mars est-il le même jour qu'un mois avant le 28 mars, 3 jours plus tôt? Tout dépend de ce que vous entendez par «un mois avant». Allez avoir une conversation avec votre propriétaire de produit.

Si vous voulez faire comme momentjs et corriger ces erreurs du dernier jour du mois en passant au dernier jour du mois, vous pouvez faire quelque chose comme ceci:

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());

Si vos exigences sont plus compliquées que cela, utilisez des mathématiques et écrivez du code. Vous êtes développeur! Vous n'avez pas besoin d'installer une bibliothèque! Vous n'avez pas à copier et coller à partir de stackoverflow! Vous pouvez développer le code vous-même pour faire exactement ce dont vous avez besoin!

gilly3
la source
var currentDate = nouvelle date (); var currentMonth = currentDate.getMonth () -12; var pastDate = new Date (2011, currentMonth, 01); alert (pastDate); cela a fonctionné, vérifié avec 12 mois
KeenUser
C'est une réponse malsaine ... D'où vais-je obtenir 2012,0,15? Convertir un mois existant -1?
Alex G
3
@AlexG - Si vous êtes nouveau dans l'analyse des dates JavaScript, je peux voir à quel point mon exemple rapide serait déroutant. JavaScript exprime les mois en base zéro, où janvier est zéro. Pour éviter une telle confusion, d'autant plus que cela n'a rien à voir avec la question ou ma réponse, j'ai mis à jour ma démo pour obtenir la date à partir d'une chaîne, ce qui devrait être plus intuitif.
gilly3
7
Je sais que c'est vieux mais si la date est le 31 mars et que vous soustrayez un mois en utilisant cette méthode, le résultat est le 2 mars. jsfiddle.net/atamata/rvumf7dg
atamata
@atamata - Ouais, c'est bizarre, mais prévisible et attendu. 31 jours après la fin du mois précédent pour mars est le 31 mars, mais pour février c'est le 2 mars. Si vous voulez compter à partir de la fin du mois, vous devrez écrire du code personnalisé pour cela.
gilly3
28

Je recommande d'utiliser une bibliothèque appelée Moment.js.

Il est bien testé, fonctionne entre navigateurs et côté serveur (je l'utilise à la fois dans les projets Angular et Node). Il prend en charge les dates locales.

http://momentjs.com/

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

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

.format()renvoie une représentation sous forme de chaîne de la date au format ISO 8601 . Vous pouvez également l'utiliser avec un format de date personnalisé comme celui-ci:.format('dddd, MMMM Do YYYY, h:mm:ss a')

Jan Osch
la source
10

Un "one liner" (sur plusieurs lignes pour une lecture facile)) à mettre directement dans une variable:

var oneMonthAgo = new Date(
    new Date().getFullYear(),
    new Date().getMonth() - 1, 
    new Date().getDate()
);
user7394313
la source
agréable! Je ne sais pas si cela s'applique à tous les scénarios, mais semble fonctionner assez bien.
Devin Fields
8

Pour simplifier les choses, vous pouvez utiliser DateJS, une bibliothèque de dates pour JavaScript:

http://www.datejs.com/

Exemple de code pour vous:

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

Cela devrait gérer l'addition / soustraction, il suffit de mettre une valeur négative pour soustraire et une valeur positive pour ajouter. Cela résout également le problème de croisement mensuel.

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
la source
6

Si la setMonthméthode proposée par gilly3 n'est pas ce que vous recherchez, pensez à:

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

Peut être utilisé pour n'importe quelle durée, il suffit de définir les bons multiples.

Niet the Dark Absol
la source
J'irais avec la réponse de gilly3. Le vôtre suppose un nombre fixe de secondes par mois. L'arithmétique des dates clémente de JavaScript gardera le jour correct. Trois mois avant le 28 septembre devrait être le 28 juillet.
Ray Toal
1
Je me demande ce que JavaScript calculerait le 31 mars moins 1 mois.
Niet the Dark Absol
1
Dans ce cas, vous obtenez le 3 mars (pour 2011) car c'est ce que le 31 février est en mode clément. Mais soustrayez 2 mois et vous obtiendrez le 31 janvier. Avec le modèle 28 jours par mois, vous ne le feriez pas. Aussi faible que soit la Dateclasse, et autant que Date.js soit préférée, elle modélise au moins un calendrier prolptique clément qui est assez bon pour un usage occasionnel.
Ray Toal
Ne devriez-vous pas plusieurs secondes à 1000 correctement setTime()?
Vlad Tsepelev
4

J'aime la simplicité de la réponse de gilly3 , mais les utilisateurs seront probablement surpris qu'un mois avant le 31 mars soit le 3 mars. J'ai choisi d'implémenter une version qui colle à la fin du mois, donc un mois avant les 28, 29, 30 mars, et 31 seront tous le 28 février quand ce n'est pas une année bissextile.

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
la source
2

Il y a déjà une réponse élégante mais je trouve que c'est difficile à lire alors j'ai fait ma propre fonction. Pour mes besoins, je n'avais pas besoin d'un résultat négatif mais ce ne serait pas difficile à modifier.

    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
la source
2

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

pooja
la source
1

C'est le code le plus petit et le plus simple.

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

Déclarez la variable qui a la date actuelle. Ensuite, simplement en utilisant la fonction intégrée setMonth, nous pouvons obtenir une date de retour de 3 mois.

Rohit Gaidhane
la source
-1

Dans mon cas, je devais soustraire 1 mois à la date actuelle. La partie importante était le numéro du mois, donc peu importe dans quel jour du mois en cours vous êtes, j'avais besoin du mois dernier. Voici mon code:

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)

Soustraire 1 mois à la date réelle, ce n'est pas exact, c'est pourquoi, en premier lieu, j'ai défini le premier jour du mois (le premier jour de chaque mois est toujours le premier jour) et en second lieu, je soustrais 1 jour, qui vous envoie toujours au mois dernier. J'espère vous aider mec.

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
la source
-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
la source
-1

Passez un objet Date JS et un entier du nombre de mois que vous souhaitez ajouter / soustraire. monthsToAddpeut être positif ou négatif. Renvoie un objet de date JS.

Si vous êtes originalDateObjectle 31 mars et que vous passez -1 comme monthsToAdd, la date de sortie sera le 28 février.

Si vous passez un grand nombre de mois, disons 36, il gérera également correctement l'ajustement de l'année.

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);
};
Adam
la source
-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
la source
En quoi cette réponse diffère-t-elle des 7 autres, assez anciennes, déjà présentes?
Stephen Rauch
-5

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

santhosh
la source