繁体   English   中英

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

[英]Subtract days, months, years from a date in JavaScript

有人知道约会(例如今天)并返回 X 天、X 个月和 X 年的简单方法吗?

我试过了:

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

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

3/-3/2015

有什么建议吗?

谢谢。

您只是从数字中减少值。 因此,从 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()));

正如其他人所说,您正在从date.getDate()等方法返回的数值中减去,您需要在日期变量上重置这些值。 我在下面创建了一个方法来为你做这件事。 它使用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;    
    }

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

如果您使用 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。

这是一个纯函数,它采用传入的开始日期,以 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

请注意,即使您已经过了月末或年末,这也有效。

更新:如上例所示,此更新已更新以处理一个月中天数的差异。

我实现了一个类似于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('-');
}

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

我有一个更简单的答案,它可以完美运行几天; 几个月,它是 +-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 天。

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

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

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

例如,获取昨天日期的 oneliner 将是:

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM