在JavaScript中获取给定月份和年份的周范围

时间:2019-10-25 13:02:56

标签: javascript typescript

我需要显示所选月份的相应星期中的日期范围。假设选择的值为month=3(四月)和year=2018。输出应显示所选的特定月份中数周的日期范围。

month = 3;
year = 2018;

输出:

  

第1周:2018年1月4日至2018年1月4日

     

第2周:02/02/04-2018/08/04

     

第3周:2018年9月4日-2018年4月15日

     

第4周:16/04/2018-22/04/2018

     

第5周:23/04/2018-29/04/2018

     

第6周:30/04/2018-30/04/2018

我尝试了此功能,但无法正常工作。你能帮助我吗 ?非常感谢。

public getWeeksInMonth(): {

  let year: number = 2018;
  let month: number = 3 //April;

  const weeks = [];
  const firstDay: Date = new Date(year, month, 1);
  const lastDay: Date = new Date(year, month + 1, 0);
  const daysInMonth: number = lastDay.getDate();
  let dayOfWeek: number = firstDay.getDay();
  let start: number;
  let end: number;

  for (let i = 1; i < daysInMonth + 1; i++) {

    if (dayOfWeek === 0 || i === 1) {
      start = i;
    }

    if (dayOfWeek === 6 || i === daysInMonth) {

      end = i;

      if ((start !== end) || (start === 30 && end === 30) || (start === 31 && end === 31)) {

        weeks.push({
          'start': start,
          'end': end
        });
      }
    }

    dayOfWeek = new Date(year, month, i).getDay();
  }

  return weeks;
}

3 个答案:

答案 0 :(得分:0)

第一个问题是,星期日是0之前的.getDay()而不是星期一。

  

此问题已解决,它检查了dayOfWeek === 1而不是dayOfWeek === 0dayOfWeek === 0而不是dayOfWeek === 6

第二个问题是您在推送新的week之前要进行检查。您正在检查start !== endstart是否等于end

  

通过在推新一周后将start设置为null并检查start来解决此问题。

(下面的示例是用JS编写的,因为TS无法在StackOverflow上运行)

function getWeeksInMonth() {

  let year = 2018;
  let month = 3; //April;

  const weeks = [];
  const firstDay = new Date(year, month, 1);
  const lastDay = new Date(year, month + 1, 0);
  const daysInMonth = lastDay.getDate();
  let dayOfWeek = firstDay.getDay();
  let start;
  let oldstart;
  let end;

  for (let i = 1; i < daysInMonth + 1; i++) {

    if (dayOfWeek === 1 || i === 1) {
      start = i;
    }

    if (dayOfWeek === 0 || i === daysInMonth) {

      end = i;

      if(start){
        weeks.push({
          'start': start,
          'end': end
        });
        start = null;
      }
    }

    dayOfWeek = new Date(year, month, i + 1).getDay();
  }

  return weeks;
}

console.log(getWeeksInMonth());

答案 1 :(得分:0)

我已经稍微重构了您的解决方案,它似乎可以实现预期的结果。

我的代码遵循与您完全相同的方法(蛮力):

  • 组成一个数组(长度为Array.from()),该数组的长度等于给定月份中的天数,并用该月中每一天的日期填充它;
  • 循环遍历该数组(使用Array.prototype.reduce()),并放入对应于星期的结果数组对象({week,start,end}),在星期一时生成新对象,在星期日时关闭结束日期:

const getWeeksInMonth = (month, year) => 
	Array
	.from({length: (new Date(year, month+1, 0) - new Date(year, month, 0))/864E5}, 
           (_,i) => new Date(year, month, i+1))
	.reduce((res,date,idx,self) => {
	   const itsMonday = date.getDay() == 1,
		 itsSunday = date.getDay() == 0,
		 monthStart = idx == 0,					
		 monthEnd = idx == self.length-1,
		 options = {dateStyle: 'short'};
	   if(itsMonday || monthStart) 
           res.push({
                 week:(res[res.length-1]||{week:0}).week+1,
                 start: date.toLocaleDateString('fr',options),
                 end: (monthStart ? date.toLocaleDateString('fr',options) : '')
           });
	   if(itsSunday || monthEnd) 
                 res[res.length-1].end = date.toLocaleDateString('fr',options);
	   return res;
	}, []);
    
console.log(getWeeksInMonth(3,2018));
.as-console-wrapper {min-height:100%}

答案 2 :(得分:-1)

我找到了解决方案。 此处的完整功能正常运行:

public getWeeksInMonth(): Observable<Week[]> {

    let year: number = 2018;
    let month: number = 3;

    const weeks: Week[] = [];

    const firstDay: Date = new Date(Date.UTC(year, month, 1));
    const lastDay: Date = new Date(Date.UTC(year, month + 1, 0));

    const daysInMonth: number = lastDay.getDate();
    let dayOfWeek: number = firstDay.getDay();

    let start: number;
    let end: number;

    for (let i = 1; i < daysInMonth + 1; i++) {

        if (dayOfWeek === 0 || i === 1) {
            start = i;
        }

        if (dayOfWeek === 0 && start === 1 && i !== daysInMonth) {
            end = 1;

            weeks.push({
                'start': start,
                'end': end
            });
        }
        if (dayOfWeek === 6 || i === daysInMonth) {
            end = i;
            if ((start !== end) || (start === 30 && end === 30) || (start === 31 && end === 31)) {

                weeks.push({
                    'start': start,
                    'end': end
                });
            }
        }
        dayOfWeek = new Date(year, month, i).getDay();
    }
    return of(weeks);
}