Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
JavaScript - get weeks in a month as array of start and end days
//note: month is 0 based, just like Dates in js
function getWeeksInMonth(month, year){
var weeks=[],
firstDate=new Date(year, month, 1),
lastDate=new Date(year, month+1, 0),
numDays= lastDate.getDate();
var start=1;
var end=7-firstDate.getDay();
while(start<=numDays){
weeks.push({start:start,end:end});
start = end + 1;
end = end + 7;
if(end>numDays)
end=numDays;
}
return weeks;
}
@ecorvo

This comment has been minimized.

Copy link

ecorvo commented Nov 21, 2016

Thanks!

@TheGitPanda

This comment has been minimized.

Copy link

TheGitPanda commented Jun 7, 2017

Thanks for this works perfect, except I had to add this line after end = end + 7:

end = start === 1 && end === 8 ? 1 : end;

Without it, months where they start on the last day of the week were returning {start:1, end: 8} for first week : )

@itzikbenh

This comment has been minimized.

Copy link

itzikbenh commented Oct 9, 2017

If you want to support starting with Monday, I believe this should work.

function getWeeksStartAndEndInMonth(month, year, start) {
    let weeks = [],
        firstDate = new Date(year, month, 1),
        lastDate = new Date(year, month + 1, 0),
        numDays = lastDate.getDate();

    let start = 1;
    let end = 7 - firstDate.getDay();
    if (start === 'monday') {
        if (firstDate.getDay() === 0) {
            end = 1;
        } else {
            end = 7 - firstDate.getDay() + 1;
        }
    }
    while (start <= numDays) {
        weeks.push({start: start, end: end});
        start = end + 1;
        end = end + 7;
        end = start === 1 && end === 8 ? 1 : end;
        if (end > numDays) {
            end = numDays;
        }
    }
    return weeks;
}
@itzikbenh

This comment has been minimized.

Copy link

itzikbenh commented Oct 9, 2017

This one will allow you to start from any day of the week.

function endFirstWeek(firstDate, firstDay) {
    if (! firstDay) {
        return 7 - firstDate.getDay();
    }
    if (firstDate.getDay() < firstDay) {
        return firstDay - firstDate.getDay();
    } else {
        return 7 - firstDate.getDay() + firstDay;
    }
}

function getWeeksStartAndEndInMonth(month, year, start) {
    let weeks = [],
        firstDate = new Date(year, month, 1),
        lastDate = new Date(year, month + 1, 0),
        numDays = lastDate.getDate();

    let start = 1;
    let end = endFirstWeek(firstDate, 2);
    while (start <= numDays) {
        weeks.push({start: start, end: end});
        start = end + 1;
        end = end + 7;
        end = start === 1 && end === 8 ? 1 : end;
        if (end > numDays) {
            end = numDays;
        }
    }
    return weeks;
}
@Chriskuang

This comment has been minimized.

Copy link

Chriskuang commented Jan 17, 2018

thks

@leorcvargas

This comment has been minimized.

Copy link

leorcvargas commented Feb 5, 2018

Thank you! This are really useful for me. <3

@ghidhawidhekra

This comment has been minimized.

Copy link

ghidhawidhekra commented Feb 13, 2018

Thank you for the Share! Could you please add week number too? @itzikbenh

@ghost

This comment has been minimized.

Copy link

ghost commented Apr 15, 2018

@itzikbenh solution worked out best.

@BorisTB

This comment has been minimized.

Copy link

BorisTB commented Jun 18, 2018

@itzikbenh why is there "start" in arguments and then you define it again with "let start = 1" ? Not sure how you made that work

@NerdGr8

This comment has been minimized.

Copy link

NerdGr8 commented Jul 11, 2018

function getWeeksStartAndEndInMonth(month, year, _start) {
    let monthNames = ["January", "February", "March", "April", "May", "June",
        "July", "August", "September", "October", "November", "December"
        ],
        d = new Date();
    console.log("The current month is " + monthNames[d.getMonth()]);
    let weeks = [],
        firstDate = new Date(year, month, 1),
        lastDate = new Date(year, month + 1, 0),
        numDays = lastDate.getDate();
    var c = Date()
    let start = 1;
    let end = 7 - firstDate.getDay();
    if (_start == 'monday') {
        if (firstDate.getDay() === 0) {
            end = 1;
        } else {
            end = 7 - firstDate.getDay() + 1;
        }
    }
    while (start <= numDays) {
        var businessWeekEnd = end-2
        if(businessWeekEnd > 0){
            if(businessWeekEnd > start){
                weeks.push({start: start, end: businessWeekEnd});
            }
            else{
                //Check for last day else end date is within 5 days of the week.
                weeks.push({start: start, end: end});
            }
        }
        start = end + 1;
        end = end + 7;
        end = start === 1 && end === 8 ? 1 : end;
        if (end > numDays) {
            end = numDays;
        }
    }

    weeks.forEach(week => {
        var _s = parseInt(week.start, 10)+1,
            _e = parseInt(week.end,10)+1;
        console.log(new Date(year, month, _s).toJSON().slice(0,10).split('-').reverse().join('/') + " - " + new Date(year, month, _e).toJSON().slice(0,10).split('-').reverse().join('/'));
        console.log(((_e-_s)+1)*8)
    });
    return weeks;
}
console.table(getWeeksStartAndEndInMonth(6, 2018, 'monday'));
@anantl05

This comment has been minimized.

Copy link

anantl05 commented Oct 25, 2018

Thanks a ton!

@kingqi

This comment has been minimized.

Copy link

kingqi commented Dec 3, 2018

Thanks a lot, here is some code to get full weeks ( like first week will be like '26-2'), also allow you to start from any day of the week.
Any suggestion will be appreciated

// _start is 0 based
getFullWeeksStartAndEndInMonth = (month, year, _start) => {
    let weeks = [],
      firstDate = new Date(year, month, 1),
      lastDate = new Date(year, month + 1, 0),
      numDays = lastDate.getDate()

    let start = 1
    let end = 7 - firstDate.getDay()
    if (firstDate.getDay() === _start) {
      end = 7
    } else {
      preMonthEndDay = new Date(year, month, 0)
      start = preMonthEndDay.getDate() + 1 - firstDate.getDay() + _start
      end = 7 - firstDate.getDay() + _start
      weeks.push({ start: start, end: end })
      start = end + 1
      end = end + 7
    }
    while (start <= numDays) {
      weeks.push({ start: start, end: end })
      start = end + 1
      end = end + 7
      if (end > numDays) {
        end = end - numDays + _start
        weeks.push({ start: start, end: end })
        break
      }
    }
    return weeks
  }
@abcx

This comment has been minimized.

Copy link

abcx commented Mar 15, 2019

This TypeScript function returns date ranges for all weeks in given month:

    getWeeksInMonth(year: number, month: number) {

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

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

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

        return weeks;
    }

Usage:

getWeeksInMonth(2019, 2);

Result for March 2019:

0: {start: 1, end: 3}
1: {start: 4, end: 10}
2: {start: 11, end: 17}
3: {start: 18, end: 24}
4: {start: 25, end: 31}
@junreyd

This comment has been minimized.

Copy link

junreyd commented Jun 20, 2019

Very helpful.

@baj9032

This comment has been minimized.

Copy link

baj9032 commented Aug 17, 2019

Thank you very useful.

@infomed92

This comment has been minimized.

Copy link

infomed92 commented Oct 25, 2019

Hi abcx,
your function is not bad BUT it is not working correctly when we put year=2018 and month=Avril or July.
For example, result for Avril 2018 :
0: {start: 2, end: 8}
1: {start: 9, end: 15}
2: {start: 16, end: 22}
3: {start: 23, end: 29}

@infomed92

This comment has been minimized.

Copy link

infomed92 commented Oct 25, 2019

We should have for Avril 2018 :
0: {start: 1, end: 1}
1: {start: 2, end: 8}
2: {start: 9, end: 15}
3: {start: 16, end: 22}
4: {start: 23, end: 29}
5: {start: 30, end: 30}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.