Subtrahieren Sie Tage, Monate, Jahre von einem Datum in JavaScript

78

Kennt jemand eine einfache Möglichkeit, ein Datum (z. B. Heute) zu erfassen und X Tage, X Monate und X Jahre zurückzugehen?

Ich habe das versucht:

var date = new Date();
$("#searchDateFrom").val((date.getMonth() -1 ) + '/' + (date.getDate() - 6) + '/' + (date.getFullYear() - 1));

Aber ich habe ein negatives Datum bekommen, zum Beispiel war heute die Ausgabe:

3/3/2015

Irgendwelche Ratschläge?

Vielen Dank.

user3378165
quelle
4
date.get....wird a zurückgeben Numberund wenn Sie eine Zahl von einer anderen subtrahieren number, kann der Wert negativ sein (wenn der linke Wert kleiner ist). Ich würde Ihnen empfehlen, DateObj.set...Methoden zu verwenden und dann die entsprechenden Werte abzurufen ...
Rayon

Antworten:

105

Sie reduzieren einfach die Werte von einer Zahl. Wenn Sie also 6 von 3 (Datum) abziehen, wird nur -3 zurückgegeben.

Sie müssen die Zeiteinheit im Datumsobjekt einzeln hinzufügen / entfernen

var date = new Date();
date.setDate( date.getDate() - 6 );
date.setFullYear( date.getFullYear() - 1 );
$("#searchDateFrom").val((date.getMonth() ) + '/' + (date.getDate()) + '/' + (date.getFullYear()));
gurvinder372
quelle
14
getMonth () basiert auf Null. Das heißt, es wird der falsche Monat angezeigt. Beispiel: 10 ist November.
Tony
1
Sagen wir einfach: getMonth () ist indexbasiert.
GottZ
22

Wie andere gesagt haben, subtrahieren Sie von den numerischen Werten, die von Methoden wie zurückgegeben wurden date.getDate(), und müssen diese Werte für Ihre Datumsvariable zurücksetzen. Ich habe unten eine Methode erstellt, die dies für Sie erledigt. Es wird ein Datum erstellt, mit new Date()dem das aktuelle Datum initialisiert wird. Anschließend werden Datum, Monat und Jahr gemäß den übergebenen Werten festgelegt. Wenn Sie beispielsweise 6 Tage zurückgehen möchten, übergeben Sie -6 wie folgt var newdate = createDate(-6,0,0). Wenn Sie keinen Wert festlegen möchten, übergeben Sie eine Null (oder Sie können Standardwerte festlegen). Die Methode gibt das neue Datum für Sie zurück (getestet in Chrome und Firefox).

function createDate(days, months, years) {
        var date = new Date(); 
        date.setDate(date.getDate() + days);
        date.setMonth(date.getMonth() + months);
        date.setFullYear(date.getFullYear() + years);
        return date;    
    }
Phil
quelle
17

Ich würde empfehlen, die MomentJS-Bibliotheken zu verwenden. Sie machen alle Interaktionen mit Dates viel einfacher.

Wenn Sie Moment verwenden, ist Ihr Code so einfach:

var today = moment();
var nextMonth = today.add('month', 1);
// note that both variables `today` and `nextMonth` refer to 
// the next month at this point, because `add` mutates in-place

Sie finden MomentJS hier: http://momentjs.com/

AKTUALISIEREN:

In JavaScript gibt die Funktion Date.getDate () den aktuellen Tag des Monats von 1-31 zurück. Sie subtrahieren 6 von dieser Zahl und es ist derzeit der 3. des Monats. Dies bringt den Wert auf -3.

FvB
quelle
@Fvb Danke, ich habe den Leitfaden gelesen und es ist eine ausgezeichnete Bibliothek. Danke für die Idee, ihn zu verwenden.
user3378165
Denken Sie daran, dass moment.js Ihrer App ungefähr 16.000 hinzufügt. Normalerweise keine große Sache. Wenn die Leistung jedoch kritisch ist, ist es für eine so kleine Berechnung billiger, sich an einfache alte js zu halten.
Shanemgrey
3
Die aktuelle Version von moment (2.18.2 zum Zeitpunkt dieses Schreibens) gibt eine Warnung zu dieser Funktion aus. add / subtrahieren ('Punkt', Zahl) ist veraltet und schlägt vor, stattdessen addieren / subtrahieren (Zahl, 'Punkt') zu verwenden.
Jamie M
11

Dies ist eine reine Funktion, die ein übergebenes Startdatum annimmt und auf Phils Antwort aufbaut:

function deltaDate(input, days, months, years) {
    return new Date(
      input.getFullYear() + years, 
      input.getMonth() + months, 
      Math.min(
        input.getDate() + days,
        new Date(input.getFullYear() + years, input.getMonth() + months + 1, 0).getDate()
      )
    );
}

zB schreibt das Datum vor einem Monat in das Konsolenprotokoll:

console.log(deltaDate(new Date(), 0, -1, 0));

zB subtrahiert einen Monat vom 30. März 2020:

console.log(deltaDate(new Date(2020, 2, 30), 0, -1, 0)); // Feb 29, 2020

Beachten Sie, dass dies auch dann funktioniert, wenn Sie das Ende des Monats oder Jahres überschreiten.

Update: Wie das obige Beispiel zeigt, wurde dies aktualisiert, um Abweichungen in der Anzahl der Tage in einem Monat zu behandeln.

N8allan
quelle
2
Aber es wird am Ende der Monate ein seltsames Verhalten haben. 29. März - 1 Monat = 29. Februar, was zum 1. März führt. 31. März + 1 Monat = 31. April, was zum 1. Mai führt. Abhängig von Ihrem Anwendungsfall entspricht dies möglicherweise nicht Ihren Erwartungen.
Johanneke
1
Vielen Dank an Johanneke. Ich habe den Code aktualisiert, um dies zu beheben.
N8allan
3

Verwenden Sie die Bibliothek moment.js für die Zeit- und Datumsverwaltung.

import moment = require('moment');

const now = moment();

now.subtract(7, 'seconds'); // 7 seconds ago
now.subtract(7, 'days');    // 7 days and 7 seconds ago
now.subtract(7, 'months');  // 7 months, 7 days and 7 seconds ago
now.subtract(7, 'years');   // 7 years, 7 months, 7 days and 7 seconds ago
// because `now` has been mutated, it no longer represents the current time
Younes Henni
quelle
1
Vielen Dank für Ihre nützliche Antwort. Genauer gesagt: "Vor Version 2.8.0 wurde auch die subtract(String, Number)Syntax unterstützt. Sie wurde zugunsten von subtract(Number, String)" veraltet. "
plkpiotr
2

Ich habe eine Funktion implementiert, die der momentjs- Methode subtrahiert .

- Wenn Sie Javascript verwenden

function addDate(dt, amount, dateType) {
  switch (dateType) {
    case 'days':
      return dt.setDate(dt.getDate() + amount) && dt;
    case 'weeks':
      return dt.setDate(dt.getDate() + (7 * amount)) && dt;
    case 'months':
      return dt.setMonth(dt.getMonth() + amount) && dt;
    case 'years':
      return dt.setFullYear( dt.getFullYear() + amount) && dt;
  }
}

Beispiel:

let dt = new Date();
dt = addDate(dt, -1, 'months');// use -1 to subtract 

- Wenn Sie Typescript verwenden:

export enum dateAmountType {
  DAYS,
  WEEKS,
  MONTHS,
  YEARS,
}

export function addDate(dt: Date, amount: number, dateType: dateAmountType): Date {
  switch (dateType) {
    case dateAmountType.DAYS:
      return dt.setDate(dt.getDate() + amount) && dt;
    case dateAmountType.WEEKS:
      return dt.setDate(dt.getDate() + (7 * amount)) && dt;
    case dateAmountType.MONTHS:
      return dt.setMonth(dt.getMonth() + amount) && dt;
    case dateAmountType.YEARS:
      return dt.setFullYear( dt.getFullYear() + amount) && dt;
  }
}

Beispiel:

let dt = new Date();
dt = addDate(dt, -1, 'months'); // use -1 to subtract

Optional (Unit-Tests)

Ich habe auch einige Unit-Tests für diese Funktion mit Jasmine durchgeführt :

  it('addDate() should works properly', () => {
    for (const test of [
      { amount: 1,  dateType: dateAmountType.DAYS,   expect: '2020-04-13'},
      { amount: -1, dateType: dateAmountType.DAYS,   expect: '2020-04-11'},
      { amount: 1,  dateType: dateAmountType.WEEKS,  expect: '2020-04-19'},
      { amount: -1, dateType: dateAmountType.WEEKS,  expect: '2020-04-05'},
      { amount: 1,  dateType: dateAmountType.MONTHS, expect: '2020-05-12'},
      { amount: -1, dateType: dateAmountType.MONTHS, expect: '2020-03-12'},
      { amount: 1,  dateType: dateAmountType.YEARS,  expect: '2021-04-12'},
      { amount: -1, dateType: dateAmountType.YEARS,  expect: '2019-04-12'},
    ]) {
      expect(formatDate(addDate(new Date('2020-04-12'), test.amount, test.dateType))).toBe(test.expect);
    }

  });

Um diesen Test verwenden zu können, benötigen Sie folgende Funktion:

// get format date as 'YYYY-MM-DD'
export function formatDate(date: Date): string {
  const d     = new Date(date);
  let month   = '' + (d.getMonth() + 1);
  let day     = '' + d.getDate();
  const year  = d.getFullYear();

  if (month.length < 2)  {
    month = '0' + month;
  }
  if (day.length < 2) {
    day = '0' + day;
  }

  return [year, month, day].join('-');
}
Stefano Borzì
quelle
1

Dies beantwortet die Frage nicht vollständig, aber für alle, die in der Lage sind, die Anzahl der Tage zu berechnen, um die sie ein Anfangsdatum versetzen möchten, funktioniert die folgende Methode:

myDate.setUTCDate(myDate.getUTCDate() + offsetDays);

offsetDays können positiv oder negativ sein und das Ergebnis ist für jedes gegebene Anfangsdatum mit jedem gegebenen Versatz korrekt.

Alan Gee
quelle
0

Ich habe eine einfachere Antwort, die tagelang perfekt funktioniert. seit Monaten sind es + -2 Tage:

let today=new Date();
const days_to_subtract=30;
let new_date= new Date(today.valueOf()-(days_to_subtract*24*60*60*1000));

Sie haben die Idee - monatelang mit 30 multiplizieren; aber das wird + -2 Tage sein.

Vinayak Thatte
quelle