patternjavascriptMinor
Clean Calendar Object
Viewed 0 times
calendarobjectclean
Problem
I am writing a small chunk of code (a module>?) that I will use to create a view on a page using angular. The angular directive will take care of generating the html.
The sole purpose of this module is expose a given month's data, specifically on what day it starts for the given year and how many days it has. I want to make this module as clean as possible and would appreciate anyfeedback.
The sole purpose of this module is expose a given month's data, specifically on what day it starts for the given year and how many days it has. I want to make this module as clean as possible and would appreciate anyfeedback.
function Calendar(month, year) {
var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
var months = [
'January', 'February', 'March', 'April',
'May', 'June', 'July', 'August', 'September',
'October', 'November', 'December'
];
var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
this.getMonthData = function() {
var startingDay = new Date(this.year, this.month, 1).getDay();
var monthLength = daysInMonth[this.month];
if (this.month === 1) {
if ((this.year % 4 === 0 && this.year % 100 !== 0) || this.year % 400 === 0) {
monthLength = 29;
}
}
};
}Solution
For one, I see your code is a bit over-engineered. So let's go back to the problem: Given a year and month, determine what day that month starts in a year and how many days it has.
To start, I would need 2 functions to keep the code understandable. Trying to jam a lot of functionality into one function would only cause problems in trying to understand things.
You could go for a constructor to house the month and year value, and the functions be methods on the prototype. Also, your lookup arrays need to come with the constructor, not just some free-floating variable. You can attach them to the constructor, since functions are also objects.
So it comes to getting how long a month is. There's a trick for that. You can construct a
In the end:
To start, I would need 2 functions to keep the code understandable. Trying to jam a lot of functionality into one function would only cause problems in trying to understand things.
function getFirstDayOfMonthAtYear(month, year){...}
function getLengthOfMonthAtYear(month, year){...}You could go for a constructor to house the month and year value, and the functions be methods on the prototype. Also, your lookup arrays need to come with the constructor, not just some free-floating variable. You can attach them to the constructor, since functions are also objects.
function Calendar(year, month){
// Default to January 1970
this.month = month || 0;
this.year = year || 1970;
// Generate the Date object so we don't need to create on every call.
// Also note that months are zero-indexed. So if we provide the
// real month number, we need to subtract 1.
this.date = new Date(year, month - 1, 1);
}
Calendar.prototype.getFirstDay = function(){
return Calendar.DAY_NAMES[this.date.getDay()];
};
Calendar.prototype.getMonthLength = function(){
// I'll show you a trick next
};
// We use pseudo-static variables. Essentially we're just attaching
// to the constructor. That way, our lookup comes with the constructor.
Calendar.DAY_NAMES = ['Sun', 'Mon', ..., 'Sat'];So it comes to getting how long a month is. There's a trick for that. You can construct a
Date object with the current year but on the next month with date 0. JavaScript dates that underflows/overflows the months date range automatically increments/decrements the month. Then it's all a matter of doing getDate.// So the date is March 0, 2004... essentially Feb 29, 2004
var daysOnFeb2004 = (new Date(2004, 2, 0)).getDate(); // 29In the end:
function Calendar(year, month) {
this.month = month || 0;
this.year = year || 1970;
this.date = new Date(year, month - 1, 1);
}
Calendar.prototype.getFirstDay = function() {
return Calendar.DAY_NAMES[this.date.getDay()];
};
Calendar.prototype.getMonthLength = function() {
return (new Date(this.year, this.month, 0)).getDate();
};
Calendar.DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
// Usage
var date = new Calendar(2004, 2);
document.write('First day: ' + date.getFirstDay() + ' Length:' + date.getMonthLength());Code Snippets
function getFirstDayOfMonthAtYear(month, year){...}
function getLengthOfMonthAtYear(month, year){...}function Calendar(year, month){
// Default to January 1970
this.month = month || 0;
this.year = year || 1970;
// Generate the Date object so we don't need to create on every call.
// Also note that months are zero-indexed. So if we provide the
// real month number, we need to subtract 1.
this.date = new Date(year, month - 1, 1);
}
Calendar.prototype.getFirstDay = function(){
return Calendar.DAY_NAMES[this.date.getDay()];
};
Calendar.prototype.getMonthLength = function(){
// I'll show you a trick next
};
// We use pseudo-static variables. Essentially we're just attaching
// to the constructor. That way, our lookup comes with the constructor.
Calendar.DAY_NAMES = ['Sun', 'Mon', ..., 'Sat'];// So the date is March 0, 2004... essentially Feb 29, 2004
var daysOnFeb2004 = (new Date(2004, 2, 0)).getDate(); // 29Context
StackExchange Code Review Q#109115, answer score: 3
Revisions (0)
No revisions yet.