Subtract days, months, years from a date in JavaScript

Does anybody know of a simple way of taking a date (e.g. Today) and going back X days, X months and X years?

I have tried that:

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

But I got a negative date, for example today the output was:

3/-3/2015

Any advise?

Thanks.

194465 次浏览

2021年更新:

MomentJS has been replaced/improved with LuxonJS, a much more up-to-date and newer version. You can find it here: https://moment.github.io/luxon/#/

我将暂时离开这个旧职位,因为它仍然可以帮助别人。

Old post:

我建议使用 MomentJS 库,它们使得所有与 Dates 的交互变得更加简单。

如果您使用 Moment,您的代码将如下所示:

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

你可以在这里找到 MomentJS: http://momentjs.com/

更新:

In JavaScript, the Date.getDate() function returns the current day of the month from 1-31. You are subtracting 6 from this number, and it is currently the 3rd of the month. This brings the value to -3.

您只是简单地从一个数字中减去值。因此,从3(日期)中减去6将只返回 -3。

您需要在 date 对象中单独添加/删除时间单位

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

As others have said you're subtracting from the numeric values returned from methods like date.getDate(), you need to reset those values on your date variable. I've created a method below that will do this for you. It creates a date using new Date() which will initialize with the current date, then sets the date, month, and year according to the values passed in. For example, if you want to go back 6 days then pass in -6 like so var newdate = createDate(-6,0,0). If you don't want to set a value pass in a zero (or you could set default values). The method will return the new date for you (tested in Chrome and 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 的回答,它需要一个传递的开始日期:

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

例如,将一个月前的日期写入控制台日志:

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

例如,从2020年3月30日起减去一个月:

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

请注意,即使过了月底或年底,这也是有效的。

更新: 正如上面的示例所示,这已经被更新以处理一个月中天数方面的差异。

这并不能完全回答这个问题,但是对于任何能够计算出他们希望抵消初始日期的天数的人来说,以下方法可行:

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

OffsetDays 可以是正数也可以是负数,对于任何给定的初始日期和任何给定的偏移量,结果都是正确的。

使用 等一下 JS库进行时间和日期管理。

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

我实现了一个类似于 momentjs方法 减去的函数。

如果你使用 Javascript

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;
}
}

例如:

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

- 如果你使用打字稿:

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;
}
}

例如:

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

可选(单元测试)

我还使用 茉莉对这个函数进行了一些单元测试:

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


});

要使用这个测试,你需要这个函数:

// 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('-');
}

我有一个更简单的答案,它可以完美地工作几天; 对于几个月来说,它是 +-2天:

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

你得到了这个想法-几个月,乘以30; 但那将是 +-2天。

例如,得到昨天日期的线条是:

const yesterday = ((date) => date.setDate(date.getDate() - 1) && date)(new Date());

它将定义一个箭头函数,接收 new Date()作为参数(日期)。创建箭头函数的原因是新的 Date 对象将被多次使用。首先检索当前日期(getDate) ,然后设置日期(setDate) ,并将其作为结果返回。所以它会返回变异日期,而不是原始日期。

现在定义了这个箭头函数,并将立即使用 new Date()调用它,以返回昨天的日期。

香草 JS Date将时间从 史诗时代(1970)节省为毫秒,因此我们所需要做的就是以毫秒为单位减去。 如果我们想减去10天,我们会减去1000(ms) * 60(s) * 60(m) * 24(h) * 10(d)

A simple Vanilla function to subtract from a date (notice the years exception):

subtractFromDate(new Date(), { hours: 15 }) // now - 15 hours
subtractFromDate(new Date(), { days: 15 }) // now - 15 days
subtractFromDate(new Date(), { years: 15 }) // now - 15 years
const subtractFromDate = (
date,
{ years, days, hours, minutes, seconds, milliseconds } = {}
) => {
const millisecondsOffset = milliseconds ?? 0
const secondsOffset = seconds ? 1000 * seconds : 0
const minutesOffset = minutes ? 1000 * 60 * minutes : 0
const hoursOffset = hours ? 1000 * 60 * 60 * hours : 0
const daysOffset = days ? 1000 * 60 * 60 * 24 * days : 0
const dateOffset =
millisecondsOffset +
secondsOffset +
minutesOffset +
hoursOffset +
daysOffset


let newDate = date
if (years) newDate = date.setFullYear(date.getFullYear() - years)
newDate = new Date(newDate - dateOffset)


return newDate
}