0

I wrote a calendar in javascript and jquery (adapted from "Simple Calendar with Javascript") that allows me to move back and forward months at a time.

It accounts for leap years by adding in an extra day every 4 years in February, but it seems that an error is being caused because of this.

When you move back in time, or forward, it changes the date and runs the calendar() function according to the new date. Normally, it has 5 rows with 7 columns, each column containing a day. If there isn't enough room with the 5 rows, such as there being 31 days with the 1st being on a Saturday, then it will add an extra 6th row to accommodate.

During a leap year, however, the function doesn't seem to add the extra rows in if the same scenario above happens.

Here's a jsFiddle: http://jsfiddle.net/charlescarver/DrMWM/

This gist of calendar():

function calendar(d){

                $("#calendar").remove();
                $("body").append("<table border='1' id='calendar'></table>");

                // Date vars
                var today = new Date(d);
                var month = today.getMonth();
                var day = today.getDay();
                var dayN = today.getDate();
                var week = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
                var monthdays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
                var days = monthdays[month];
                var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

                // Determine if leap year, if not, set to current year
                if (month > 0) {
                    year = today.getYear();
                    if (year % 4 == 0){
                        days = 29;
                    }
                } else {
                    year = today.getYear();
                }

                // Parse vars
                var jumped = 0;
                var inserted = 1;
                var start = day - dayN%7 + 1;
                if (start < 0) start += 7;
                var weeks = parseInt((start + days)/7);
                if ((start + days)%7 != 0){
                    weeks++;
                }

                $("#calendar").append("<tr><td class='month' colspan='7'>" + monthNames[month] + " - " + today.getFullYear() + "</td></tr>");

                $("#calendar").append("<tr class='day'></tr>");
                for (var i=0; i<7; i++) {
                    $(".day").append("<td>" + week[i][0] + "</td>");
                }

                function datDate(m, n, y){
                    date = new Date(" " + monthNames[m] + " " + n + " " + y);
                    return date;
                }

                for (var i=weeks; i>0; i--) {
                    if (i === i){
                        $("#calendar").append("<tr class=" + i + "></tr>");
                        for (var j=0; j<7; j++) {
                            console.log(inserted);
                            if (jumped<start || inserted>days) {
                                $("." + i).append("<td> </td>");
                                jumped++;
                            }
                            else {
                                m = month;
                                n = inserted;
                                y = today.getFullYear();
                                date = datDate(m, n, y);
                                if (inserted == dayN) {
                                    $("." + i).append("<td><a class='calendar_date current_date' data-date='" + date + "'>[" + n + "]</a></td>");
                                } else {
                                    $("." + i).append("<td><a class='calendar_date' data-date='" + date + "'>" + n + "</a></td>");
                                }
                                inserted++;
                            }
                        }
                    }
                }   
            }
Charlie
  • 11,380
  • 19
  • 83
  • 138
  • Why not just iterate through the days in the month you're trying to render, and let the built in Date library do all the heavy lifting? – Dolph Jan 16 '13 at 22:34
  • Do you have an example of this? This sounds like a much cleaner way... – Charlie Jan 16 '13 at 22:35
  • @Charlie you can simply increment the day-of-month; the library "fixes" the date if you try to set it to January 32 in other words, and the date comes out February 1. – Pointy Jan 16 '13 at 22:46
  • http://stackoverflow.com/a/10040679/176741 for some date range and then render them back to text however you'd like with http://www.w3schools.com/jsref/jsref_obj_date.asp – Dolph Jan 16 '13 at 22:46
  • 1
    @Dolph [Be wary of w3schools.](http://w3fools.com) The [MDN documentation site](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date) is generally more reliable, and if you do find a problem there you can fix it yourself :-) – Pointy Jan 16 '13 at 22:59

1 Answers1

2
            // Determine if leap year, if not, set to current year
            if (month == 1) {
                year = today.getYear();
                if (year % 4 == 0){
                    days = 29;
                }
            } else {
                year = today.getYear();
            }
user1920281
  • 114
  • 3
  • 3
    This is not accurate - a leap year has more rules than just dividing by 4 and checking the remainder: http://www.wikihow.com/Calculate-Leap-Years – James Wilkins Nov 17 '13 at 06:32