C270a3d9a0091977de642fec90b43ad3

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?

//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 !

D41d8cd98f00b204e9800998ecf8427e

Andre Steenveld

May 25, 2008, May 25, 2008 19:48, permalink

1 rating. Login to rate!

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( ); }
4d5cf9b8d40af8083b1797aa7c5f3de9

nosredna.myopenid.com

August 23, 2008, August 23, 2008 22:47, permalink

No rating. Login to rate!

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;
}
Fede7405a0e4cd5722e0b85920a0728c

Andrew Dupont

September 2, 2008, September 02, 2008 22:59, permalink

No rating. Login to rate!

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

Andrew Dupont

September 3, 2008, September 03, 2008 14:51, permalink

No rating. Login to rate!

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);  
};
4d5cf9b8d40af8083b1797aa7c5f3de9

nosredna.myopenid.com

September 3, 2008, September 03, 2008 15:46, permalink

No rating. Login to rate!

>>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.

Fede7405a0e4cd5722e0b85920a0728c

Andrew Dupont

September 4, 2008, September 04, 2008 15:47, permalink

No rating. Login to rate!

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

Your refactoring





Format Copy from initial code

or Cancel