//Given a date, returns a new date object that contains the start of the week
function startOfWeek(d){
var beg = new Date(d);
beg.setDate(beg.getDate() - beg.getDay());
beg.setHours(0);
beg.setMinutes(0);
beg.setSeconds(0);
return beg;
}
//Given a date, returns a new date object that contains the end of the week
function endOfWeek(d){
var end = startOfWeek(d);
end.setDate(beg.getDate() + 7);
return end;
}
//takes a Date d and returns a formatted string given the week
function loadDate(d){
var m_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
//finds the beginning date and end date of the week
var beg = startOfWeek(d);
var end = endOfWeek(d);
// str holds the date
var str = m_names[beg.getMonth()] + " " + beg.getDate()
//builds the string
if (beg.getYear() != end.getYear()) {
str += " " + beg.getFullYear() + " - ";
}
else {
str += " - ";
}
if (beg.getMonth() != end.getMonth()) {
str += m_names[end.getMonth()] + " ";
}
str += end.getDate() + ", " + end.getFullYear();
return str;
}
Refactorings
No refactoring yet !
Andre Steenveld
May 25, 2008, May 25, 2008 19:48, permalink
At the cost of creating 2 extra date objects for a very short period of time i refactord startOfWeek( ) and endOfWeek( ) out of the script.
Date.prototype.getFormatedWeek = function( ){
var months = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
return function( ){
var begin = new Date( new Date( this ).setDate( this.getDate( ) - this.getDate( ) ) );
var end = new Date( new Date( this ).setDate( this.getDate( ) + 7 ) ),
output = months[ begin.getMonth( ) ] + " " + begin.getDate( )
output += begin.getYear( ) !== end.getYear( )
? " " + begin.getFullYear( ) + " - "
: " - ";
output += begin.getMonth( ) !== end.getMonth( )
? months[ end.getMonth( ) ] + " "
: "";
return output + end.getDate( ) + ", " + end.getFullYear( );
};
}( );
// For backwards compatability
function loadDate( date ){ return date.getFormatedWeek( ); }
nosredna.myopenid.com
August 23, 2008, August 23, 2008 22:47, permalink
Here's a not-quite-serious attempt that I did just to satisfy an idea I had.
It relies on the fact that JavaScript already has the ability to convert a date into a string.
It doesn't satisfy your requirements because (among other problems) the months come out as three-letter abbreviations.
I'd also be concerned that it wouldn't work right, perhaps, in some foreign languages.
Still thought it was worth posting, though, because the JavaScript Date system is so strange and poorly understood, and the more solutions out there the better.
For example, why can you have a literal array, object, regex, but not Date? Seems like you could get rid of the "new" keyword if it weren't for Date.
function weekString(d){
var msInDay = 60 * 60 * 1000 * 24,
day = d.getDay(),
tim = d.getTime(),
d2 = new Date,
a,
b,
out;
d2.setTime(tim - day * msInDay);
a = (d2 + "").split(" ");
d2.setTime(tim + (6 - day) * msInDay);
b = (d2 + "").split(" ");
out = a[1] + " " + a[2];
if (a[3] != b[3]) {
out += ", " + a[3];
}
out += "-";
if (a[1] != b[1]) {
out += b[1] + " ";
}
out += b[2] + ", " + b[3];
return out;
}
Andrew Dupont
September 2, 2008, September 02, 2008 22:59, permalink
Moves everything into Date instance methods. Also creates Date#toDateString (for converting one date to the needed string) and Date#toWeekString (for taking the start and end dates of that week and joining them together in a string).
Date.MONTH_NAMES = ["January", "February", "March", "April", "May",
"June", "July", "August", "September", "October", "November", "December"];
Date.prototype.startOfWeek = function() {
var start = new Date(this);
start.setDate(start.getDate() - start.getDay());
start.setHours(0);
start.setMinutes(0);
start.setSeconds(0);
return start;
};
Date.prototype.endOfWeek = function() {
var end = this.startOfWeek();
end.setDate(end.getDate() + 7);
return end;
};
Date.prototype.toDateString = function(includeYear) {
var str = Date.MONTH_NAMES[this.getMonth()] + " " + this.getDate();
if (includeYear) str += (", " + this.getFullYear());
return str;
};
Date.prototype.toWeekString = function() {
var start = this.startOfWeek(), end = this.endOfWeek();
var includeYear = (start.getFullYear() != end.getFullYear());
return start.toDateString(includeYear) + "\u2013" + end.toDateString(includeYear);
};
Andrew Dupont
September 3, 2008, September 03, 2008 14:51, permalink
One more time; I'd failed to catch the fact that you echo the month only once if the two days are in the same month.
Date.MONTH_NAMES = ["January", "February", "March", "April", "May",
"June", "July", "August", "September", "October", "November", "December"];
Date.prototype.startOfWeek = function() {
var start = new Date(this);
start.setDate(start.getDate() - start.getDay());
start.setHours(0);
start.setMinutes(0);
start.setSeconds(0);
return start;
};
Date.prototype.endOfWeek = function() {
var end = this.startOfWeek();
end.setDate(end.getDate() + 7);
return end;
};
Date.prototype.toDateString = function(includeMonth, includeYear) {
var str = "";
if (includeMonth) str += Date.MONTH_NAMES[this.getMonth()] + " ";
str += this.getDate();
if (includeYear) str += (", " + this.getFullYear());
return str;
};
Date.prototype.toWeekString = function() {
var start = this.startOfWeek(), end = this.endOfWeek();
var includeMonth = (start.getMonth() != end.getMonth());
var includeYear = (start.getFullYear() != end.getFullYear());
return start.toDateString(true, includeYear) + "\u2013" +
end.toDateString(includeMonth, includeYear);
};
nosredna.myopenid.com
September 3, 2008, September 03, 2008 15:46, permalink
>>One more time; I'd failed to catch the fact that you echo the month only once if the two days are in the same month.
Yeah. The month can show up once or twice and the year can show up once or twice.
Andrew Dupont
September 4, 2008, September 04, 2008 15:47, permalink
Right, OK. Tweaked again so that it always shows the year on the second date.
Date.MONTH_NAMES = ["January", "February", "March", "April", "May",
"June", "July", "August", "September", "October", "November", "December"];
Date.prototype.startOfWeek = function() {
var start = new Date(this);
start.setDate(start.getDate() - start.getDay());
start.setHours(0);
start.setMinutes(0);
start.setSeconds(0);
return start;
};
Date.prototype.endOfWeek = function() {
var end = this.startOfWeek();
end.setDate(end.getDate() + 7);
return end;
};
Date.prototype.toDateString = function(includeMonth, includeYear) {
var str = "";
if (includeMonth) str += Date.MONTH_NAMES[this.getMonth()] + " ";
str += this.getDate();
if (includeYear) str += (", " + this.getFullYear());
return str;
};
Date.prototype.toWeekString = function() {
var start = this.startOfWeek(), end = this.endOfWeek();
var includeMonth = (start.getMonth() != end.getMonth());
var includeYear = (start.getFullYear() != end.getFullYear());
return start.toDateString(true, includeYear) + "\u2013" +
end.toDateString(includeMonth, true);
};
The code takes a date object, and returns a string giving the week of the date. For instance, given May 20, 2008, it would return May 18 - May 24, 2008. Can it be written more concisely?