it-swarm.com.de

JavaScript-Funktion zum Hinzufügen von X Monaten zu einem Datum

Ich suche nach der einfachsten und saubersten Möglichkeit, einem JavaScript-Datum X Monate hinzuzufügen.

Ich würde lieber nicht das Wegrollen des Jahres bewältigen oder ich muss schreibe meine eigene Funktion .

Gibt es etwas eingebautes, das das kann?

171
ChadD

Ich denke, das sollte es tun:

var x = 12; //or whatever offset
var CurrentDate = new Date();
CurrentDate.setMonth(CurrentDate.getMonth() + x);

Ich glaube, es sollte automatisch mit der Erhöhung auf das entsprechende Jahr und der Anpassung auf den entsprechenden Monat umgehen.

versuch es

238
ChadD

Ich benutze moment.js library für date-time-Manipulationen .

var startDate = new Date(...);
var endDateMoment = moment(startDate); // moment(...) can also be used to parse dates in string format
endDateMoment.add(1, 'months');
51
anre

Diese Funktion behandelt Edge-Fälle und ist schnell:

function addMonthsUTC (date, count) {
  if (date && count) {
    var m, d = (date = new Date(+date)).getUTCDate()

    date.setUTCMonth(date.getUTCMonth() + count, 1)
    m = date.getUTCMonth()
    date.setUTCDate(d)
    if (date.getUTCMonth() !== m) date.setUTCDate(0)
  }
  return date
}

prüfung:

> d = new Date('2016-01-31T00:00:00Z');
Sat Jan 30 2016 18:00:00 GMT-0600 (CST)
> d = addMonthsUTC(d, 1);
Sun Feb 28 2016 18:00:00 GMT-0600 (CST)
> d = addMonthsUTC(d, 1);
Mon Mar 28 2016 18:00:00 GMT-0600 (CST)
> d.toISOString()
"2016-03-29T00:00:00.000Z"

Update für Nicht-UTC-Daten: (von A.Hatchkins)

function addMonths (date, count) {
  if (date && count) {
    var m, d = (date = new Date(+date)).getDate()

    date.setMonth(date.getMonth() + count, 1)
    m = date.getMonth()
    date.setDate(d)
    if (date.getMonth() !== m) date.setDate(0)
  }
  return date
}

prüfung:

> d = new Date(2016,0,31);
Sun Jan 31 2016 00:00:00 GMT-0600 (CST)
> d = addMonths(d, 1);
Mon Feb 29 2016 00:00:00 GMT-0600 (CST)
> d = addMonths(d, 1);
Tue Mar 29 2016 00:00:00 GMT-0600 (CST)
> d.toISOString()
"2016-03-29T06:00:00.000Z"
19
aMarCruz

Wenn Sie berücksichtigen, dass keine dieser Antworten das aktuelle Jahr berücksichtigt, wenn sich der Monat ändert, finden Sie unter der folgenden Antwort eine der folgenden Antworten:

Die Methode:

Date.prototype.addMonths = function (m) {
    var d = new Date(this);
    var years = Math.floor(m / 12);
    var months = m - (years * 12);
    if (years) d.setFullYear(d.getFullYear() + years);
    if (months) d.setMonth(d.getMonth() + months);
    return d;
}

Verwendungszweck:

return new Date().addMonths(2);
13
Control Freak

Aus @bmpsini und @Jazaret antworten, jedoch nicht um Prototypen erweitert: Verwenden von einfachen Funktionen ( Warum ist das Erweitern von nativen Objekten eine schlechte Praxis? ):

function isLeapYear(year) { 
    return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)); 
}

function getDaysInMonth(year, month) {
    return [31, (isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
}

function addMonths(date, value) {
    var d = new Date(date),
        n = date.getDate();
    d.setDate(1);
    d.setMonth(d.getMonth() + value);
    d.setDate(Math.min(n, getDaysInMonth(d.getFullYear(), d.getMonth())));
    return d;
}

Benutze es:

var nextMonth = addMonths(new Date(), 1);
6
Miquel
d = new Date();

alert(d.getMonth()+1);

Die Monate haben einen 0-basierten Index, es sollte Alarm (4) geben, der 5 (Mai) ist;

2
Ben

Wie die meisten Antworten hervorgehoben haben, könnten wir die setMonth () method zusammen mit getMonth () method verwenden, um einem bestimmten Datum eine bestimmte Anzahl von Monaten hinzuzufügen.

Beispiel: (wie von @ChadD in seiner Antwort erwähnt.) 

var x = 12; //or whatever offset 
var CurrentDate = new Date();
CurrentDate.setMonth(CurrentDate.getMonth() + x);

Wir sollten diese Lösung jedoch sorgfältig verwenden, da bei Edge-Fällen Probleme auftreten. 

Für die Bearbeitung von Edge-Fällen ist die Antwort, die im folgenden Link angegeben ist, hilfreich. 

https://stackoverflow.com/a/13633692/3668866

2
Sampath Dilhan

Nur um die akzeptierte Antwort und die Kommentare hinzuzufügen.

var x = 12; //or whatever offset
var CurrentDate = new Date();

//For the very rare cases like the end of a month
//eg. May 30th - 3 months will give you March instead of February
var date = CurrentDate.getDate();
CurrentDate.setDate(1);
CurrentDate.setMonth(CurrentDate.getMonth()+X);
CurrentDate.setDate(date);
2
iamjt

Aufgrund der obigen Antworten ist der einzige, der die Edge-Fälle behandelt (bmpasini aus datejs-Bibliothek), ein Problem:

var date = new Date("03/31/2015");
var newDate = date.addMonths(1);
console.log(newDate);
// VM223:4 Thu Apr 30 2015 00:00:00 GMT+0200 (CEST)

oK aber:

newDate.toISOString()
//"2015-04-29T22:00:00.000Z"

schlechter :

var date = new Date("01/01/2015");
var newDate = date.addMonths(3);
console.log(newDate);
//VM208:4 Wed Apr 01 2015 00:00:00 GMT+0200 (CEST)
newDate.toISOString()
//"2015-03-31T22:00:00.000Z"

Dies ist darauf zurückzuführen, dass die Uhrzeit nicht eingestellt wurde, also auf 00:00:00 zurückgesetzt wird, was aufgrund von Zeitzonen oder zeitsparenden Änderungen oder was auch immer ...

Hier ist meine vorgeschlagene Lösung, die dieses Problem nicht hat, und ist meiner Meinung nach auch eleganter, da sie nicht auf hartcodierten Werten basiert.

/**
* @param isoDate {string} in ISO 8601 format e.g. 2015-12-31
* @param numberMonths {number} e.g. 1, 2, 3...
* @returns {string} in ISO 8601 format e.g. 2015-12-31
*/
function addMonths (isoDate, numberMonths) {
    var dateObject = new Date(isoDate),
        day = dateObject.getDate(); // returns day of the month number

    // avoid date calculation errors
    dateObject.setHours(20);

    // add months and set date to last day of the correct month
    dateObject.setMonth(dateObject.getMonth() + numberMonths + 1, 0);

    // set day number to min of either the original one or last day of month
    dateObject.setDate(Math.min(day, dateObject.getDate()));

    return dateObject.toISOString().split('T')[0];
};

Gerät erfolgreich getestet mit:

function assertEqual(a,b) {
    return a === b;
}
console.log(
    assertEqual(addMonths('2015-01-01', 1), '2015-02-01'),
    assertEqual(addMonths('2015-01-01', 2), '2015-03-01'),
    assertEqual(addMonths('2015-01-01', 3), '2015-04-01'),
    assertEqual(addMonths('2015-01-01', 4), '2015-05-01'),
    assertEqual(addMonths('2015-01-15', 1), '2015-02-15'),
    assertEqual(addMonths('2015-01-31', 1), '2015-02-28'),
    assertEqual(addMonths('2016-01-31', 1), '2016-02-29'),
    assertEqual(addMonths('2015-01-01', 11), '2015-12-01'),
    assertEqual(addMonths('2015-01-01', 12), '2016-01-01'),
    assertEqual(addMonths('2015-01-01', 24), '2017-01-01'),
    assertEqual(addMonths('2015-02-28', 12), '2016-02-28'),
    assertEqual(addMonths('2015-03-01', 12), '2016-03-01'),
    assertEqual(addMonths('2016-02-29', 12), '2017-02-28')
);
2
pansay

Einfache Lösung: 2678400000 ist 31 Tage in Millisekunden

var oneMonthFromNow = new Date((+new Date) + 2678400000);

Update:

Verwenden Sie diese Daten, um unsere eigene Funktion aufzubauen:

  • 2678400000 - 31 tage
  • 2592000000 - 30 Tage
  • 2505600000 - 29 Tage
  • 2419200000 - 28 Tage
2
dr.dimitru

All dies scheint viel zu kompliziert zu sein, und ich denke, es kommt zu einer Debatte darüber, was genau "Monat hinzufügen" bedeutet. Bedeutet das 30 Tage? Bedeutet das vom 1. bis zum 1.? Vom letzten Tag bis zum letzten Tag?

Wenn letztere zum 27. Februar hinzukommt, gelangen Sie zum 27. März, aber zum 28. Februar kommt ein Monat zum 31. März (außer in Schaltjahren, wo Sie zum 28. März gelangen). Wenn Sie dann einen Monat vom 30. März abziehen, erhalten Sie ... 27. Februar? Wer weiß...

Wenn Sie nach einer einfachen Lösung suchen, fügen Sie einfach Millisekunden hinzu und fertig.

function getDatePlusDays(dt, days) {
  return new Date(dt.getTime() + (days * 86400000));
}

oder

Date.prototype.addDays = function(days) {
  this = new Date(this.getTime() + (days * 86400000));
};
0
jdforsythe

Das folgende Beispiel zeigt, wie ein zukünftiges Datum basierend auf der Datumseingabe berechnet wird (mitgliedschaftsignup_date) + hinzugefügten Monaten (mitgliedschaftsmonate) über Formularfelder.

Das Feld Membershipsmonths hat den Standardwert 0

Auslöserlink (kann ein onchange-Ereignis sein, das an das Feld für die Mitgliedschaftsbedingungen angehängt ist):

<a href="#" onclick="calculateMshipExp()"; return false;">Calculate Expiry Date</a>

function calculateMshipExp() {

var calcval = null;

var start_date = document.getElementById("membershipssignup_date").value;
var term = document.getElementById("membershipsmonths").value;  // Is text value

var set_start = start_date.split('/');  

var day = set_start[0];  
var month = (set_start[1] - 1);  // January is 0 so August (8th month) is 7
var year = set_start[2];
var datetime = new Date(year, month, day);
var newmonth = (month + parseInt(term));  // Must convert term to integer
var newdate = datetime.setMonth(newmonth);

newdate = new Date(newdate);
//alert(newdate);

day = newdate.getDate();
month = newdate.getMonth() + 1;
year = newdate.getFullYear();

// This is British date format. See below for US.
calcval = (((day <= 9) ? "0" + day : day) + "/" + ((month <= 9) ? "0" + month : month) + "/" + year);

// mm/dd/yyyy
calcval = (((month <= 9) ? "0" + month : month) + "/" + ((day <= 9) ? "0" + day : day) + "/" + year);

// Displays the new date in a <span id="memexp">[Date]</span> // Note: Must contain a value to replace eg. [Date]
document.getElementById("memexp").firstChild.data = calcval;

// Stores the new date in a <input type="hidden" id="membershipsexpiry_date" value="" name="membershipsexpiry_date"> for submission to database table
document.getElementById("membershipsexpiry_date").value = calcval;
}
0
John G

Wie viele der komplizierten, hässlichen Antworten zeigen, können Dates und Times für Programmierer, die eine beliebige Sprache verwenden, ein Alptraum sein. Mein Ansatz ist, Datums- und Delta-Delta-Werte in Epoch Time (in ms) umzuwandeln, eine beliebige Arithmetik auszuführen und dann wieder in "menschliche Zeit" umzuwandeln.

// Given a number of days, return a Date object
//   that many days in the future. 
function getFutureDate( days ) {

    // Convert 'days' to milliseconds
    var millies = 1000 * 60 * 60 * 24 * days;

    // Get the current date/time
    var todaysDate = new Date();

    // Get 'todaysDate' as Epoch Time, then add 'days' number of mSecs to it
    var futureMillies = todaysDate.getTime() + millies;

    // Use the Epoch time of the targeted future date to create
    //   a new Date object, and then return it.
    return new Date( futureMillies );
}

// Use case: get a Date that's 60 days from now.
var twoMonthsOut = getFutureDate( 60 );

Dies wurde für einen etwas anderen Anwendungsfall geschrieben, Sie sollten es jedoch leicht für verwandte Aufgaben anpassen können.

EDIT: Vollständige Quelle hier !

0
Dan Ahlquist

Ich habe diese alternative Lösung geschrieben, die für mich gut funktioniert. Dies ist nützlich, wenn Sie das Vertragsende berechnen möchten. Beispiel: start = 2016-01-15, Monate = 6, Ende = 2016-7-14 (d. H. Letzter Tag - 1):

<script>
function daysInMonth(year, month)
{
    return new Date(year, month + 1, 0).getDate();
}

function addMonths(date, months)
{
    var target_month = date.getMonth() + months;
    year = date.getFullYear() + parseInt(target_month / 12);
    month = target_month % 12;
    day = date.getDate();
    last_day = daysInMonth(year, month);
    if (day > last_day)
    {
        day = last_day;
    }
    new_date = new Date(year, month, day);
    return new_date;
}

var endDate = addMonths(startDate, months);
</script>

Beispiele:

addMonths(new Date("2016-01-01"), 1); // 2016-01-31
addMonths(new Date("2016-01-01"), 2); // 2016-02-29 (2016 is a leap year)
addMonths(new Date("2016-01-01"), 13); // 2017-01-31
addMonths(new Date("2016-01-01"), 14); // 2017-02-28
0
David Ragazzi