Most efficient way to get the dates for the past 7 days?
Asked Answered
S

9

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);
 }
Shawndashawnee answered 3/4, 2014 at 23:34 Comment(2)
Loops, they ARE useful. Arrays, they ARE useful too.Temporary
Inefficient in terms of code-size or runtime?Barbet
M
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

Microbicide answered 3/4, 2014 at 23:41 Comment(2)
@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)Microbicide
In the second solution, +1 must be added to month to yield correct results.Uella
M
10

Or the ES6 way:

const dates = [...Array(7)].map((_, i) => {
    const d = new Date()
    d.setDate(d.getDate() - i)
    return d
})
Motorway answered 4/6, 2020 at 15:6 Comment(0)
C
5

Use Moment.js

daysAgo = {}
for(var i=1; i<=7; i++) {
  daysAgo[i] = moment().subtract(i, 'days').format("DD MM YYYY")
}
return daysAgo
Cohen answered 3/4, 2014 at 23:39 Comment(2)
why so much hate towards <8Herminahermine
Probably should return an Array, not an Object.Lhary
T
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
Tellurize answered 13/11, 2018 at 12:40 Comment(0)
H
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/

Heterogamete answered 3/4, 2014 at 23:43 Comment(9)
I think the OP wanted something more efficient? ;-)Lhary
@RobG: "efficiency" is a vague term. This code is much more efficient from readability and maintainability point of view.Heterogamete
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.Lhary
@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 :-)Heterogamete
That code does not look any more readable than an alternative version which does much the same thing inside a single mapped function. I can see no advantage to the multiple map calls.Progesterone
@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.Heterogamete
@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. 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.Progesterone
@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.Heterogamete
@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.Progesterone
L
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'));
Lhary answered 4/4, 2014 at 1:39 Comment(6)
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!)Progesterone
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.Lhary
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.Progesterone
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.Progesterone
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.Lhary
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.Progesterone
C
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

Cavern answered 13/2, 2019 at 20:23 Comment(0)
P
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());
Poverty answered 1/3, 2021 at 18:31 Comment(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?". 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.Jacquard
D
-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;
Dozy answered 28/3, 2023 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.