【问题标题】:Simple javascript date math... not really简单的javascript日期数学......不是真的
【发布时间】:2011-06-15 10:13:55
【问题描述】:

我正在尝试创建一个简单的脚本,根据从 2011 年 7 月 6 日星期三开始的双周计划,为我提供下一个回收日期。所以我创建了这个简单的函数...

    function getNextDate(startDate) {
        if (today <= startDate) {
            return startDate;
        }
        // calculate the day since the start date.
        var totalDays = Math.ceil((today.getTime()-startDate.getTime())/(one_day));
        // check to see if this day falls on a recycle day 
        var bumpDays = totalDays%14;  // mod 14 -- pickup up every 14 days...
        // pickup is today
        if (bumpDays == 0) {
            return today;
        }
        // return the closest day which is in 14 days, less the # of days since the last
        // pick up..
        var ms =  today.getTime() + ((14- bumpDays) * one_day);
        return new Date(ms);
    }

并且可以这样称呼它......

 var today=new Date();
 var one_day=1000*60*60*24;  // one day in milliseconds
 var nextDate = getNextDate(new Date(2011,06,06));

到目前为止一切顺利...但是当我将“今天”计划到 2011 年 10 月 27 日时,我会将 2011 年 8 月 11 日星期二作为下一个日期,而不是 2011 年 11 月 9 日星期三...实际上每个从现在到 2011 年 10 月 26 日的那一天预测正确的接送......从 2011 年 10 月 27 日到 2012 年 2 月 28 日的每个日期都预测周二而不是周三。然后从 2012 年 2 月 29 日(闰年)到 2012 年 10 月 24 日(嗯,又是 10 月)的每个日期都正确预测星期三。我错过了什么?任何帮助将不胜感激..

V

【问题讨论】:

  • 天花板不应该是地板吗?因为是你使用 2011-06-06 1:00u totalDays 将是 1,下一次取件将在 13 天而不是 14 天,所以是星期二。
  • 看起来很奇怪。我得到了one_day=1000*60*60*24; today = new Date(2011,8,27); nextDate = getNextDate(new Date(2011,6,6)); 的正确日期,而nextDate 是Wed Sep 28 2011 00:00:00 GMT+,这是正确的吗?在 FF4 上测试。
  • startDate 总是新的 Date(2011,06,06) -- 所以它不应该移动
  • Raze,您使用的日期可以正常使用,请尝试 2​​011 年 10 月 27 日至 2012 年 2 月 28 日范围内的日期..
  • 如果您在美国,那么您在 10 月到 11 月的跨度内正从夏令时过渡到标准时间。

标签: javascript math date


【解决方案1】:

最简单的方法是使用setDate 更新Date 对象。由于此答案的 cmets 表明这不是规范的正式部分,但所有主要浏览器都支持它。

您应该永远不要更新与您最初调用 getDate 的对象不同的 Date 对象。

示例实现:

var incrementDate = function (date, amount) {
    var tmpDate = new Date(date);
    tmpDate.setDate(tmpDate.getDate() + amount)
    return tmpDate;
};

如果您要增加日期,请使用此功能。它将接受正值和负值。它还保证使用的日期对象不会更改。如果您不希望更新更改对象的值,这应该可以防止可能发生的任何错误。


错误用法:

var startDate = new Date('2013-11-01T11:00:00');
var a = new Date();
a.setDate(startDate.getDate() + 14)

这将根据a 的值将startDate 的“日期”值更新为14 天。因为a 的值与之前定义的startDate 不同,所以可能会得到错误的值。

【讨论】:

  • 很难找到保证这在一般情况下有效的文档(添加任意天数)。
  • 这是一个非常危险的思考过程。想象一下“startDate”是一个月的 1 号,而今天是 31 号。您想要从 startdate 7 天后的日期。 a.setDate(startDate.getDate() - 7) 就足够了,对吧?没那么快。 'a' 现在是 当前 月份开始前 7 天,而不是 'startDate' 前 7 天。考虑到此页面出现在 Google 结果中的哪个位置,了解这一点绝对重要。我现在正在纠正这样的问题,并且强烈怀疑我们的承包商找到了这个页面并遵循了这个确切的逻辑。
  • 嗯,我从未打算以您描述的方式使用它。仅用于更新日期值。我将更改我的答案以反映问题。
  • @10gistic a 现在是本月初前 7 天,而不是 startDate 前 7 天。 为什么a 现在是本月初前 7 天当月月初,而不是startDate 之前的 7 天? getDate 没有获取日期 date 对象吗?
  • @10gistic 仔细查看文档解释了它。我的困惑是我认为getDate 返回了日期,getTime 返回了时间。 getDate 不返回日期,getTime 不返回时间。 getTime() 返回日期(自 1970 年以来以毫秒为单位的值)。 getDate() 返回月份中的某一天 (1..31)。如果您认为getDate 返回日期时间的日期部分,您会看到该算法的意义。
【解决方案2】:

扩展 Exellian 的答案,如果您想计算未来的任何时期(在我的情况下,为下一个付款日期),您可以做一个简单的循环:

var today = new Date();
var basePayDate = new Date(2012, 9, 23, 0, 0, 0, 0);

while (basePayDate < today) {
    basePayDate.setDate(basePayDate.getDate()+14);
}

var nextPayDate = new Date(basePayDate.getTime());
basePayDate.setDate(nextPayDate.getDate()-14);

document.writeln("<p>Previous pay Date: " + basePayDate.toString());
document.writeln("<p>Current Date: " + today.toString());
document.writeln("<p>Next pay Date: " + nextPayDate.toString());

假设核心日期服务按预期工作,这不会遇到奇怪的问题。我必须承认,我在未来很多年都没有测试过......

【讨论】:

    【解决方案3】:

    注意:我遇到了类似的问题;我想每周创建一个日期数组,即开始日期 10/23/2011 并持续 12 周。我的代码或多或少是这样的:

    var myDate = new Date(Date.parse(document.eventForm.startDate.value));
    var toDate = new Date(myDate);
    
    var week = 60 * 60 * 24 * 7 * 1000;
    var milliseconds = toDate.getTime();
    
    dateArray[0] = myDate.format('m/d/Y');
    
    for (var count = 1; count < numberOccurrences; count++) {
        milliseconds += week;
    toDate.setTime(milliseconds);
        dateArray[count] = toDate.format('m/d/Y');
    }
    

    因为我没有指定时间,而且我住在美国,所以我的默认时间是午夜,所以当我越过夏令时边界时,我就搬到了前一天。呸。我通过在计算周数之前将时间设置为中午来解决这个问题。

    【讨论】:

      猜你喜欢
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      • 2012-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多