【问题标题】:How do i add years, months, days, hours, minutes or seconds to JavaScript Date object?如何向 JavaScript Date 对象添加年、月、日、小时、分钟或秒?
【发布时间】:2019-04-19 15:53:43
【问题描述】:

我经常遇到想在 JavaScript 中的 Date 对象中添加年、月、日、小时、分钟或秒的情况。每个特定“添加”都有很多方法描述(编辑:例如添加日),但我还没有在stackoverflow上找到完整的解决方案,所以我决定在@分享我的方法987654321@ 风格。 My own answer 是一种不使用框架来处理问题的方法。


cmets 和答案中建议的问题的其他解决方案:

处理问题的框架/库:

moment.js(感谢 JonnyIrving/Eugene Mihaylin/Pac0)

https://blog.bitsrc.io/9-javascript-date-time-libraries-for-2018-12d82f37872d(感谢 RobG)

fecha.js(感谢 RobG)

特定添加主题的示例(感谢 Pac0):

天数:Add days to JavaScript Date

分钟:How to add 30 minutes to a JavaScript Date object?

时间:Adding hours to Javascript Date object?

月份:JavaScript function to add X months to a date


(我不会将任何答案标记为已接受,因为我认为有多种有效方式)

【问题讨论】:

标签: javascript date datetime time date-arithmetic


【解决方案1】:

我的方法是使用以下添加功能扩展 Date.prototype:

Date.prototype.addYears = Date.prototype.addYears || function (y, supressSet) {
    if (!supressSet) { this.setFullYear(this.getFullYear() + y); return this; }
    return new Date(this).addYears(y);
};
Date.prototype.addDays = Date.prototype.addDays || function (d, supressSet) {
    return this.addHours(d * 24, supressSet);
};
Date.prototype.addHours = Date.prototype.addHours || function (h, supressSet) {
    return this.addMinutes(h * 60, supressSet);
};
Date.prototype.addMinutes = Date.prototype.addMinutes || function (m, supressSet) {
    return this.addSeconds(m * 60, supressSet);
};
Date.prototype.addSeconds = Date.prototype.addSeconds || function (s, supressSet) {
    return this.addMilliseconds(s * 1000, supressSet);
};
Date.prototype.addMilliseconds = Date.prototype.addMilliseconds || function (ms, supressSet) {
    if (!supressSet) { this.setTime(this.getTime() + ms); return this; }
    return new Date(this).addMilliseconds(ms);
};

supressSet 参数是可选的,它使相应的函数作为 getter 工作,而无需更改对象本身。如果省略,则评估为 false,这意味着将修改原始日期对象。

正如 cmets 中指出的那样,我没有考虑闰年。为此,我采用并调整了几个月的解决方案from Jazaret

var DateHelper = {
    isLeapYear: function (year) {
        return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
    },
    getDaysInMonth: function (dateinput) {
        return [31, (DateHelper.isLeapYear(dateinput.getFullYear()) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][dateinput.getMonth()];
    }
};

Date.prototype.addMonths = function (m, supressSet) {
    var n = this.getDate(),nDate=new Date(this);
    nDate.setDate(1);
    nDate.setMonth(nDate.getMonth() + m);
    nDate.setDate(Math.min(n, DateHelper.getDaysInMonth(nDate)));
    if (!supressSet) {
        this.setDate(nDate.getDate()); this.setMonth(nDate.getMonth());
    }
    return nDate;
};

【讨论】:

  • 在多个库位于同一个命名空间中的今天,扩展原生原型已不再有用。这就是过去流行的库的问题,因为他们在争论谁能用他们的 addX 版本扩展 Date、Functiona 和 Object。
  • 另外,添加一天并不总是添加 24 小时。这将以某种方式取决于时区,即使在 UTC 中你也有闰秒,这不会被考虑在内。
  • 这似乎是一个毫无意义的练习,而且是错误的。添加 1 天与添加 24 小时不同,您越过夏令时边界。此外,您添加月份的方式意味着 1 月 31 日 + 1 个月将是 3 月 2 日或 3 日,具体取决于它是否是闰年。添加负月份将产生类似的结果:3 月 31 日 + -1 月将是 3 月 2 日或 3 日。在 31 天和 30 天的几个月里,您会得到类似的结果。
  • 如果您的计算机处于夏令时之后的时区,您可以尝试.addDays(180),结果会延迟 1 小时。
  • 简而言之:日期/日历算术比它看起来要困难得多,并且自己滚动会使您陷入很多陷阱,图书馆(有点)或多或少地处理得比较顺利。
【解决方案2】:

尝试跳出JS约会地狱,使用广泛使用的moment.js library

moment('2018-01-01').add(1, 'day'); 

moment('2018-01-01').add(1, 'hour');

等等……

【讨论】:

    【解决方案3】:

    您可以使用moment.js

    moment('2000-01-01').add(1, 'year');
    moment('2000-01-01').add(1, 'month');
    moment('2000-01-01').add(1, 'days');
    moment('2000-01-01').add(1, 'hour');
    

    或手动制作,例如answer

    【讨论】:

      【解决方案4】:

      你可能不倾向于引入一个库来解决这个问题,我理解有时最好还是用普通的,但就我个人而言,我发现在 JS 中处理日期和时间的所有令人头疼的事情变得容易多了你介绍 Moment.js 库。

      您可以在这里查看文档:https://momentjs.com/docs/#/parsing/date/

      下面我展示了它在添加时间单位方面可以做什么,但正如您从文档中看到的那样,它可以做的更多。例如,它非常擅长格式化日期对象。

      moment(new Date());
      
      var nowPlusYear = moment().add(1, 'year');
      var nowPlusMonth = moment().add(1, 'month');
      var nowPlusMinute = moment().add(1, 'minute');
      
      console.log("In 1 year it will be", nowPlusYear);
      console.log("In 1 month it will be", nowPlusMonth);
      console.log("In 1 minute it will be", nowPlusMinute);
      <script src="https://cdn.jsdelivr.net/momentjs/2.10.6/moment-with-locales.min.js"></script>

      不管怎样,看看你的想法。

      希望这会有所帮助!

      【讨论】:

      • 感谢您的贡献,我在原始问题中添加了链接。我认为我不会将任何答案标记为已接受,因为我认为有多种有效的方法(到目前为止,我会标记这个和我的)。投赞成票。
      • 当然没问题!对原始问题进行了很好的修改。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-25
      • 2011-07-26
      • 2010-11-06
      • 2019-09-30
      • 1970-01-01
      • 2021-06-06
      相关资源
      最近更新 更多