根据给定的日期,从一个范围内选择日期。

4

我有一个日期范围

日期范例:

const startDate = "2022-06-02";
const endDate = "2022-06-20";

我想获取那些日期,在提供的日期数组中,它们落在开始日期和结束日期之间。

例如,日期数组:

["tuesday", "friday", "saturday"]

预期结果是:
2022-06-03
2022-06-04
2022-06-07
2022-06-10
2022-06-11
2022-06-14
2022-06-17
2022-06-18

有人能帮我解决这个逻辑吗?

我尝试的方法很丑陋,我在日期范围上放了一个循环,并获取了所有日期的列表,然后再放一个循环来获取每个日期的星期几名称,并将每个星期几名称与一个包含星期几名称的数组进行比较,最后将该日期推送到新数组中。

以下是代码(它完美地工作),但我需要更好的解决方案

function getDaysArray(start, end) {
        
    for(var arr=[],dt=new Date(start); dt<=new Date(end); dt.setDate(dt.getDate()+1)){
        
        arr.push(helperClass.getDateTime(new Date(dt)).date);
    }
    
    return arr;
}

function getDayName (dateStr, locale){

    var date = new Date(dateStr);

    return date.toLocaleDateString(locale, { weekday: 'long' });        
}

var days = ["tuesday", "friday", "saturday"];

var getAllDates = getDaysArray("2022-06-02", "2022-06-20");
var getDates = [];
for(var i = 0; i < getAllDates.length; i++){

    if(days.includes(getDayName(getAllDates[i]).toLowerCase())){

        getDates.push(getAllDates[i])
    }
}

你尝试过什么吗? - rustyBucketBay
1
@rustyBucketBay 我尝试的方法很粗糙,我使用了日期范围的循环,并获取了所有日期的列表,然后我又使用了另一个循环来获取每个日期的星期几名称,并将每个日期名称与一组日期进行比较,将符合条件的日期推入新数组。 - StormTrooper
最好使用数字数组,其中星期日=0,星期六=6。然后,您只需创建一个日期数组,并根据getDay的值进行过滤即可。 - Heretic Monkey
请将您尝试过的实际代码放入,而不是描述,并格式化为代码。 - Heretic Monkey
@StormTrooper,我认为你知道SO的工作方式。在我看来,不应该期望社区为你解决代码问题。你需要展示可重现的例子,包括你期望得到的结果和实际得到的结果等。这是一个明显可以这样做的问题。 - rustyBucketBay
显示剩余2条评论
3个回答

0

如果您可以使用外部库,则date-fns库提供了一些辅助功能:

  • parse - 使用给定的格式字符串返回从字符串解析的日期。
  • eachDayOfInterval - 返回指定时间间隔内的日期数组。
  • getDay - 获取给定日期的星期几。
  • 或者is*辅助函数 - 例如 isSunday, isMonday 等。

所以如果你解析起始日期和结束日期,获取完整的时间间隔范围,然后对其进行与天数的筛选,你就可以得到列表。

import("https://unpkg.com/date-fns@2.28.0/esm/index.js").then(({ eachDayOfInterval, getDay, parse }) => {
    const startDate = parse("2022-06-02", "yyyy-MM-dd", new Date());
    const endDate = parse("2022-06-20", "yyyy-MM-dd", new Date());
    const daysOfWeek = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];

    // Here is your list
    const daysToFilterFor = ["tuesday", "friday", "saturday"];
    const daysToFilterForIndex = daysToFilterFor.map((day) => daysOfWeek.indexOf(day));

    const range = eachDayOfInterval({
        start: startDate,
        end: endDate,
    }).filter((day) => daysToFilterForIndex.includes(getDay(day)));

    console.log(range);
});


0

详细信息在示例中有注释

// Array of days to filter
const daysOff = ["Tuesday", "Friday", "Saturday"];

/**
 * @desc Determine the specific dates of days that match a given array
 * of weekdays within the range of two given dates.
 * @param {string<date>} start - The first date of the range
 * @param {string<date>} end - The last date of the range
 * @param {array<string>} weekdays - The list of days used to find the dates
 * @return {array<date>} An array of dates that correspond to weekdays
 */
function dateRanger(start, end, weekdays) {

  // Convert dates into timestamps {number}
  const A = Date.parse(start);
  const Z = Date.parse(end);

  // Seconds in a day
  const day = 86400000;
  // Determine number of days the range spans
  const total = Math.floor(((Z - A) / day) + 1);
  // Object that stores format settings for .toLocaleDateString()
  const options = {
    weekday: 'long',
    year: 'numeric',
    month: 'numeric',
    day: 'numeric'
  };

  /*
  - Instantiate an Array with room to fit the range of dates
  - On each iteration instantiate a date based on the first date then format 
    it and add it's weekday using .toLocaleDateString() 
  - Return date string as an array of pairs using .split()
  */
  const range = [...new Array(total)].map(
    (_, i) => new Date(A + (day * i))
    .toLocaleDateString('en-US', options)
    .split(', ')
  );

  /*
  - .flatMap() the first level of range to access the array of pairs
  - On each iteration compare the first value of each pair (sub[0]) with the 
    given array (weekdays).
  - If there's a match, return the second value (sub[1]) of each pair 
  - Otherwise return an empty array that gets flattened to zilch.
  */
  return range.flatMap(
    sub => weekdays.flatMap(
      day => day === sub[0] ?
      sub[1] : []
    )
  );
}

console.log(dateRanger('6-4-2022', '6-20-2022', daysOff));


-1

我知道这可能不是最好的方法,但这是我做的方式

let days = { monday: 0, tuesday: 1, wednesday: 2, thursday: 3, friday: 4, saturday: 5, sunday: 6 };
const startDate = "2022-06-02";
const endDate = "2022-06-20";
function daysindates(arr) {
    let stdate = startDate.substr(-2);
    let endate = endDate.substr(-2);
    let myarr = [],
        result = [],
        finalresult = [];
    for (y of arr) {
        for (let i = parseInt(stdate) + days[y]; i <= parseInt(endate); i += 7) {
            result.push(i);
        }
    }
    finalresult = result.map((item) => {
        return "2022-06-" + item;
    });
    console.log(finalresult);
}

daysindates(["monday", "tuesday"]);


你需要设置 result = [] - Lee Taylor
你的代码中为什么2022-06-是静态的? - StormTrooper
我只让它在同一个月份内工作,好的,我要改变它。 - Sevada 797
这个不起作用。第一个结果是“2022-06-2”,那是星期四,不是星期一或星期二。代码没有缩进,有许多未声明的变量,函数名毫无意义等等。 - RobG
它被调用时使用了 ["星期一", "星期二"],但返回的日期是星期四和星期五,所以不,不是“好的”。 - RobG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接