0

My JS newbie question actually involves a few components (elaborated below), but I'd be happy with help just on the basics: How to calculate the difference between dates for selection of object values in in an array?

I realize there are a lot of examples on the internet for both creating iterative loops and examining the difference between dates. But most of these example calculating duration use one variable, and the examples on loops tend to include statements like // Do something rather than providing examples for including functions. I haven't (yet) found a question that addresses this particular (simple) problem.

The closest that I have come so far is this, which seeks to calculate the difference between one of the object values and today:

durationArray = {
var myArray = report_data;
var arrayLength = report_data.length;
for (var i = 0; i < arrayLength; i++) {
  var copy = new Date(report_data[i]["Start Date"]);
  var duration_adjusted = (today - copy)/24/60/60/1000;
  return duration_adjusted;
}
  return myArray
}

With report_data being supplied as:

report_data =  [{
    "Author Name": "Joe",
    "Unit Name": "IT",
    "Report Name": "Tech Paper 1",
    "Start Date": "2/3/2014",
    "End Date": "21-Mar-17"
  },
  {
    "Author Name": "Carole",
    "Unit Name": "IT",
    "Report Name": "Tech Paper 2",
    "Start Date": "4/8/2015",
    "End Date": "5-May-16"
  },
  {
    "Author Name": "Bob",
    "Unit Name": "IT",
    "Report Name": "Tech Paper 3",
    "Start Date": "6/16/2015",
    "End Date": "30-May-17"
  },
  {
    "Author Name": "Sue",
    "Unit Name": "IT",
    "Report Name": "Tech Paper 4",
    "Start Date": "7/16/2015",
    "End Date": "pending"
  }]

But this code is wrong, as it only returns one value (not values for all array objects). Also, I'd like to compare two object in the array ["Start Date"] and ["End Date] rather than only calculating the difference between today and the start date (but I haven't gotten this far in my attempts b/c I can't iterate correctly).

In case it helps to facilitate an answer, here's an Obeservable notebook with my errant code.

If you're feeling extra generous or would like more of a challenge (I realize this is an extremely basic question), then here's where the second part of the question comes in:

In the last item of my dummy data, instead of a date there's the value "pending" (indicating that the report isn't finished). In addition to calculating the difference between array objects ["Start Date"] and ["End Date], I'd like to add an "else" statement that for "pending" values that calculates the difference between today and ["Start Date"].

I hope this is clear and that I don't get slammed too hard for raising this very 'newbie' question. I am learning JS from home via tutorials, and have been struggling for a couple of days to combine them appropriately, so I turn to you for help.

Thanks in advance for your time and guidance!

aaron.kyle
  • 163
  • 3
  • 10
  • 1
    I think you should use `getTime` method (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime) In short: `let diff = new Date().getTime() - new Date(report_data[i]["Start Date"]).getTime()` – ymz Feb 03 '19 at 14:54
  • Thanks @ymz - this is a helpful lead, but i still don't get how to include this sort of function in a loop – aaron.kyle Feb 03 '19 at 14:56
  • Please read [*Why does Date.parse give incorrect results?*](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results). – RobG Feb 03 '19 at 22:30
  • Thanks @RobG. I've read about JS times being based in UTC, which can give weird conversion results (like showing a date from an input as occurring a few hours prior to an input date when interpreted by a user's system time). For this question, it's not too big of a deal... I mostly am after a way of taking approximate differences between values within an array for the all array elements. The example uses dates, but these could equally just be numbers. My struggle is trying to get logic within an loop statement to apply to all array items, rather than returning a single result. – aaron.kyle Feb 04 '19 at 08:40

2 Answers2

2

The map function will help you modify each item of your data set

var modifiedReports = report_data.map(function(item)
{
    item.diff = new Date(item['End Date']).getTime() - new Date(item['Start Date']).getTime();

    return item;
})

In this sample the modifiedReports set will hold the same data as the report_data PLUS an additional field called diff (a number of milliseconds between start and end date)

ymz
  • 6,602
  • 1
  • 20
  • 39
  • Awesome! Thanks @ymz for this solution, and apologies that I misunderstood your earlier comment. I like how this adds the 'diff' to my array :) Thank's so much! – aaron.kyle Feb 03 '19 at 15:42
  • Hi again @ymz and community. This answer solves the basic question (and I very much appreciate your time, patience, and guidance!). But I wonder if I still need a loop? Specifically, the last array item in the example returns NaN for 'pending' (expected), but can it also calculate against today's today for values that are 'pending'? I am still struggling with loop syntax and logic. – aaron.kyle Feb 03 '19 at 16:13
  • I think you will need to reveal more of your code to answer the question "do I still need a loop" – ymz Feb 03 '19 at 16:45
  • What do you expect the result of `new Date(item['End Date']).getTime()` to be when the value of *item.End Date* is "pending"? And therefore the value of *item.diff*? – RobG Feb 03 '19 at 22:34
  • Thanks @RobG. With the map function provided by ymz, the result is NaN. I'd be ideal if I could add an condition in to the calculation such as follows: if End Date isNumeric, then diff: 'Start Date' and 'End Date', else: diff newDate(); and 'Start Date' – aaron.kyle Feb 04 '19 at 08:36
  • 1
    @aaron.kyle—it would be much better to 1) use a decent parser rather than the built–in parser and 2) test the value before parsing it or (better) test the returned value after parsing it. – RobG Feb 04 '19 at 09:14
0

I don't know from where did you get this syntax, but it should look something like this:

var durationArray = [];
var myArray = report_data;
var arrayLength = report_data.length;
for (var i = 0; i < arrayLength; i++) {
  var copy = new Date(report_data[i]["Start Date"]);
  var duration_adjusted = (today - copy)/24/60/60/1000;
  durationArray.push(duration_adjusted);
}
jcubic
  • 61,973
  • 54
  • 229
  • 402
  • Thanks @jcubic. I tried your approach but I am still returning one value - not an array. I updated my Observable notebook to demonstrate. As for my syntax... it's just what I've slowly figured out from the internet. ;) – aaron.kyle Feb 03 '19 at 14:59
  • 1
    @aaron.kyle this syntax is not valid javascript if it's working on Observeable notebook it mean that's their syntax. This is how you do this in JavaScript. Please don't use Observeable to teach yourself JavaScript use Codepen/jsfiddle/codeSandobox or other JS playground. – jcubic Feb 03 '19 at 15:13
  • Hi jcubic, and thank you for this feedback. Next time I'll try porting this over to codepen or JSfiddle. – aaron.kyle Feb 03 '19 at 15:43