从JavaScript中减去日期

jon*_*bbs 548 javascript datetime date

有没有人知道一个简单的约会方式(例如今天)和回去X天?

因此,例如,如果我想在今天前5天计算日期.

Ste*_*ton 856

尝试这样的事情:

 var d = new Date();
 d.setDate(d.getDate()-5);
Run Code Online (Sandbox Code Playgroud)

请注意,这会修改日期对象并返回更新日期的时间值.

var d = new Date();

document.write('Today is: ' + d.toLocaleString());

d.setDate(d.getDate() - 5);

document.write('<br>5 days ago was: ' + d.toLocaleString());
Run Code Online (Sandbox Code Playgroud)

  • 鉴于这是google的顶部,我想我会回答上面的评论:`new Date(new Date().setDate(new Date().getDate() - 5))` - 这将是5天前.在答案示​​例中,将其传递给新日期以获取日期对象.所以`new Date(d)`就是你想要的. (145认同)
  • `setDate(-1)`将日期设置为该月的最后一天 (23认同)
  • 它的输出给了我一长串整数.有什么想法如何将其格式化为05/14/2012? (8认同)
  • 问题是你最终可能得到的00不是日期的有效值. (8认同)
  • @ user525146询问如何格式化数字,而不是数字是什么.不需要居高临下的答案.要格式化数字,请使用Date`toString`方法之一,如`toISOString`,`toDateString`等. (5认同)
  • "长整数串"是UTC时间,以毫秒为单位.如果这个概念对你来说是新的,或者你没有意识到为什么使用这种格式很重要,我建议你阅读这里的介绍部分(你可以跳过所有内容):http://www.tablespace.net/papers /unix_time.html (4认同)
  • 这不是正确的答案.如上所述,如果d是一个月的第一天,则这种方法不能正常工作. (4认同)
  • @SouvikBasu它完美无缺.就试一试吧! (2认同)
  • @TheCuBeMan setDate()比这更复杂.它将在当前月份中设置日期,但它也将应用边界逻辑.如果你调用`setDate(0)`它将减少月份并将日期设置为该月的最后一个月.如果你在二月份的某个日期调用`setDate(30)`,它将返回`March 2nd`.这就是为什么`getDate() - 1`解决方案可以工作**如果你将它传递给`setDate`**但是如果你只是寻找昨天的整数日期则不行.在这种情况下,您应该使用`d.setDate(d.getDate() - 1).getDate()`来对日历进行规范化. (2认同)
  • @Peter `setDate(-1)` 将设置为上个月的第二个最后一天。对于您想要的最后一天“setDate(0)”(仍然返回上个月,但您明白了)。 (2认同)
  • 似乎没有人阅读评论,但让我总结一下:#1 `setDate(0)`,有效,它给你上个月的最后一天。#2 这适用于闰年 `let d = new Date(1996,2,1); d.setDate(0); d` 为您提供“Thu Feb 29”。我将添加: #3 `setDate` 函数以数字形式返回时间,但变量已发生变化并且仍为日期形式。 (2认同)

kar*_*m79 71

var dateOffset = (24*60*60*1000) * 5; //5 days
var myDate = new Date();
myDate.setTime(myDate.getTime() - dateOffset);
Run Code Online (Sandbox Code Playgroud)

如果您在整个Web应用程序中执行大量日常操作,DateJS将使您的生活更轻松:

http://simonwillison.net/2007/Dec/3/datejs/

  • 这是一个边缘情况,但这可能会在夏令时的开始/结束时失败.你不是减去5天,而是5*24小时.夏令时的第一天只有23小时,最后一天是25小时.它通常无关紧要,但需要考虑的事情. (21认同)
  • @Kip我讨厌夏令时......和时区.我们都应该转向GMT. (9认同)
  • @cwallenpoole不会破坏你的泡沫,但他们甚至在格林威治使用DST.因此,如果您真的想参加GMT,那么您将被限制在冰岛和一些西非国家. (4认同)
  • @danielWilliams新的一年怎么办?getTime()和setTime()是自该纪元以来的毫秒数。时间是否跨过年份边界并不重要。 (3认同)

Bon*_*ict 49

如果您希望将所有内容都放在一行上。

从今天起5天

//past
var fiveDaysAgo = new Date(new Date().setDate(new Date().getDate() - 5));
//future
var fiveDaysInTheFuture = new Date(new Date().setDate(new Date().getDate() + 5));
Run Code Online (Sandbox Code Playgroud)

自特定日期起 5 天

 var pastDate = new Date('2019-12-12T00:00:00');

 //past
 var fiveDaysAgo = new Date(new Date().setDate(pastDate.getDate() - 5));
 //future
 var fiveDaysInTheFuture = new Date(new Date().setDate(pastDate.getDate() + 5));
Run Code Online (Sandbox Code Playgroud)

我写了一个你可以使用的函数。

//past
var fiveDaysAgo = new Date(new Date().setDate(new Date().getDate() - 5));
//future
var fiveDaysInTheFuture = new Date(new Date().setDate(new Date().getDate() + 5));
Run Code Online (Sandbox Code Playgroud)

  • 你不需要 add 参数,如果你想减去,只需传递 -5 就可以了:) (5认同)

Chr*_*sen 48

它是这样的:

var d = new Date(); // today!
var x = 5; // go back 5 days!
d.setDate(d.getDate() - x);
Run Code Online (Sandbox Code Playgroud)

  • d.setDate的返回值确实是一个整数值.但是,您可能实际上对此处的返回值不感兴趣,因为"d"的实际值已被修改.你真正的问题是如何格式化你的日期,现在是"d"而不是setDate的返回值.(嗯,它实际上是返回值,但它不是那个点的日期,我不想混淆你 - 只需使用d,它会更快).对于格式化日期,您需要d.getMonth(),d.getFullYear()和d.getDate()方法.你想在d.getMonth()中添加一个,因为Jan是0. (7认同)
  • 作为一个简单的方法:`function getDaysAgo(b){var a = new Date; a.setDate(a.getDate() - b); return a};`然后只是`var daysAgo45 = getDaysAgo(45);` (2认同)

awj*_*wjr 22

我注意到getDays + X在日/月边界上不起作用.只要您的日期不是1970年之前,就可以使用getTime.

var todayDate = new Date(), weekDate = new Date();
weekDate.setTime(todayDate.getTime()-(7*24*3600000));
Run Code Online (Sandbox Code Playgroud)

  • 这是不正确的,新的Date().setDate(-1)将为您提供上个月的最后一天. (11认同)
  • 我也注意到了.我更惊讶的是没有,或者我错过了什么? (2认同)
  • 在夏令时开始/结束的边缘情况下,这也是不正确的.假设每天都有24小时,你的方法减去7*24小时.夏令时的第一天只有23个小时,最后一天是25个小时.setDate(getDate() - 7)没有这个问题. (2认同)
  • getTime 工作于世界时。因此将从 Date 对象中正确减去 7 天时间。当您将其转换为指定时区的字符串时,它将正确显示该时区的时间。 (2认同)

Ken*_*max 17

得到moment.js.所有酷孩子都使用它.它有更多的格式选项,等等

var n = 5;
var dateMnsFive = moment(<your date>).subtract(n , 'day');
Run Code Online (Sandbox Code Playgroud)

可选的!转换为JS Date obj for Angular binding.

var date = new Date(dateMnsFive.toISOString());
Run Code Online (Sandbox Code Playgroud)

可选的!格式

var date = dateMnsFive.format("YYYY-MM-DD");
Run Code Online (Sandbox Code Playgroud)


Rob*_*ley 12

我为Date制作了这个原型,这样我就可以传递负值来减去天数和正值来增加天数.

if(!Date.prototype.adjustDate){
    Date.prototype.adjustDate = function(days){
        var date;

        days = days || 0;

        if(days === 0){
            date = new Date( this.getTime() );
        } else if(days > 0) {
            date = new Date( this.getTime() );

            date.setDate(date.getDate() + days);
        } else {
            date = new Date(
                this.getFullYear(),
                this.getMonth(),
                this.getDate() - Math.abs(days),
                this.getHours(),
                this.getMinutes(),
                this.getSeconds(),
                this.getMilliseconds()
            );
        }

        this.setTime(date.getTime());

        return this;
    };
}
Run Code Online (Sandbox Code Playgroud)

所以,要使用它,我可以简单地写:

var date_subtract = new Date().adjustDate(-4),
    date_add = new Date().adjustDate(4);
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用 `d.setDate(d.getDate() + days)` 和 *days* 的正负值来分别添加和减去天数。它应该在实例上工作(就像其他 Date 方法一样),而不是创建和返回副本。 (2认同)

pos*_*est 11

我喜欢在几毫秒内完成数学运算.所以使用Date.now()

var newDate = Date.now() + -5*24*3600*1000; // date 5 days ago in milliseconds
Run Code Online (Sandbox Code Playgroud)

如果你喜欢它格式化

new Date(newDate).toString(); // or .toUTCString or .toISOString ...
Run Code Online (Sandbox Code Playgroud)

注意:Date.now()在旧版浏览器中不起作用(例如IE8).Polyfill在这里.

2015年6月更新

@socketpair指出我的邋.. 正如他/她所说的那样"一年中的某些日子有23个小时,而根据时区规则,大约有25个小时".

为了扩展这一点,如果你想在5天前计算一个时区的日期变化,那么上面的答案会有一些日常的不准确之处

  • 假设(错误地)Date.now()给你当前的LOCAL现在时间,或
  • use .toString()返回本地日期,因此与Date.now()UTC中的基准日期不兼容.

但是,如果您使用UTC进行数学计算,则可以正常工作,例如

A.你想要从5天前开始的UTC日期(UTC)

var newDate = Date.now() + -5*24*3600*1000; // date 5 days ago in milliseconds UTC
new Date(newDate).toUTCString(); // or .toISOString(), BUT NOT toString
Run Code Online (Sandbox Code Playgroud)

B.您使用"现在"以外的UTC基准日期开始 Date.UTC()

newDate = new Date(Date.UTC(2015, 3, 1)).getTime() + -5*24*3600000;
new Date(newDate).toUTCString(); // or .toISOString BUT NOT toString
Run Code Online (Sandbox Code Playgroud)

  • 这不准确.一年中的某些日子有23个小时,而根据时区规则,大约有25个小时. (3认同)

Joe*_*ore 11

一些现有的解决方案很接近,但并不完全是我想要的.此函数适用于正值或负值,并处理边界情况.

function addDays(date, days) {
    return new Date(
        date.getFullYear(),
        date.getMonth(),
        date.getDate() + days,
        date.getHours(),
        date.getMinutes(),
        date.getSeconds(),
        date.getMilliseconds()
    );
}
Run Code Online (Sandbox Code Playgroud)

  • 如果我使用这种方法将20天增加到当月的第15个月,它是否"溢出"到下个月?它似乎没有. (2认同)
  • @Bora - 是的,如果有必要,它会正确地增加月份.例如,在8月15日添加20天:addDays(新日期(2015,07,15),20)将返回"2015年9月4日星期五00:00:00 GMT-0700(PDT)" (2认同)

Jos*_*hua 10

将您的日期拆分为多个部分,然后返回带有调整值的新日期

function DateAdd(date, type, amount){
    var y = date.getFullYear(),
        m = date.getMonth(),
        d = date.getDate();
    if(type === 'y'){
        y += amount;
    };
    if(type === 'm'){
        m += amount;
    };
    if(type === 'd'){
        d += amount;
    };
    return new Date(y, m, d);
}
Run Code Online (Sandbox Code Playgroud)

请记住,月份是零,但日子不是.即新日期(2009年,1,1)== 2009年2月1日,新日期(2009年,1,0)== 2009年1月31日;

  • 如果您通过这种方式添加例如50天的日期会发生什么?它会将日期设定为2009年8月68日吗?或者你确定这总是正确地包装到适当的月份和/或年份吗? (2认同)

Jon*_*tel 9

我发现getDate()/ setDate()方法的一个问题是它很容易将所有内容都转换为毫秒,而且语法有时很难让我遵循.

相反,我喜欢解决1天= 86,400,000毫秒的事实.

所以,对于你的特定问题:

today = new Date()
days = 86400000 //number of milliseconds in a day
fiveDaysAgo = new Date(today - (5*days))
Run Code Online (Sandbox Code Playgroud)

奇迹般有效.

我一直使用这种方法进行30/60/365天的滚动计算.

您可以轻松地推断这个以创建数月,数年等的时间单位.

  • 如果使用 TypeScript,则需要为“new Date(today.getTime() - (5*days))” (3认同)
  • 如果代码在凌晨 2 点附近运行并且夏令时在过去 5 天内发生了变化,则可能会给出不正确的结果。 (2认同)

小智 9

有些人建议使用 moment.js 来让你在 js 中处理日期时更轻松。这些答案已经过去了,值得注意的是,moment.js 的作者现在不鼓励使用它。主要是由于它的大小和缺乏摇树支撑。

如果您想走图书馆路线,请使用像Luxon这样的替代方案。它明显更小(因为它巧妙地使用了Intl 对象并支持 tree-shaking)并且与 moment.js 一样通用。

要返回 5 天后的 Luxon,您可以执行以下操作:

import { DateTime } from 'luxon'

DateTime.now().minus({ days: 5 });
Run Code Online (Sandbox Code Playgroud)


小智 5

function addDays (date, daysToAdd) {
  var _24HoursInMilliseconds = 86400000;
  return new Date(date.getTime() + daysToAdd * _24HoursInMilliseconds);
};

var now = new Date();

var yesterday = addDays(now, - 1);

var tomorrow = addDays(now, 1);
Run Code Online (Sandbox Code Playgroud)


小智 5

无需使用第二个变量,您可以将x替换为x天:

let d=new Date(new Date().getTime() - (7 * 24 * 60 * 60 * 1000))
Run Code Online (Sandbox Code Playgroud)

  • 我在另一个条目中评论了这一点,但这里也适用:由于时间调整,并非所有日子都是 8640 万毫秒。这可能会使结果失真 +/- 1 天 (4认同)