JasonDavis
JasonDavis

Reputation: 48933

Calculate last week start date in JavaScript (not -7 days ago)

I have a list of activity records which all have a date and show in an activity stream.

I am wanting to insert a separator DIV between the records based on which date group they fall under based on the recordsa creation date.

I want to show a DIV with text This week which would take the start date of the current week (not past 7 days) and then I can show all my records created since that date.

I also want to do one for Last week which would mean I need to get the Date value for the start date of last week and the end date of last week. Or Start date +7 would be fine.

I then have a JavaScript library to compare date ranges. I can pass in a start date and end date and find out if a 3rd date is within the date range which would let me know which of my records to show under each Date section.

So I am asking for help in calculating the :

A week start date is on a Sunday by most calendar or Monday

Also I prefer not to use the massive in size Moment.js library for these few date operations if I can help it.

Thanks for any help

This image below shows what I am trying to achieve with the date sections to break my records up...

enter image description here


Date library for DateTime comparisons and checking if a date is in-between range of 2 dates!

// Source: http://stackoverflow.com/questions/497790
var dates = {
  convert: function(d) {
    // Converts the date in d to a date-object. The input can be:
    //   a date object: returned without modification
    //  an array      : Interpreted as [year,month,day]. NOTE: month is 0-11.
    //   a number     : Interpreted as number of milliseconds
    //                  since 1 Jan 1970 (a timestamp)
    //   a string     : Any format supported by the javascript engine, like
    //                  "YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" etc.
    //  an object     : Interpreted as an object with year, month and date
    //                  attributes.  **NOTE** month is 0-11.
    return (
      d.constructor === Date ? d :
      d.constructor === Array ? new Date(d[0], d[1], d[2]) :
      d.constructor === Number ? new Date(d) :
      d.constructor === String ? new Date(d) :
      typeof d === "object" ? new Date(d.year, d.month, d.date) :
      NaN
    );
  },
  compare: function(a, b) {
    // Compare two dates (could be of any type supported by the convert
    // function above) and returns:
    //  -1 : if a < b
    //   0 : if a = b
    //   1 : if a > b
    // NaN : if a or b is an illegal date
    // NOTE: The code inside isFinite does an assignment (=).
    return (
      isFinite(a = this.convert(a).valueOf()) &&
      isFinite(b = this.convert(b).valueOf()) ?
      (a > b) - (a < b) :
      NaN
    );
  },
  inRange: function(d, start, end) {
    // Checks if date in d is between dates in start and end.
    // Returns a boolean or NaN:
    //    true  : if d is between start and end (inclusive)
    //    false : if d is before start or after end
    //    NaN   : if one or more of the dates is illegal.
    // NOTE: The code inside isFinite does an assignment (=).
    return (
      isFinite(d = this.convert(d).valueOf()) &&
      isFinite(start = this.convert(start).valueOf()) &&
      isFinite(end = this.convert(end).valueOf()) ?
      start <= d && d <= end :
      NaN
    );
  },

  // Subtract number of months from current month
  // dates.subtractMonth(1)
  subtractMonth: function(numberOfMonths) {
    //var d = this;
    var d = new Date();
    d.setMonth(d.getMonth() - numberOfMonths);
    d.setDate(1);
    return d;
  }

};

///////////////////////////////////////////////////////////////////////////

my sample JSON data with a date that will be compared with the other dates to determine when to inject a date section header into the loop

var task_activities = [{"id":1,"name":"record 1","date_time":"1\/5\/2015"},{"id":2,"name":"record 2","date_time":"1\/9\/2015"},{"id":3,"name":"record 3","date_time":"1\/13\/2015"},{"id":4,"name":"record 4","date_time":"1\/17\/2015"},{"id":5,"name":"record 5","date_time":"1\/21\/2015"},{"id":6,"name":"record 6","date_time":"1\/25\/2015"},{"id":7,"name":"record 7","date_time":"1\/29\/2015"},{"id":8,"name":"record 8","date_time":"2\/1\/2015"},{"id":9,"name":"record 9","date_time":"2\/5\/2015"},{"id":10,"name":"record 10","date_time":"2\/9\/2015"},{"id":11,"name":"record 11","date_time":"2\/13\/2015"},{"id":12,"name":"record 12","date_time":"2\/17\/2015"},{"id":13,"name":"record 13","date_time":"2\/21\/2015"},{"id":14,"name":"record 14","date_time":"2\/25\/2015"},{"id":15,"name":"record 15","date_time":"2\/29\/2015"},{"id":16,"name":"record 16","date_time":"3\/1\/2015"},{"id":17,"name":"record 17","date_time":"3\/5\/2015"},{"id":18,"name":"record 18","date_time":"3\/9\/2015"},{"id":19,"name":"record 19","date_time":"3\/13\/2015"},{"id":20,"name":"record 20","date_time":"3\/17\/2015"}];



// Loop over each Task Activity record and generate HTML
$.each(task_activities, function(i, activity) {
    console.log(activity.date_time);
}); // end each

Upvotes: 0

Views: 1248

Answers (1)

RobG
RobG

Reputation: 147363

Firstly, the subtractMonth function is flawed, for 31 March minus 1 month it returns 1 March.

If you want to find the first day of the week for a given date, just subtract the day number from the date for weeks starting on Sunday, or subtract one less day or 6 for Sunday for weeks starting on Monday:

/**
**  @param {Date} date - date to get start of week for
**  @param {Boolean} mondayStart - falsey for Sunday as first day of week,
**                                 truthy for Monday as first day of week
**  @returns {Date} - date for first day of week
*/
function getStartOfWeek(date, mondayStart) {

  // copy date
  var d = new Date(+date);
  // days to previous Sunday
  var shift = d.getDay();

  // Adjust shift if week starts on Monday
  if (mondayStart) {
    shift = shift? shift - 1 : 6;
  }

  // Shift to start of week
  d.setDate(d.getDate() - shift);
  return d;
}

If you want the subtractMonth function to work, say what you want it to do.

Edit

As a bonus feature, here's a subtract months function that works how I think it was intended to work:

/*
** @param {number} numberOfMonths - number of months to add to date
** @param {Date} date - date to subract months from
** @returns {Date} - the passed in date object with the specified number of months subtracted
*/
function subtractMonth (numberOfMonths, date) {

  // If date not supplied, default to today
  var d = date || new Date();

  // Get the date
  var day = d.getDate();

  // Subtract the months
  d.setMonth(d.getMonth() - numberOfMonths);

  // If date has changed, was too big for month and has rolled over
  // into next month, so set to last day of previous month
  if (day != d.getDate) d.setDate(0);
  return d;
}

Upvotes: 2

Related Questions