【问题标题】:Javascript: How to get NEXT occurring X day of weekJavascript:如何获得下一个发生在一周中的 X 天
【发布时间】:2018-12-06 22:06:07
【问题描述】:

我正在我的应用程序中构建一个功能,允许将事件安排到未来。 IE:该活动每周三下午 6:30 举行。我需要根据今天的当前日期向用户显示下一个星期三的时间。

如果今天是 2018 年 12 月 6 日星期四,则需要向用户显示下一个事件是“2018 年 12 月 12 日星期三下午 6:30”

如果今天是“2019 年 1 月 8 日星期二”,则需要向用户显示下一个事件是“2019 年 1 月 9 日星期三下午 6:30”

事件的原始开始日期是在我的数据库中捕获的,作为正在进行的系列的第一天。 IE:2018 年 9 月 10 日,星期三。我正在使用该开始日期来尝试计算每个下周三。

  function nextEvent(cEvent) {
      var startDate = cEvent.ceDate+ ", " +cEvent.ceTime ;
      var ceDate = new Date(startDate) ;
      var curDate = new Date() ;
      var timeDiff = Math.abs(curDate.getTime() - ceDate.getTime()) ;
      var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24)) ;
      var addDays = Math.ceil(diffDays / 7) * 7 ;
      var futureDate = ceDate.setDate(ceDate.getDate() + addDays) ;
      var futureEvent = ceDate.format('D, M d, Y @ g:i a') ;
      return futureEvent ;
    }
  }

  // this date object START event is Wed Sept 10, 2018
  var dObject = {"ceDate":"2018-09-10","ceTime":"18:30:00"}
  var nextDate = nextEvent(dObject) ;

我正在循环浏览几个事件,所有事件都使用不同的开始日期(即:ceDate),而 NEXT 事件在第二天显示错误。上面的示例(在 dObject 中硬编码)显示 Mon Dec 10, 2018,而它应该显示 Wed Dec 12, 2018

同样,如果今天是星期三下午 6 点,则下一个事件仍需要在下午 6 点 30 分显示为今天。活动至少持续 2 小时......所以理想情况下,我还想弄清楚如何展示如下内容:Next Event: happening now til 8:30pm

【问题讨论】:

标签: javascript date datetime date-arithmetic


【解决方案1】:

使用时刻,不要尝试编写自己的日期函数来进行简单的计算。

https://momentjs.com/

Find next instance of a given weekday (ie. Monday) with moment.js

【讨论】:

  • "使用库 X" 不是一个有用的答案。这可能是一个有用的评论。
【解决方案2】:

您的代码存在许多问题。给定:

 var dObject = {"ceDate":"2018-09-10","ceTime":"18:30:00"}

然后

var startDate = cEvent.ceDate+ ", " +cEvent.ceTime ;

将构建一个类似 "2018-09-10, 18:30:00" 的字符串,它不是 ECMAScript 支持的格式,所以当你这样做时:

var ceDate = new Date(startDate);

结果取决于实现,很可能导致日期无效。

下一步:

var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24)) ;

似乎试图获取两个日期之间的天数差异,但它不包含时间部分,因此 11 月 3 日 09:00 到 11 月 3 日 09:01 将是 1 天,即使它是在同一天仅 1 分钟后。

无论如何,根据您确定每周事件下一次发生的要求,您可以获得本周的事件,如果已通过,则添加 7 天,例如

var dObject = {
  "ceDate": "2018-09-10", // Mon, 9 Sep 2018
  "ceTime": "18:30:00",
  "recurrenceUnit": "day",
  "recurrenceLength": 7
}

// Helper to parse ISO date as local
function parseISOLocal(s) {
  var b = s.split(/\D/);
  return new Date(b[0],b[1]-1,b[2]);
}

function nextEvent(obj) {
  // Get today's details
  var now = new Date();
  var day = now.getDay();

  // Get event details
  var evtDate = parseISOLocal(obj.ceDate);
  var evtDay = evtDate.getDay();
  
  // Set nextEvt to event for this week
  var nextEvt = new Date(+now);
  nextEvt.setHours(0,0,0,0);
  nextEvt.setDate(nextEvt.getDate() - day + evtDay);
  nextEvt.setHours(...obj.ceTime.split(/\D/));
  
  // If the nextEvent has passed, add 7 days
  // Should use the recurrenceUnit and recurrenceLength
  if (nextEvt < now) {
    nextEvt.setDate(nextEvt.getDate() + 7)
  }

  return nextEvt;
}

console.log(nextEvent(dObject).toString());

源对象需要有重复周期单位和倍数。我已经添加了这些但没有使用它们,你应该能够看到它的去向。您还需要具有加减小时、天、月等功能以利用它们。这里已经有很多关于这些主题的问题和答案。

如果我正在设计一个循环事件对象,它会比上面包含更多的信息以及处理各种场景的方法。

【讨论】:

  • 感谢您的详细回复。在什么实现中,ceDate+ ", " +ceTime 的串联会返回不正确的日期对象?
  • @rolinger——至少是 Safari 和 Firefox。但与其说有没有失败的情况,不如说它是否符合语言规范。现在它们之间几乎没有区别,但是当有一个简单的、符合标准的替代方案时,您不应该依赖标准化的行为。 :-)
猜你喜欢
  • 1970-01-01
  • 2012-12-12
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
  • 2011-03-20
  • 2015-08-14
  • 1970-01-01
  • 2012-12-01
相关资源
最近更新 更多