12

I've got two functions which I can use to get the dates of the past 7 days and formats the into a particular format but it's pretty slow, does anybody know of a better way maybe using a loop or something similar?

 function formatDate(date){

    var dd = date.getDate();
    var mm = date.getMonth()+1;
    var yyyy = date.getFullYear();
    if(dd<10) {dd='0'+dd}
    if(mm<10) {mm='0'+mm}
    date = mm+'/'+dd+'/'+yyyy;
    return date
 }

 function Last7Days () {

      var today = new Date();
      var oneDayAgo = new Date(today);
      var twoDaysAgo = new Date(today);
      var threeDaysAgo = new Date(today);
      var fourDaysAgo = new Date(today);
      var fiveDaysAgo = new Date(today);
      var sixDaysAgo = new Date(today);

      oneDayAgo.setDate(today.getDate() - 1);
      twoDaysAgo.setDate(today.getDate() - 2);
      threeDaysAgo.setDate(today.getDate() - 3);
      fourDaysAgo.setDate(today.getDate() - 4);
      fiveDaysAgo.setDate(today.getDate() - 5);
      sixDaysAgo.setDate(today.getDate() - 6);

      var result0 = formatDate(today);
      var result1 = formatDate(oneDayAgo);
      var result2 = formatDate(twoDaysAgo);
      var result3 = formatDate(threeDaysAgo);
      var result4 = formatDate(fourDaysAgo);
      var result5 = formatDate(fiveDaysAgo);
      var result6 = formatDate(sixDaysAgo);

      var result = result0+","+result1+","+result2+","+result3+","+result4+","+result5+","+result6;

      return(result);
 }
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
user2236497
  • 343
  • 3
  • 5
  • 12

9 Answers9

33
function Last7Days () {
    var result = [];
    for (var i=0; i<7; i++) {
        var d = new Date();
        d.setDate(d.getDate() - i);
        result.push( formatDate(d) )
    }

    return(result.join(','));
}

FIDDLE

Or another solution for the whole thing

function Last7Days () {
    return '0123456'.split('').map(function(n) {
        var d = new Date();
        d.setDate(d.getDate() - n);

        return (function(day, month, year) {
            return [day<10 ? '0'+day : day, month<10 ? '0'+month : month, year].join('/');
        })(d.getDate(), d.getMonth(), d.getFullYear());
    }).join(',');
 }

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • @gerdhübner - That's just a hack to iterate with `map`, if you need more iterations than 9, find some way to create an array with more than 9 indices … obviously! (`new Array(12)` comes to mind) – adeneo Oct 06 '19 at 18:09
  • In the second solution, +1 must be added to `month` to yield correct results. – rubick Jun 11 '21 at 14:32
8

Or the ES6 way:

const dates = [...Array(7)].map((_, i) => {
    const d = new Date()
    d.setDate(d.getDate() - i)
    return d
})
francis
  • 3,852
  • 1
  • 28
  • 30
5

Use Moment.js

daysAgo = {}
for(var i=1; i<=7; i++) {
  daysAgo[i] = moment().subtract(i, 'days').format("DD MM YYYY")
}
return daysAgo
Ryan Bigg
  • 106,965
  • 23
  • 235
  • 261
3

I like as short and efficient code as possible, might not be the best but IMO best of both worlds:

Array(7) // Create empty array of specified length, here a week.
    .fill(new Date()) // Fill it with dates of your choice, here today.
    .map((today, i) => today - 8.64e7 * i) // Subtract days worth of time times the index
    .map(day => formatDate(day)) // format your dates however you like
1
var dates = Array.apply(null, new Array(7))
     .map(function() {
         return new Date();
     })
     .map(function(v, i) {
         v.setDate(v.getDate() - i);
         return v;
     })
     .map(function(v) {
         return formatDate(v);
     })
     .reverse()
     .join(',');

JSFiddle: http://jsfiddle.net/R5dnu/1/

zerkms
  • 249,484
  • 69
  • 436
  • 539
  • 1
    I think the OP wanted something **more** efficient? ;-) – RobG Apr 04 '14 at 01:40
  • @RobG: "efficiency" is a vague term. This code is much more efficient from readability and maintainability point of view. – zerkms Apr 04 '14 at 01:43
  • Yes, "efficient" should be qualified (amount of code? speed? maintainable?). Readability is in the eye of the beholder. :-) In terms of speed, the OP is probably as fast as any, but certainly verbose. You could replace `Array.apply(null, new Array(7))` with `[0,0,0,0,0,0,0]`, dunno if that helps though. – RobG Apr 04 '14 at 02:15
  • @RobG: yep, `[0,0,0,0,0,0,0]` could be used indeed. It doesn't state the `7` explicitly so you will have to count manually :-) – zerkms Apr 04 '14 at 02:43
  • That code does not look any more readable than **[an alternative version](http://jsfiddle.net/R5dnu/6/)** which does much the same thing inside a single mapped function. I can see no advantage to the multiple `map` calls. – Scott Sauyet Apr 04 '14 at 12:30
  • @Scott Sauyet: you cannot see and you don't see - and it's fine. I can accept some people are not familiar with FP paradigm. – zerkms Apr 04 '14 at 20:33
  • @zerkms: I find that amusing, as I've spent the last several years promoting FP in the JS community, and am the author of a **[JS FP library](https://github.com/CrossEye/ramda)**. If your code were written to take advantage of reusable functions, I could buy it: `var dates = makeEmptyArray(7).map(createDate).map(subtractDaysFromDate).map(formatDate).reverse().join(',');` But these lambdas you supply to `map` are to my eyes no more helpful than the the three-line one in my alternative. They just make it more complex. – Scott Sauyet Apr 05 '14 at 15:27
  • @Scott Sauyet: "But these lambdas you supply to map are to my eyes no more helpful than the the three-line one in my alternative" --- I don't see how it's less FP if I don't create named functions, but use anonymous instead. "They just make it more complex" --- it's subjective. From my perspective this code is perfectly readable and maintainable. – zerkms Apr 05 '14 at 20:19
  • @zerkms: I didn't say it was less FP. I said it was more complex. It's mostly a syntactic matter rather than a semantic one. You have the `map` keywords, three `function` keywords, three `return` keywords, and a bunch of extra punctuation, not to mention that you include a `reverse` you could have easily avoided. That's the kind of complexity I objected to. The ideas were sound; in fact I used them almost intact in my alternative. I just did so with less ceremony. – Scott Sauyet Apr 06 '14 at 01:44
0

Well, one more won't hurt. Note that dates in m/d/y format are pretty confusing to many.

// Get 7 days prior to provided date or today
function last7Days(d) {
  d = +(d || new Date()), days = [], i=7;
  while (i--) {
    days.push(formatUSDate(new Date(d-=8.64e7)));
  }
  return days;
}

// Return date string in mm/dd/y format
function formatUSDate(d) {
  function z(n){return (n<10?'0':'')+ +n;}
  return z(d.getMonth() + 1) + '/' + z(d.getDate()) + '/' + d.getFullYear();
}

console.log(last7Days().join('\n'));
RobG
  • 142,382
  • 31
  • 172
  • 209
  • I believe this could fail around those days the clocks remove an hour to begin Summer Time (US: Daylight Savings Time) or add an hour to end it, if your current time is in (respectively) the last hour or the first hour of the day. (Private note: The ghost of Dr. Stockton strikes again!) – Scott Sauyet Apr 04 '14 at 11:43
  • It adjusts the timevalue, which is UTC so unaffected by daylight saving. In any case, the daylight saving change is at 02:00 so an hour either way won't change the date. – RobG Apr 04 '14 at 12:26
  • Maybe I'm misunderstanding, but by subtracting 24 hours from a 23- or 25-hour day, it looks like you could have problems you wouldn't have if you used the `setDate()` method in the other answers. But I haven't actually tested this. – Scott Sauyet Apr 04 '14 at 12:33
  • Tested. If I pass in (from the US) `new Date(2014, 02, 12, 0, 30)`, then the output skips March 9. If I pass in `new Date(2014, 10, 4, 23, 30)`, then I get November 2 twice. – Scott Sauyet Apr 04 '14 at 12:43
  • I think you're right. I usually never use the time to adjust dates, so now it does the set date thing. :-/ While testing I think I found a bug in how Safari creates dates. – RobG Apr 04 '14 at 13:22
  • It's not so much the adjustment as the construction, although even adjusting by adding hours, minutes, second, or milliseconds would presumably have this same behavior. Adjusting by days, months, or years should work as expected, that is, they should take summer time rules into account. Or so I believe without extensive testing. But in constructing, you're constructing with a specific instant, calculated as so many milliseconds before another. Summer Time will not be considered. – Scott Sauyet Apr 04 '14 at 13:57
0

Based on @adeneo solution, i think we could send the number of days... Not the 7 days solution but this could be a better way:

function LastDays (n, option) {
  let arr = Array.apply(0, Array(n)).map(function(v,i){return i}),
    weekday = new Array(7);
      
  weekday[0] = "Sunday";
  weekday[1] = "Monday";
  weekday[2] = "Tuesday";
  weekday[3] = "Wednesday";
  weekday[4] = "Thursday";
  weekday[5] = "Friday";
  weekday[6] = "Saturday";
  
  return arr.map(function(n) {
    let date = new Date();
    date.setDate(date.getDate() - n);
    return (function(day, month, year, weekendDay) {
     switch(option) {
       case 'weekday': return weekday[weekendDay];
       default: return [day<10 ? '0'+day : day, month<10 ? '0'+month : month, year].join('/');
      }
    })(date.getDate(), date.getMonth(), date.getFullYear(), date.getDay());
  }).join(', ');
}

document.getElementById("testA").innerHTML = LastDays(3)
document.getElementById("testB").innerHTML = LastDays(5,'weekday')
<div id="testA"></div>

<hr/>

<div id="testB"></div>

FIDDLE

0
function last7Days() {
      let today = new Date();
      let lastSevenDays = [today.toLocaleDateString()];
      let dateOffset;
      for (let i = 1; i < 7; i++) {
        dateOffset = (24 * 60 * 60 * 1000) //Reset the value evry iteration
        dateOffset *= i;
        today = new Date(); //Reset the day value evry iteration
        today.setTime(today.getTime() - dateOffset);
        lastSevenDays.push(today.toLocaleDateString());
      }
      return lastSevenDays;
    }
    console.log(last7Days());
Zohar H
  • 1
  • 1
  • Code dumps do not make for good answers. You should explain *how* and *why* this solves their problem. I recommend reading, "[How do I write a good answer?"](//stackoverflow.com/help/how-to-answer). This can help future users learn and eventually apply that knowledge to their own code. You are also likely to have positive feedback/upvotes from users, when the code is explained. – John Conde Mar 01 '21 at 19:00
-2
var Today = moment(new Date()).format('DD-MM-YYYY');
var yesterdaydate = moment(new Date((new Date()).valueOf() - 1000 * 60 * 60 * 24)).format('DD-MM-YYYY');
var thirdDate = moment(new Date((new Date()).valueOf() - 1000 * 60 * 60 * 24 * 2)).format('DD-MM-YYYY');
var Fourthdate = moment(new Date((new Date()).valueOf() - 1000 * 60 * 60 * 24 * 3)).format('DD-MM-YYYY');
var fifthdate = moment(new Date((new Date()).valueOf() - 1000 * 60 * 60 * 24 * 4)).format('DD-MM-YYYY');
var Sixthdate = moment(new Date((new Date()).valueOf() - 1000 * 60 * 60 * 24 * 5)).format('DD-MM-YYYY');
var sevendate = moment(new Date((new Date()).valueOf() - 1000 * 60 * 60 * 24 * 6)).format('DD-MM-YYYY');
var eightdate = moment(new Date((new Date()).valueOf() - 1000 * 60 * 60 * 24 * 7)).format('DD-MM-YYYY');
let lastsevenDays = Today + yesterdaydate + thirdDate + Fourthdate + fifthdate + Sixthdate + sevendate + eightdate;
Eric Aya
  • 69,473
  • 35
  • 181
  • 253