从JavaScript中的日期中减去天,月,年


78

有人知道一种简单的约会方式(例如今天)并回溯X天,X个月和X年的简单方法吗?

我已经尝试过:

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

但是我得到一个负日期,例如今天的输出是:

2015年3月3日

有什么建议吗?

谢谢。


4
date.get....将返回一个a,Number并且如果您要从另一个中减去数字number,则值可以为负(如果左值较小)。我建议您使用DateObj.set...方法,然后检索相应的值...
人造丝

Answers:


105

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

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

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

14
getMonth()从零开始。这意味着它将显示错误的月份。示例:11月10日。
托尼

1
我们只是说:getMonth()是基于索引的。
GottZ

22

就像其他人所说的那样date.getDate(),您要从像这样的方法返回的数值中减去,您需要在date变量上重置这些值。我在下面创建了一个可以为您完成此操作的方法。它创建一个日期new Date(),该日期将使用当前日期进行初始化,然后根据传入的值设置日期,月份和年份。例如,如果您想返回6天,则像这样传入-6 var newdate = createDate(-6,0,0)。如果您不想设置一个值,请传入零(或者可以设置默认值)。该方法将为您返回新日期(已在Chrome和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;    
    }

17

我建议使用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/

更新:

在JavaScript中,Date.getDate()函数返回从1-31开始的当前日期。您将从这个数字中减去6,目前是该月的3号。这将值带到-3。


@Fvb谢谢,我阅读了指南,它是一个出色的库,感谢您使用它的想法。
user3378165's

请记住,moment.js为您的应用程序增加了大约1万6千。通常没什么大不了的。但是如果性能至关重要,那么对于如此小的计算,坚持使用普通的旧js会更便宜。
shanemgrey

3
当前版本的矩(在撰写本文时为2.18.2)对此功能发出警告。不建议使用add / subtract('period',number),建议您改用add / subtract(number,'period')。
杰米·M

11

这是一个纯函数,需要一个传递的开始日期,以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

请注意,即使您在月底或年份结束时也可以使用。

更新:如上面的示例所示,已对其进行了更新以处理一个月中天数的变化。


2
但几个月后它将有奇怪的行为。3月29日-1个月= 2月29日,将导致3月1日。3月31日+ 1个月= 4月31日,将导致5月1日。根据您的用例,可能不是您所期望的。
Johanneke

1
谢谢@Johanneke,我已经更新了代码以解决此问题。
N8allan

3

使用moment.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

1
感谢您的有用回答。更准确地说:“在2.8.0之前的版本中,subtract(String, Number)还支持该语法。不建议使用它,而推荐使用subtract(Number, String)“。
plkpiotr

2

我实现了类似于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

可选(单元测试)

我还使用Jasmine对该功能进行了一些单元测试:

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

1

这不能完全回答问题,但是对于任何能够计算他们希望抵消初始日期的天数的人,以下方法将起作用:

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

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


0

我有一个简单的答案,可以完美地工作几天。几个月,这是+ -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天。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.