Javascript:如何获取一周中第X天发生的NEXT

iqjalb3h  于 2023-01-11  发布在  Java
关注(0)|答案(3)|浏览(95)

我正在我的应用程序中构建一个功能,允许将事件安排到未来。IE:事件发生在每周三下午6:30。我需要根据今天的当前日期向用户显示下周三是什么时候。
如果今天是2018年12月6日星期四,则需要向用户显示下一个事件是“2018年12月12日星期三下午6:30”
如果今天是“2019年1月8日星期二”,则需要向用户显示下一个事件是“2019年1月9日星期三下午6:30”
事件的原始开始日期在我的数据库中被捕获为正在进行的系列的第一天。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

9vw9lbht

9vw9lbht1#

使用moment,不要尝试编写自己的日期函数,它只用于简单的计算。
https://momentjs.com/
Find next instance of a given weekday (ie. Monday) with moment.js

tjrkku2a

tjrkku2a2#

你的代码有很多问题。

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)) ;

似乎试图获得两个日期之间的天数差异,但它不适应时间组件,因此3 Nov 09:00到3 Nov 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());

源对象需要有重复周期单位和倍数。我已经添加了这些,但没有使用它们,你应该能够看到它去哪里。你还需要有增加和减少小时,天,月等函数。利用它们。有很多问题和答案在这里已经对这些主题。
如果我正在设计一个重复发生的事件对象,它将比上面的方法拥有更多的信息来处理各种场景。

uxhixvfz

uxhixvfz3#

假设您的数据库中只有一周中的几天和开始时间,例如:周一16:00周三18:30周五17:00
在我的例子中,我将数据库中的数据(星期几和时间)转换为数字,并将它们放入一个数组中,以便获得前一个和下一个值

const days_arr = [];
const dayToNumber = (day) => {
    if(day == 'Sunday') return 0;
    if(day == 'Monday') return 1;
    if(day == 'Tuesday') return 2;
    if(day == 'Wednesday') return 3;
    if(day == 'Thursday') return 4;
    if(day == 'Friday') return 5;
    if(day == 'Saturday') return 6;
}
db.query = SELECT day_name, from_time FROM table_of_days WHERE id!=id
const days = res.map((s) => {
    // slice(0, -3) to only use Hour because i have hh:mm  
    // converted day + hour into 3 digit number d+hh
    days_arr.push(Number(dayToNumber(s.day_name)+s.from_time.slice(0, -3)));
}
// days_arr output is [116, 318, 517] 

const given_date = new Date(your_date_variable)
// converting given_date into 3 digit number d+hh
const given_day = String(new Date(presence_date).getDay())+(String(new Date(presence_date).getHours())).padStart(2, '0');
// output given_day = 110

因为我们有事件的星期几,所以我们可以调用函数从days_arr中获取given_day的下一个/上一个值

const nextEvent = (days_arr, given_day) => {
    const arrayMin = function(days_arr) { return days_arr.reduce(function (p, v) { return ( p < v ? p : v ); }); }
    let next_day = Infinity;
    // only consider higher than the given_day
    const highest_values_arr = days_arr.filter(values => values > given_day);
    // if there is lower date ? get lower : get lower (first) of next week (from the entire array and not from highest value array)
    typeof highest_values_arr[0] != 'undefined' ? next_day = arrayMin(highest_values_arr) : next_day = arrayMin(days_arr);
    // now next_day has the result we are looking for 

    // i will use the first digit of the values in order to get how many days left
    // if next event day has not 3 char ? next event is today (0) : get first char as a day 
    let next_d = next_day.toString().length < 3 ? 0 : Number(next_day.toString()[0]) ;
    let given_d = given_day.toString().length < 3 ? 0 : Number(given_day.toString()[0]) ;
    
    // if next event day < given day ? count days left to finish the week + next day : ... ;
    let next_d_in = next_day < given_day ? (7 - given_d) + next_d : next_d - given_d ;

    return {
        next_day : next_day, // day & hour
        next_day_in : next_d_in // only days
    };
}
const previousEvent = (days_arr, given_day) => {
    const arrayMax = function (days_arr) { return days_arr.reduce(function (p, v) { return ( p > v ? p : v ); }); }
    let prev_day = 0;
    //only consider Lowest than given_day
    const lowest_values_arr = days_arr.filter(values => values < given_day);
    typeof lowest_values_arr[0] != 'undefined' ? prev_day = arrayMax(lowest_values_arr) : prev_day = arrayMax(days_arr);

    let prev_d = prev_day.toString().length < 3 ? 0 : Number(prev_day.toString()[0]) ;
    let given_d = given_day.toString().length < 3 ? 0 : Number(given_day.toString()[0]) ;
    let prev_d_in = prev_day > given_day ? (7 - prev_d) +  given_d : given_d - prev_d ;

    return {
        prev_day : prev_day, // day & hour
        prev_day_in : prev_d_in, // only days
    };
}

if(days.length != 0){
    const getNextEvent = nextEvent(days_arr, Number(given_day))  
    const getPrevEvent = previousEvent(days_arr, Number(given_day)) 

    // then use getPrevEvent & getNextEvent values to add/sub to the given date in order to get the full next/previous datetime
}else{
    // it's once a week
}

这可以帮助您根据星期几定义下一个和上一个事件日期
我只知道还剩多少天,我知道我没有深究还剩多少时间,我希望这对你有帮助。

相关问题