Find all the days in a month with Date object?
To get a list of all days in a month, you can start with a Date
on the first day of a month, increase the day until the month changes.
/**
* @param {int} The month number, 0 based
* @param {int} The year, not zero based, required to account for leap years
* @return {Date[]} List with date objects for each day of the month
*/
function getDaysInMonth(month, year) {
var date = new Date(year, month, 1);
var days = [];
while (date.getMonth() === month) {
days.push(new Date(date));
date.setDate(date.getDate() + 1);
}
return days;
}
UTC Version
In response to some comments, I've created a version that uses UTC methods in case you want to call UTC methods instead of the standard methods that return the localized time zone.
I suspect this is the culprit of the comments saying this didn't work. You typically want to make sure you call getUTCMonth/Day/Hours
methods if you instantiated it with Date.UTC
, and vice-versa, unless you are trying to convert time zones and show differences.
function getDaysInMonthUTC(month, year) {
var date = new Date(Date.UTC(year, month, 1));
var days = [];
while (date.getUTCMonth() === month) {
days.push(new Date(date));
date.setUTCDate(date.getUTCDate() + 1);
}
return days;
}
Editing This Answer
If you think there's a problem with this script, please feel free to:
- First see existing unit tests below
- Write a test case that proves it's broken.
- Fix the code, making sure existing tests pass.
Unit Tests
/**
* @param {int} The month number, 0 based
* @param {int} The year, not zero based, required to account for leap years
* @return {Date[]} List with date objects for each day of the month
*/
function getDaysInMonthUTC(month, year) {
var date = new Date(Date.UTC(year, month, 1));
var days = [];
while (date.getUTCMonth() === month) {
days.push(new Date(date));
date.setUTCDate(date.getUTCDate() + 1);
}
return days;
}
function getDaysInMonth(month, year) {
var date = new Date(year, month, 1);
var days = [];
while (date.getMonth() === month) {
days.push(new Date(date));
date.setDate(date.getDate() + 1);
}
return days;
}
const days2020 = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const days2021 = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
describe("getDaysInMonthUTC", function() {
it("gets day counts for leap years", function() {
const actual = days2020.map(
(day, index) => getDaysInMonthUTC(index, 2020).length
);
expect(actual).toEqual(days2020);
});
it("gets day counts for non-leap years", function() {
const actual = days2021.map(
(day, index) => getDaysInMonthUTC(index, 2021).length
);
expect(actual).toEqual(days2021);
});
});
describe("getDaysInMonth", function() {
it("gets day counts for leap years", function() {
const actual = days2020.map(
(day, index) => getDaysInMonth(index, 2020).length
);
expect(actual).toEqual(days2020);
});
it("gets day counts for non-leap years", function() {
const actual = days2021.map(
(day, index) => getDaysInMonth(index, 2021).length
);
expect(actual).toEqual(days2021);
});
});
// load jasmine htmlReporter
(function() {
var env = jasmine.getEnv();
env.addReporter(new jasmine.HtmlReporter());
env.execute();
}());
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>
<link href="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css" rel="stylesheet"/>
One liner to get all days as Date object in a month
const getDaysInMonth = (month, year) => (new Array(31)).fill('').map((v,i)=>new Date(year,month-1,i+1)).filter(v=>v.getMonth()===month-1)
I'm not sure from your description if the standard disable dates datepicker will work with you, so I'll answer you question directly.
You can construct an array of days for a month fairly easily by doing this:
var numOfDays = new Date(2012, 10, 0).getDate(); //use 0 here and the actual month
var days = new Array();
//This will construct an array with all the elements represent the day of the week
//(i.e. Oct 30th would be days[30-1] or days[29]) and the value would be the actual
//day of the week (i.e. Tuesday which is representing by the number 2)
for(var i=0;i<=numOfDays;i++)
{
days[i] = new Date(2012,9,i+1).getDay(); //use month-1 here
}
//This will give you a number from 0 - 6 which represents (Sunday - Saturday)
alert(days[29]);
Using that array of days you can pretty much do whatever you want with it and know the day of the week as well.
Using ES6 Array Initializer
You can get the number of days in a specified month, and then create a new array with that length and each of the days as items.
const getAllDaysInMonth = (month, year) =>
Array.from(
{ length: new Date(year, month, 0).getDate() },
(_, i) => new Date(year, month - 1, i + 1)
);
Demo in Stack Snippets
const getAllDaysInMonth = (month, year) =>
Array.from(
{length: new Date(year, month, 0).getDate()}, // get next month, zeroth's (previous) day
(_, i) => new Date(year, month - 1, i + 1) // get current month (0 based index)
);
const allDatesInOctober = getAllDaysInMonth(10, 2021)
console.log(allDatesInOctober.map(x => x.toLocaleDateString([], { month: "short", day: "numeric" })))
// ['Oct 1', 'Oct 2', 'Oct 3', 'Oct 4', 'Oct 5', 'Oct 6', 'Oct 7', 'Oct 8', 'Oct 9', 'Oct 10', 'Oct 11', 'Oct 12', 'Oct 13', 'Oct 14', 'Oct 15', 'Oct 16', 'Oct 17', 'Oct 18', 'Oct 19', 'Oct 20', 'Oct 21', 'Oct 22', 'Oct 23', 'Oct 24', 'Oct 25', 'Oct 26', 'Oct 27', 'Oct 28', 'Oct 29', 'Oct 30', 'Oct 31']
Here's a loopp that runs through each month to determine the last day of that month. Javascript Date object indexes months starting at zero and if you set the day to zero it reverts back to last day of prior month. Handy for determining leap year last day for February
Date( 2012, 12, 0)
will return Dec 31, 2012
Date (2012,0,0)
will return Dec 31,2011
and the all important one to figure out is February with
Date ( 2012,3,0)
Returns Feb 29 since leap year this year
var mos=['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec']
for (i = 0; i < 12; i++) {
var lastDate = new Date(2012, i+1, 0);
$('body').append('Last day of ' + mos[i] + ' is ' + lastDate.getDate()+'<br>')
}
DEMO: http://jsfiddle.net/5k8sn/1/