News for hackers. Stuff that matters.
Re:Pickadate.js by Stratoscope on Wednesday November 21, 2012 @02:27AM (#4813255)
A few random comments...

This value is not what it says:

    SECONDS_IN_DAY = 86400000,
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:

    HOURS_IN_DAY = 24,
    MINUTES_IN_DAY = HOURS_IN_DAY * 60,
    SECONDS_IN_DAY = MINUTES_IN_DAY * 60,
    MILLISECONDS_IN_DAY = SECONDS_IN_DAY * 1000,
Personally, I find these kinds of string constants get in the way:

    STRING_DIV = 'div',
    STRING_TR = 'tr',
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:

    /**
     * Get the count of the number of
     * days in a month, given the
     * month and year
     */
    getCountDays = function( year, month ) {
    
        var
            // Set flip based on if month is
            // before or after July
            flip = ( month > 6 ) ? true : false
    
        // If it's February
        if ( month === 1 ) {
    
            // If it's not a leap year
            // then 28 otherwise 29
            return ( year % 4 ) ? 28 : 29
        }
    
        // If it's an odd month ID
        if ( month % 2 ) {

            // If it's after July then 31
            // otherwise 30
            return ( flip ) ? 31 : 30
        }
    
        // If it's an even month ID
        // and it's after July then 30
        // otherwise 31
        return ( flip ) ? 30 : 31
    }, //getCountDays
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?

    getCountDays = function( year, month ) {
        var msInMonth = new Date(year,month+1) - new Date(year,month);
        return Math.floor( msInMonth / MILLISECONDS_IN_DAY );
    },
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.

Re:Pickadate.js by Stratoscope on Wednesday November 21, 2012 @12:44PM (#4815289)
Just a followup on my "amazing and scary" comment. The "amazing" part is a genuine compliment: you found a pattern in the number of days in each month that I never noticed (the 'flip' trick). Being able to see these kinds of patterns and take advantage of them is an invaluable skill in programming.

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.

Re:Pickadate.js by abp on Wednesday November 21, 2012 @05:32AM (#4813650)
Looks like you were trying to send pull requests?
Re:Pickadate.js by Stratoscope on Wednesday November 21, 2012 @03:12PM (#4816093)
Ha! I was thinking about my version of getCountDays() and realized there was probably a bug in it. Did anyone else see it?

  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 );
    },