The problem here, of course, is that it makes the code a lot harder to understand. To understand and verify the function, I'd start by writing out a table of the days in each month while reciting the "30 days hath September" rhyme. :-) Then I'd have to go through all the the flip and non-flip cases in the code and compare against my table.
Let's imagine that JavaScript didn't have convenient date calculations so we couldn't use the updated function I posted above. If that were the case, what would be a simpler way to code the function? Just use the table of months directly. After all, there are only 12 months to deal with, so it's very simple:
getCountDays: function( year, month ) {
var monthDays = [
31, 0, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31
];
return monthDays[month] || getFebDays( year );
},
where getFebDays() handles all the special cases for leap years ( /4, /100, /400, etc.)Now, with the exception of February, it's trivial to see at a glance if the function is correct.
getCountDays( 2012, 2 ) // Daylight time began March 11
30 // oops
new Date(year,month,...) uses local time, so the day will be an hour longer or shorter when the time changes.A quick and dirty fix would be to use Math.round instead of Math.floor:
getCountDays = function( year, month ) {
var msInMonth = new Date(year,month+1) - new Date(year,month);
return Math.round( msInMonth / MILLISECONDS_IN_DAY );
},
And maybe better to use UTC? (I'd stick with Math.round at the same time.) getCountDays = function( year, month ) {
var msInMonth = Date.UTC(year,month+1) - Date.UTC(year,month);
return Math.round( msInMonth / MILLISECONDS_IN_DAY );
},
This value is not what it says:
That's the number of milliseconds in a day. Instead of a magic precalculated number, why not create all the relevant constants so the values become perfectly clear: Personally, I find these kinds of string constants get in the way: The string 'div' is never going to change to something else, is it? It would be better to just use the string directly where you need it.This is an amazing and scary piece of code:
It also calculates leap years incorrectly - try getCountDays(1900,1). February 1900 had 28 days, not 29.Why not let JavaScript do the work for you?
This will handle all leap years correctly.You can probably do something similar in your createDate function to avoid the manual tests.
Also the name getCountDays is not very informative. Maybe getDaysInMonth?
The settings options use names_with_underscores, but that's not very idiomatic in JavaScript (except for capitalized constants). camelCaseNames would be more comfortable.